Index: code/trunk/src/core/ArgumentCompletionFunctions.cc
===================================================================
--- code/trunk/src/core/ArgumentCompletionFunctions.cc	(revision 3214)
+++ code/trunk/src/core/ArgumentCompletionFunctions.cc	(revision 3280)
@@ -34,5 +34,5 @@
 
 #include "util/Convert.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "Identifier.h"
 #include "ConfigValueContainer.h"
@@ -143,5 +143,5 @@
 
             for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it)
-                threads.push_back(ArgumentCompletionListElement(getConvertedValue<unsigned int, std::string>(*it)));
+                threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it)));
 
             return threads;
Index: code/trunk/src/core/BaseObject.cc
===================================================================
--- code/trunk/src/core/BaseObject.cc	(revision 3214)
+++ code/trunk/src/core/BaseObject.cc	(revision 3280)
@@ -36,5 +36,5 @@
 #include <tinyxml/tinyxml.h>
 
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "CoreIncludes.h"
 #include "Event.h"
Index: code/trunk/src/core/CMakeLists.txt
===================================================================
--- code/trunk/src/core/CMakeLists.txt	(revision 3214)
+++ code/trunk/src/core/CMakeLists.txt	(revision 3280)
@@ -68,5 +68,4 @@
   TOLUA_FILES
     CommandExecutor.h
-    Game.h
     LuaBind.h
   DEFINE_SYMBOL
Index: code/trunk/src/core/CommandEvaluation.cc
===================================================================
--- code/trunk/src/core/CommandEvaluation.cc	(revision 3214)
+++ code/trunk/src/core/CommandEvaluation.cc	(revision 3280)
@@ -30,5 +30,5 @@
 
 #include "util/Debug.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "ConsoleCommand.h"
 #include "Identifier.h"
@@ -39,5 +39,5 @@
     {
         this->initialize("");
-        this->state_ = CS_Uninitialized;
+        this->state_ = CommandState::Uninitialized;
     }
 
@@ -64,5 +64,5 @@
 
         this->errorMessage_ = "";
-        this->state_ = CS_Empty;
+        this->state_ = CommandState::Empty;
     }
 
@@ -104,9 +104,9 @@
             switch (this->state_)
             {
-                case CS_Uninitialized:
-                    break;
-                case CS_Empty:
-                    break;
-                case CS_ShortcutOrIdentifier:
+                case CommandState::Uninitialized:
+                    break;
+                case CommandState::Empty:
+                    break;
+                case CommandState::ShortcutOrIdentifier:
                     if (this->function_)
                     {
@@ -119,5 +119,5 @@
                         return (this->command_ = this->functionclass_->getName() + " ");
                     break;
-                case CS_Function:
+                case CommandState::Function:
                     if (this->function_)
                     {
@@ -128,6 +128,6 @@
                     }
                     break;
-                case CS_ParamPreparation:
-                case CS_Params:
+                case CommandState::ParamPreparation:
+                case CommandState::Params:
                 {
                     if (this->argument_ == "" && this->possibleArgument_ == "")
@@ -149,7 +149,7 @@
                     break;
                 }
-                case CS_Finished:
-                    break;
-                case CS_Error:
+                case CommandState::Finished:
+                    break;
+                case CommandState::Error:
                     break;
             }
@@ -163,8 +163,8 @@
         switch (this->state_)
         {
-            case CS_Uninitialized:
-                break;
-            case CS_Empty:
-            case CS_ShortcutOrIdentifier:
+            case CommandState::Uninitialized:
+                break;
+            case CommandState::Empty:
+            case CommandState::ShortcutOrIdentifier:
                 if (this->listOfPossibleFunctions_.size() == 0)
                     return CommandEvaluation::dump(this->listOfPossibleIdentifiers_);
@@ -174,18 +174,18 @@
                     return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_));
                 break;
-            case CS_Function:
+            case CommandState::Function:
                 return CommandEvaluation::dump(this->listOfPossibleFunctions_);
                 break;
-            case CS_ParamPreparation:
-            case CS_Params:
+            case CommandState::ParamPreparation:
+            case CommandState::Params:
                 if (this->listOfPossibleArguments_.size() > 0)
                     return CommandEvaluation::dump(this->listOfPossibleArguments_);
                 else
                     return CommandEvaluation::dump(this->function_);
-            case CS_Finished:
+            case CommandState::Finished:
                 if (this->function_)
                     return CommandEvaluation::dump(this->function_);
                 break;
-            case CS_Error:
+            case CommandState::Error:
                 return this->errorMessage_;
                 break;
@@ -200,5 +200,5 @@
 
         for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
-            this->param_[i] = MT_null;
+            this->param_[i] = MT_Type::Null;
 
         if (!this->isValid())
@@ -230,5 +230,5 @@
             return this->param_[index];
 
-        return MT_null;
+        return MT_Type::Null;
     }
 
@@ -238,5 +238,5 @@
             return this->function_->hasReturnvalue();
 
-        return MT_null;
+        return MT_Type::Null;
     }
 
Index: code/trunk/src/core/CommandEvaluation.h
===================================================================
--- code/trunk/src/core/CommandEvaluation.h	(revision 3214)
+++ code/trunk/src/core/CommandEvaluation.h	(revision 3280)
@@ -41,15 +41,18 @@
 namespace orxonox
 {
-    enum CommandState
+    namespace CommandState
     {
-        CS_Uninitialized,
-        CS_Empty,
-        CS_ShortcutOrIdentifier,
-        CS_Function,
-        CS_ParamPreparation,
-        CS_Params,
-        CS_Finished,
-        CS_Error
-    };
+        enum Value
+        {
+            Uninitialized,
+            Empty,
+            ShortcutOrIdentifier,
+            Function,
+            ParamPreparation,
+            Params,
+            Finished,
+            Error
+        };
+    }
 
     class _CoreExport CommandEvaluation
@@ -112,5 +115,5 @@
 
             std::string errorMessage_;
-            CommandState state_;
+            CommandState::Value state_;
 
             bool bEvaluatedParams_;
Index: code/trunk/src/core/CommandExecutor.cc
===================================================================
--- code/trunk/src/core/CommandExecutor.cc	(revision 3214)
+++ code/trunk/src/core/CommandExecutor.cc	(revision 3280)
@@ -30,5 +30,5 @@
 
 #include "util/Debug.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "ConsoleCommand.h"
 #include "Identifier.h"
@@ -141,5 +141,5 @@
     void CommandExecutor::parseIfNeeded(const std::string& command)
     {
-        if (CommandExecutor::getEvaluation().state_ == CS_Uninitialized)
+        if (CommandExecutor::getEvaluation().state_ == CommandState::Uninitialized)
         {
             CommandExecutor::parse(command);
@@ -169,10 +169,10 @@
         switch (CommandExecutor::getEvaluation().state_)
         {
-            case CS_Uninitialized:
+            case CommandState::Uninitialized:
             {
                 // Impossible
                 break;
             }
-            case CS_Empty:
+            case CommandState::Empty:
             {
                 if (CommandExecutor::argumentsGiven() == 0)
@@ -184,9 +184,9 @@
                 else
                 {
-                    CommandExecutor::getEvaluation().state_ = CS_ShortcutOrIdentifier;
+                    CommandExecutor::getEvaluation().state_ = CommandState::ShortcutOrIdentifier;
                     // Move on to next case
                 }
             }
-            case CS_ShortcutOrIdentifier:
+            case CommandState::ShortcutOrIdentifier:
             {
                 if (CommandExecutor::argumentsGiven() > 1)
@@ -199,5 +199,5 @@
                     {
                         // It's a shortcut
-                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                         CommandExecutor::getEvaluation().functionclass_ = 0;
                         // Move on to next case
@@ -206,5 +206,5 @@
                     {
                         // It's a functionname
-                        CommandExecutor::getEvaluation().state_ = CS_Function;
+                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
                         CommandExecutor::getEvaluation().function_ = 0;
                         // Move on to next case
@@ -213,5 +213,5 @@
                     {
                         // The first argument is bad
-                        CommandExecutor::getEvaluation().state_ = CS_Error;
+                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
                         AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
                         CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
@@ -238,5 +238,5 @@
                             CommandExecutor::getEvaluation().bCommandChanged_ = true;
                         }
-                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                         CommandExecutor::getEvaluation().functionclass_ = 0;
                         CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
@@ -258,5 +258,5 @@
                             CommandExecutor::getEvaluation().bCommandChanged_ = true;
                         }
-                        CommandExecutor::getEvaluation().state_ = CS_Function;
+                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
                         CommandExecutor::getEvaluation().function_ = 0;
                         CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
@@ -266,5 +266,5 @@
                     {
                         // No possibilities
-                        CommandExecutor::getEvaluation().state_ = CS_Error;
+                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
                         AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
                         CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
@@ -285,5 +285,5 @@
                 }
             }
-            case CS_Function:
+            case CommandState::Function:
             {
                 if (CommandExecutor::getEvaluation().functionclass_)
@@ -298,5 +298,5 @@
                         {
                             // It's a function
-                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                             // Move on to next case
                         }
@@ -304,5 +304,5 @@
                         {
                             // The second argument is bad
-                            CommandExecutor::getEvaluation().state_ = CS_Error;
+                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
                             AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of");
                             CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + ".";
@@ -326,5 +326,5 @@
                                 CommandExecutor::getEvaluation().bCommandChanged_ = true;
                             }
-                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                             CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
                             if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
@@ -338,5 +338,5 @@
                         {
                             // No possibilities
-                            CommandExecutor::getEvaluation().state_ = CS_Error;
+                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
                             AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
                             CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + ".";
@@ -355,12 +355,12 @@
                 else
                 {
-                    // There is no classname - move on to CS_ParamPreparation
-                }
-            }
-            case CS_ParamPreparation:
+                    // There is no classname - move on to CommandState::ParamPreparation
+                }
+            }
+            case CommandState::ParamPreparation:
             {
                 if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_))
                 {
-                    CommandExecutor::getEvaluation().state_ = CS_Finished;
+                    CommandExecutor::getEvaluation().state_ = CommandState::Finished;
                     return;
                 }
@@ -372,5 +372,5 @@
 
                     CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
-                    CommandExecutor::getEvaluation().state_ = CS_Params;
+                    CommandExecutor::getEvaluation().state_ = CommandState::Params;
 
                     if (CommandExecutor::getEvaluation().bCommandChanged_)
@@ -381,5 +381,5 @@
                 }
             }
-            case CS_Params:
+            case CommandState::Params:
             {
                 if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
@@ -388,5 +388,5 @@
                     CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
                     CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
-                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                     return;
                 }
@@ -394,5 +394,5 @@
                 {
                     // The user tries something new - we let him do
-                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                     CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
                     return;
@@ -409,14 +409,14 @@
                     CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
                     CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
-                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
                     return;
                 }
             }
-            case CS_Finished:
+            case CommandState::Finished:
             {
                 // Nothing more to do
                 break;
             }
-            case CS_Error:
+            case CommandState::Error:
             {
                 // Bad, very bad
Index: code/trunk/src/core/CommandLine.cc
===================================================================
--- code/trunk/src/core/CommandLine.cc	(revision 3214)
+++ code/trunk/src/core/CommandLine.cc	(revision 3280)
@@ -29,4 +29,6 @@
 #include "CommandLine.h"
 
+#include <algorithm>
+#include <sstream>
 #include <boost/filesystem.hpp>
 
@@ -34,5 +36,5 @@
 #include "util/Debug.h"
 #include "util/Exception.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "util/SubString.h"
 #include "Core.h"
@@ -40,5 +42,5 @@
 namespace orxonox
 {
-    SetCommandLineArgument(optionsFile, "start.ini").shortcut("o");
+    SetCommandLineOnlyArgument(optionsFile, "start.ini").shortcut("o");
 
     /**
@@ -49,7 +51,9 @@
         so that you can have simple command line switches.
     */
-    void CommandLineArgument::parse(const std::string& value)
-    {
-        if (value_.getType() == MT_bool)
+    void CommandLineArgument::parse(const std::string& value, bool bParsingFile)
+    {
+        if (bParsingFile && this->bCommandLineOnly_)
+            ThrowException(Argument, "Command line argument '" + getName() + "' is not allowed in files.");
+        if (value_.getType() == MT_Type::Bool)
         {
             // simulate command line switch
@@ -66,7 +70,5 @@
             }
             else
-            {
                 ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
-            }
         }
         else
@@ -126,102 +128,111 @@
         Vector of space separated strings.
     */
-    void CommandLine::_parse(const std::vector<std::string>& arguments)
-    {
-        // why this? See bFirstTimeParse_ declaration.
-        if (bFirstTimeParse_)
-        {
-            // first shove all the shortcuts in a map
-            for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
-                it != cmdLineArgs_.end(); ++it)
-            {
-                OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(),
-                    "Cannot have two command line shortcut with the same name.");
-                if (it->second->getShortcut() != "")
-                    cmdLineArgsShortcut_[it->second->getShortcut()] = it->second;
-            }
-            bFirstTimeParse_ = false;
-        }
-
-        std::string name;
-        std::string shortcut;
-        std::string value;
-        for (unsigned int i = 0; i < arguments.size(); ++i)
-        {
-            if (arguments[i].size() != 0)
-            {
-                // sure not ""
-                if (arguments[i][0] == '-')
+    void CommandLine::_parse(const std::vector<std::string>& arguments, bool bParsingFile)
+    {
+        try
+        {
+            // why this? See bFirstTimeParse_ declaration.
+            if (bFirstTimeParse_)
+            {
+                // first shove all the shortcuts in a map
+                for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
+                    it != cmdLineArgs_.end(); ++it)
                 {
-                    // start with "-"
-                    if (arguments[i].size() == 1)
+                    OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(),
+                        "Cannot have two command line shortcut with the same name.");
+                    if (it->second->getShortcut() != "")
+                        cmdLineArgsShortcut_[it->second->getShortcut()] = it->second;
+                }
+                bFirstTimeParse_ = false;
+            }
+
+            std::string name;
+            std::string shortcut;
+            std::string value;
+            for (unsigned int i = 0; i < arguments.size(); ++i)
+            {
+                if (arguments[i].size() != 0)
+                {
+                    // sure not ""
+                    if (arguments[i][0] == '-')
                     {
-                        // argument[i] is "-", probably a minus sign
-                        value += "- ";
-                    }
-                    else if (arguments[i][1] <= 57 && arguments[i][1] >= 48)
-                    {
-                        // negative number as a value
-                        value += arguments[i] + " ";
+                        // start with "-"
+                        if (arguments[i].size() == 1)
+                        {
+                            // argument[i] is "-", probably a minus sign
+                            value += "- ";
+                        }
+                        else if (arguments[i][1] <= 57 && arguments[i][1] >= 48)
+                        {
+                            // negative number as a value
+                            value += arguments[i] + " ";
+                        }
+                        else
+                        {
+                            // can be shortcut or full name argument
+
+                            // save old data first
+                            value = removeTrailingWhitespaces(value);
+                            if (name != "")
+                            {
+                                checkFullArgument(name, value, bParsingFile);
+                                name = "";
+                                assert(shortcut == "");
+                            }
+                            else if (shortcut != "")
+                            {
+                                checkShortcut(shortcut, value, bParsingFile);
+                                shortcut = "";
+                                assert(name == "");
+                            }
+
+                            if (arguments[i][1] == '-')
+                            {
+                                // full name argument with "--name"
+                                name = arguments[i].substr(2);
+                            }
+                            else
+                            {
+                                // shortcut with "-s"
+                                shortcut = arguments[i].substr(1);
+                            }
+
+                            // reset value string
+                            value = "";
+                        }
                     }
                     else
                     {
-                        // can be shortcut or full name argument
-
-                        // save old data first
-                        value = removeTrailingWhitespaces(value);
-                        if (name != "")
+                        // value string
+
+                        if (name == "" && shortcut == "")
                         {
-                            checkFullArgument(name, value);
-                            name = "";
-                            assert(shortcut == "");
+                            ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
                         }
-                        else if (shortcut != "")
-                        {
-                            checkShortcut(shortcut, value);
-                            shortcut = "";
-                            assert(name == "");
-                        }
-
-                        if (arguments[i][1] == '-')
-                        {
-                            // full name argument with "--name"
-                            name = arguments[i].substr(2);
-                        }
-                        else
-                        {
-                            // shortcut with "-s"
-                            shortcut = arguments[i].substr(1);
-                        }
-
-                        // reset value string
-                        value = "";
+
+                        // Concatenate strings as long as there's no new argument by "-" or "--"
+                        value += arguments[i] + ' ';
                     }
                 }
-                else
-                {
-                    // value string
-
-                    if (name == "" && shortcut == "")
-                    {
-                        ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
-                    }
-
-                    // Concatenate strings as long as there's no new argument by "-" or "--"
-                    value += arguments[i] + ' ';
-                }
-            }
-        }
-
-        // parse last argument
-        value = removeTrailingWhitespaces(value);
-        if (name != "")
-        {
-            checkFullArgument(name, value);
-            assert(shortcut == "");
-        }
-        else if (shortcut != "")
-        {
-            checkShortcut(shortcut, value);
-            assert(name == "");
+            }
+
+            // parse last argument
+            value = removeTrailingWhitespaces(value);
+            if (name != "")
+            {
+                checkFullArgument(name, value, bParsingFile);
+                assert(shortcut == "");
+            }
+            else if (shortcut != "")
+            {
+                checkShortcut(shortcut, value, bParsingFile);
+                assert(name == "");
+            }
+        }
+        catch (const ArgumentException& ex)
+        {
+            COUT(0) << "Could not parse command line (including additional files): " << ex.what() << std::endl;
+            COUT(0) << CommandLine::getUsageInformation() << std::endl;
+            throw GeneralException("");
         }
     }
@@ -235,5 +246,5 @@
         String containing the value
     */
-    void CommandLine::checkFullArgument(const std::string& name, const std::string& value)
+    void CommandLine::checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile)
     {
         std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name);
@@ -241,5 +252,5 @@
             ThrowException(Argument, "Command line argument '" + name + "' does not exist.");
 
-        it->second->parse(value);
+        it->second->parse(value, bParsingFile);
     }
 
@@ -252,5 +263,5 @@
         String containing the value
     */
-    void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value)
+    void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile)
     {
         std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut);
@@ -258,17 +269,41 @@
             ThrowException(Argument, "Command line shortcut '" + shortcut + "' does not exist.");
 
-        it->second->parse(value);
+        it->second->parse(value, bParsingFile);
     }
 
     std::string CommandLine::getUsageInformation()
     {
-        CommandLine* inst = &_getInstance();
-        std::string infoStr;
-        for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin();
-            it != inst->cmdLineArgs_.end(); ++it)
-        {
-            infoStr += "[--" + it->second->getName() + " " + it->second->getInformation() + "] ";
-        }
-        return infoStr;
+        CommandLine& inst = _getInstance();
+        std::ostringstream infoStr;
+
+        // determine maximum name size
+        size_t maxNameSize = 0;
+        for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin();
+            it != inst.cmdLineArgs_.end(); ++it)
+        {
+            maxNameSize = std::max(it->second->getName().size(), maxNameSize);
+        }
+
+        infoStr << "Usage: orxonox [options]" << std::endl;
+        infoStr << "Available options:" << std::endl;
+
+        for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin();
+            it != inst.cmdLineArgs_.end(); ++it)
+        {
+            if (it->second->getShortcut() != "")
+                infoStr << " [-" << it->second->getShortcut() << "] ";
+            else
+                infoStr << "      ";
+            infoStr << "--" << it->second->getName() << " ";
+            if (it->second->getValue().getType() != MT_Type::Bool)
+                infoStr << "ARG ";
+            else
+                infoStr << "    ";
+            // fill with the necessary amount of blanks
+            infoStr << std::string(maxNameSize - it->second->getName().size(), ' ');
+            infoStr << ": " << it->second->getInformation();
+            infoStr << std::endl;
+        }
+        return infoStr.str();
     }
 
@@ -295,14 +330,20 @@
     /**
     @brief
-        Parses both command line and start.ini for CommandLineArguments.
-    */
-    void CommandLine::_parseAll(int argc, char** argv)
-    {
-        // parse command line first
+        Parses only the command line for CommandLineArguments.
+    */
+    void CommandLine::_parseCommandLine(int argc, char** argv)
+    {
         std::vector<std::string> args;
         for (int i = 1; i < argc; ++i)
             args.push_back(argv[i]);
-        this->_parse(args);
-
+        this->_parse(args, false);
+    }
+
+    /**
+    @brief
+        Parses start.ini (or the file specified with --optionsFile) for CommandLineArguments.
+    */
+    void CommandLine::_parseFile()
+    {
         std::string filename = CommandLine::getValue("optionsFile").getString();
         boost::filesystem::path filepath(Core::getConfigPath() / filename);
@@ -312,5 +353,5 @@
         std::ifstream file;
         file.open(filepath.string().c_str());
-        args.clear();
+        std::vector<std::string> args;
         if (file)
         {
@@ -332,13 +373,5 @@
         }
 
-        try
-        {
-            _parse(args);
-        }
-        catch (orxonox::ArgumentException& ex)
-        {
-            COUT(1) << "An Exception occured while parsing " << filename << std::endl;
-            throw(ex);
-        }
+        _parse(args, true);
     }
 }
Index: code/trunk/src/core/CommandLine.h
===================================================================
--- code/trunk/src/core/CommandLine.h	(revision 3214)
+++ code/trunk/src/core/CommandLine.h	(revision 3280)
@@ -38,8 +38,14 @@
 #define SetCommandLineArgument(name, defaultValue) \
     orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
-    = orxonox::CommandLine::addArgument(#name, defaultValue)
+    = orxonox::CommandLine::addArgument(#name, defaultValue, false)
+#define SetCommandLineOnlyArgument(name, defaultValue) \
+    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLine::addArgument(#name, defaultValue, true)
 #define SetCommandLineSwitch(name) \
     orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
-    = orxonox::CommandLine::addArgument(#name, false)
+    = orxonox::CommandLine::addArgument(#name, false, false)
+#define SetCommandLineOnlySwitch(name) \
+    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLine::addArgument(#name, false, true)
 
 
@@ -74,5 +80,5 @@
 
         //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument.
-        //! Evaluates to "" if none there is none.
+        //! Evaluates to "" if there is none.
         const std::string& getShortcut() const { return shortcut_; }
         //! Sets the shortcut for the argument
@@ -93,9 +99,10 @@
     private:
         //! Constructor initialises both value_ and defaultValue_ with defaultValue.
-        CommandLineArgument(const std::string& name, const MultiType& defaultValue)
+        CommandLineArgument(const std::string& name, const MultiType& defaultValue, bool bCommandLineOnly)
             : bHasDefaultValue_(true)
             , name_(name)
             , value_(defaultValue)
             , defaultValue_(defaultValue)
+            , bCommandLineOnly_(bCommandLineOnly)
         { }
 
@@ -105,5 +112,5 @@
 
         //! Parses the value string of a command line argument.
-        void parse(const std::string& value);
+        void parse(const std::string& value, bool bParsingFile);
 
         //! Tells whether the value has been changed by the command line.
@@ -115,6 +122,7 @@
         std::string usageInformation_; //!< Tells about the usage of this parameter
 
-        MultiType value_;            //!< The actual value
-        MultiType defaultValue_;     //!< Default value. Should not be changed.
+        MultiType   value_;            //!< The actual value
+        MultiType   defaultValue_;     //!< Default value. Should not be changed.
+        bool        bCommandLineOnly_; //!< Whether you cannot specify the value in a text file
     };
 
@@ -134,5 +142,6 @@
 
         //! Parse redirection to internal member method.
-        static void parseAll(int argc, char** argv) { _getInstance()._parseAll(argc, argv); }
+        static void parseCommandLine(int argc, char** argv) { _getInstance()._parseCommandLine(argc, argv); }
+        static void parseFile() { _getInstance()._parseFile(); }
 
         static std::string getUsageInformation();
@@ -146,5 +155,5 @@
         { return getArgument(name)->getValue(); }
         template <class T>
-        static CommandLineArgument& addArgument(const std::string& name, T defaultValue);
+        static CommandLineArgument& addArgument(const std::string& name, T defaultValue, bool bCommandLineOnly);
 
         static bool existsArgument(const std::string& name)
@@ -165,8 +174,9 @@
         static CommandLine& _getInstance();
 
-        void _parseAll(int argc, char** argv);
-        void _parse(const std::vector<std::string>& arguments);
-        void checkFullArgument(const std::string& name, const std::string& value);
-        void checkShortcut(const std::string& shortcut, const std::string& value);
+        void _parseCommandLine(int argc, char** argv);
+        void _parseFile();
+        void _parse(const std::vector<std::string>& arguments, bool bParsingFile);
+        void checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile);
+        void checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile);
 
         /**
@@ -199,10 +209,13 @@
     */
     template <class T>
-    CommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue)
+    CommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue, bool bCommandLineOnly)
     {
         OrxAssert(!_getInstance().existsArgument(name),
             "Cannot add a command line argument with name '" + name + "' twice.");
-
-        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue));
+        OrxAssert(MultiType(defaultValue).getType() != MT_Type::Bool || MultiType(defaultValue).getBool() != true,
+               "Boolean command line arguments with positive default values are not supported." << std::endl
+            << "Please use SetCommandLineSwitch and adjust your argument: " << name);
+
+        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue, bCommandLineOnly));
     }
 }
Index: code/trunk/src/core/ConfigFileManager.cc
===================================================================
--- code/trunk/src/core/ConfigFileManager.cc	(revision 3214)
+++ code/trunk/src/core/ConfigFileManager.cc	(revision 3280)
@@ -33,5 +33,5 @@
 #include "util/Convert.h"
 #include "util/Math.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "ConsoleCommand.h"
 #include "ConfigValueContainer.h"
@@ -124,7 +124,7 @@
     {
         if (this->additionalComment_ == "" || this->additionalComment_.size() == 0)
-            return (this->name_ + "[" + getConvertedValue<unsigned int, std::string>(this->index_, "0") + "]" + "=" + this->value_);
-        else
-            return (this->name_ + "[" + getConvertedValue<unsigned int, std::string>(this->index_, "0") + "]=" + this->value_ + " " + this->additionalComment_);
+            return (this->name_ + "[" + multi_cast<std::string>(this->index_) + "]" + "=" + this->value_);
+        else
+            return (this->name_ + "[" + multi_cast<std::string>(this->index_) + "]=" + this->value_ + " " + this->additionalComment_);
     }
 
Index: code/trunk/src/core/ConfigValueContainer.cc
===================================================================
--- code/trunk/src/core/ConfigValueContainer.cc	(revision 3214)
+++ code/trunk/src/core/ConfigValueContainer.cc	(revision 3280)
@@ -78,5 +78,5 @@
         for (unsigned int i = 0; i < this->valueVector_.size(); i++)
         {
-            ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_string));
+            ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String));
             this->defvalueStringVector_.push_back(this->valueVector_[i]);
         }
@@ -109,5 +109,5 @@
             if (this->tset(input))
             {
-                ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isType(MT_string));
+                ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isType(MT_Type::String));
                 return true;
             }
@@ -128,5 +128,5 @@
             if (this->tset(index, input))
             {
-                ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isType(MT_string));
+                ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isType(MT_Type::String));
                 return true;
             }
@@ -228,5 +228,5 @@
                 this->valueVector_.erase(this->valueVector_.begin() + index);
                 for (unsigned int i = index; i < this->valueVector_.size(); i++)
-                    ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_string));
+                    ConfigFileManager::getInstance().setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String));
                 ConfigFileManager::getInstance().deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->valueVector_.size());
 
@@ -264,5 +264,5 @@
     {
         if (!this->bIsVector_)
-            this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isType(MT_string));
+            this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isType(MT_Type::String));
         else
         {
@@ -273,9 +273,9 @@
                 if (i < this->defvalueStringVector_.size())
                 {
-                    this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isType(MT_string));
+                    this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isType(MT_Type::String));
                 }
                 else
                 {
-                    this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, MultiType(), this->value_.isType(MT_string));
+                    this->value_ = ConfigFileManager::getInstance().getValue(this->type_, this->sectionname_, this->varname_, i, MultiType(), this->value_.isType(MT_Type::String));
                 }
 
Index: code/trunk/src/core/ConfigValueIncludes.h
===================================================================
--- code/trunk/src/core/ConfigValueIncludes.h	(revision 3214)
+++ code/trunk/src/core/ConfigValueIncludes.h	(revision 3280)
@@ -52,5 +52,5 @@
     if (!container##varname) \
     { \
-        container##varname = new orxonox::ConfigValueContainer(ConfigFileType::Settings, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \
+        container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \
         identifier##varname->addConfigValueContainer(#varname, container##varname); \
     } \
@@ -70,5 +70,5 @@
     if (!container##varname) \
     { \
-        container##varname = new orxonox::ConfigValueContainer(ConfigFileType::Settings, identifier##varname, identifier##varname->getName(), #varname, defvalue); \
+        container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue); \
         identifier##varname->addConfigValueContainer(#varname, container##varname); \
     } \
Index: code/trunk/src/core/ConsoleCommand.h
===================================================================
--- code/trunk/src/core/ConsoleCommand.h	(revision 3214)
+++ code/trunk/src/core/ConsoleCommand.h	(revision 3280)
@@ -71,5 +71,5 @@
     namespace AccessLevel
     {
-        enum Level
+        enum Value
         {
             None,
@@ -106,7 +106,7 @@
                 { this->Executor::setDefaultValue(index, param); return (*this); }
 
-            inline ConsoleCommand& accessLevel(AccessLevel::Level level)
+            inline ConsoleCommand& accessLevel(AccessLevel::Value level)
                 { this->accessLevel_ = level; return (*this); }
-            inline AccessLevel::Level getAccessLevel() const
+            inline AccessLevel::Value getAccessLevel() const
                 { return this->accessLevel_; }
 
@@ -130,7 +130,7 @@
             }
 
-            inline ConsoleCommand& keybindMode(KeybindMode::Enum mode)
+            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
                 { this->keybindMode_ = mode; return *this; }
-            inline KeybindMode::Enum getKeybindMode() const
+            inline KeybindMode::Value getKeybindMode() const
                 { return this->keybindMode_; }
 
@@ -141,9 +141,9 @@
 
         private:
-            AccessLevel::Level accessLevel_;
+            AccessLevel::Value accessLevel_;
             ArgumentCompleter* argumentCompleter_[5];
             ArgumentCompletionList argumentList_;
 
-            KeybindMode::Enum keybindMode_;
+            KeybindMode::Value keybindMode_;
             int inputConfiguredParam_;
     };
Index: code/trunk/src/core/Core.cc
===================================================================
--- code/trunk/src/core/Core.cc	(revision 3214)
+++ code/trunk/src/core/Core.cc	(revision 3280)
@@ -77,40 +77,193 @@
 namespace orxonox
 {
-    //! Path to the parent directory of the ones above if program was installed with relativ pahts
-    static boost::filesystem::path rootPath_g;
-    static boost::filesystem::path executablePath_g;            //!< Path to the executable
-    static boost::filesystem::path mediaPath_g;                 //!< Path to the media file folder
-    static boost::filesystem::path configPath_g;                //!< Path to the config file folder
-    static boost::filesystem::path logPath_g;                   //!< Path to the log file folder
-
     //! Static pointer to the singleton
     Core* Core::singletonRef_s  = 0;
 
-    SetCommandLineArgument(mediaPath, "").information("PATH");
-    SetCommandLineArgument(writingPathSuffix, "").information("DIR");
-    SetCommandLineArgument(settingsFile, "orxonox.ini");
-    SetCommandLineArgument(limitToCPU, 0).information("0: off | #cpu");
-
-    Core::Core()
-    {
-        RegisterRootObject(Core);
-
-        assert(Core::singletonRef_s == 0);
+    SetCommandLineArgument(mediaPath, "").information("Path to the media/data files");
+    SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files");
+    SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
+#ifdef ORXONOX_PLATFORM_WINDOWS
+    SetCommandLineArgument(limitToCPU, 0).information("Limits the program to one cpu/core (1, 2, 3, etc.). 0 turns it off (default)");
+#endif
+
+    /**
+    @brief
+        Helper class for the Core singleton: we cannot derive
+        Core from OrxonoxClass because we need to handle the Identifier
+        destruction in the Core destructor.
+    */
+    class CoreConfiguration : public OrxonoxClass
+    {
+    public:
+        CoreConfiguration()
+        {
+        }
+
+        void initialise()
+        {
+            RegisterRootObject(CoreConfiguration);
+            this->setConfigValues();
+
+            // Possible media path override by the command line
+            if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
+                tsetMediaPath(CommandLine::getValue("mediaPath"));
+        }
+
+        /**
+            @brief Function to collect the SetConfigValue-macro calls.
+        */
+        void setConfigValues()
+        {
+#ifdef NDEBUG
+            const unsigned int defaultLevelConsole = 1;
+            const unsigned int defaultLevelLogfile = 3;
+            const unsigned int defaultLevelShell   = 1;
+#else
+            const unsigned int defaultLevelConsole = 3;
+            const unsigned int defaultLevelLogfile = 4;
+            const unsigned int defaultLevelShell   = 3;
+#endif
+            SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
+                .description("The maximal level of debug output shown in the console")
+                .callback(this, &CoreConfiguration::debugLevelChanged);
+            SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
+                .description("The maximal level of debug output shown in the logfile")
+                .callback(this, &CoreConfiguration::debugLevelChanged);
+            SetConfigValue(softDebugLevelShell_, defaultLevelShell)
+                .description("The maximal level of debug output shown in the ingame shell")
+                .callback(this, &CoreConfiguration::debugLevelChanged);
+
+            SetConfigValue(language_, Language::getLanguage().defaultLanguage_)
+                .description("The language of the ingame text")
+                .callback(this, &CoreConfiguration::languageChanged);
+            SetConfigValue(bInitializeRandomNumberGenerator_, true)
+                .description("If true, all random actions are different each time you start the game")
+                .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
+
+            SetConfigValue(mediaPathString_, mediaPath_.string())
+                .description("Relative path to the game data.")
+                .callback(this, &CoreConfiguration::mediaPathChanged);
+        }
+
+        /**
+            @brief Callback function if the debug level has changed.
+        */
+        void debugLevelChanged()
+        {
+            // softDebugLevel_ is the maximum of the 3 variables
+            this->softDebugLevel_ = this->softDebugLevelConsole_;
+            if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
+                this->softDebugLevel_ = this->softDebugLevelLogfile_;
+            if (this->softDebugLevelShell_ > this->softDebugLevel_)
+                this->softDebugLevel_ = this->softDebugLevelShell_;
+
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
+        }
+
+        /**
+            @brief Callback function if the language has changed.
+        */
+        void languageChanged()
+        {
+            // Read the translation file after the language was configured
+            Language::getLanguage().readTranslatedLanguageFile();
+        }
+
+        /**
+        @brief
+            Callback function if the media path has changed.
+        */
+        void mediaPathChanged()
+        {
+            mediaPath_ = boost::filesystem::path(this->mediaPathString_);
+        }
+
+        /**
+            @brief Sets the language in the config-file back to the default.
+        */
+        void resetLanguage()
+        {
+            ResetConfigValue(language_);
+        }
+
+        /**
+        @brief
+            Temporary sets the media path
+        @param path
+            The new media path
+        */
+        void tsetMediaPath(const std::string& path)
+        {
+            ModifyConfigValue(mediaPathString_, tset, path);
+        }
+
+        void initializeRandomNumberGenerator()
+        {
+            static bool bInitialized = false;
+            if (!bInitialized && this->bInitializeRandomNumberGenerator_)
+            {
+                srand(static_cast<unsigned int>(time(0)));
+                rand();
+                bInitialized = true;
+            }
+        }
+
+        int softDebugLevel_;                            //!< The debug level
+        int softDebugLevelConsole_;                     //!< The debug level for the console
+        int softDebugLevelLogfile_;                     //!< The debug level for the logfile
+        int softDebugLevelShell_;                       //!< The debug level for the ingame shell
+        std::string language_;                          //!< The language
+        bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
+        std::string mediaPathString_;                   //!< Path to the data/media file folder as string
+
+        //! Path to the parent directory of the ones above if program was installed with relativ pahts
+        boost::filesystem::path rootPath_;
+        boost::filesystem::path executablePath_;        //!< Path to the executable
+        boost::filesystem::path mediaPath_;             //!< Path to the media file folder
+        boost::filesystem::path configPath_;            //!< Path to the config file folder
+        boost::filesystem::path logPath_;               //!< Path to the log file folder
+    };
+
+
+    Core::Core(int argc, char** argv)
+    {
+        if (singletonRef_s != 0)
+        {
+            COUT(0) << "Error: The Core singleton cannot be recreated! Shutting down." << std::endl;
+            abort();
+        }
         Core::singletonRef_s = this;
-    }
-
-    void Core::initialise(int argc, char** argv)
-    {
-        // Parse command line arguments fist
-        try
-        {
-            CommandLine::parseAll(argc, argv);
-        }
-        catch (ArgumentException& ex)
-        {
-            COUT(1) << ex.what() << std::endl;
-            COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl;
-        }
-
+
+        // We need the variables very soon. But don't configure them yet!
+        this->configuration_ = new CoreConfiguration();
+
+        // Parse command line arguments first
+        CommandLine::parseCommandLine(argc, argv);
+
+        // Determine and set the location of the executable
+        setExecutablePath();
+
+        // Determine whether we have an installed or a binary dir run
+        // The latter occurs when simply running from the build directory
+        checkDevBuild();
+
+        // Make sure the directories we write in exist or else make them
+        createDirectories();
+
+        // create a signal handler (only active for linux)
+        // This call is placed as soon as possible, but after the directories are set
+        this->signalHandler_ = new SignalHandler();
+        this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");
+
+        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
+        OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
+
+        // Parse additional options file now that we know its path
+        CommandLine::parseFile();
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
         // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
         // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
@@ -118,23 +271,6 @@
         int limitToCPU = CommandLine::getValue("limitToCPU");
         if (limitToCPU > 0)
-            setThreadAffinity((unsigned int)limitToCPU);
-
-        // Determine and set the location of the executable
-        setExecutablePath();
-
-        // Determine whether we have an installed or a binary dir run
-        // The latter occurs when simply running from the build directory
-        checkDevBuild();
-
-        // Make sure the directories we write in exist or else make them
-        createDirectories();
-
-        // create a signal handler (only active for linux)
-        // This call is placed as soon as possible, but after the directories are set
-        this->signalHandler_ = new SignalHandler();
-        this->signalHandler_->doCatch(executablePath_g.string(), Core::getLogPathString() + "orxonox_crash.log");
-
-        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
-        OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
+            setThreadAffinity(static_cast<unsigned int>(limitToCPU));
+#endif
 
         // Manage ini files and set the default settings file (usually orxonox.ini)
@@ -143,16 +279,10 @@
             CommandLine::getValue("settingsFile").getString());
 
+        // Required as well for the config values
         this->languageInstance_ = new Language();
 
         // Do this soon after the ConfigFileManager has been created to open up the
         // possibility to configure everything below here
-        this->setConfigValues();
-
-        // Possible media path override by the command line
-        if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
-        {
-            //std::string mediaPath = CommandLine::getValue("mediaPath");
-            Core::tsetMediaPath(CommandLine::getValue("mediaPath"));
-        }
+        this->configuration_->initialise();
 
         // Create the lua interface
@@ -168,6 +298,4 @@
         // creates the class hierarchy for all classes with factories
         Factory::createClassHierarchy();
-        
-        this->loaded_ = true;
     }
 
@@ -177,10 +305,9 @@
     Core::~Core()
     {
-        this->loaded_ = false;
-
         delete this->shell_;
         delete this->tclThreadManager_;
         delete this->tclBind_;
         delete this->luaBind_;
+        delete this->configuration_;
         delete this->languageInstance_;
         delete this->configFileManager_;
@@ -190,91 +317,29 @@
         // Also delete external console command that don't belong to an Identifier
         CommandExecutor::destroyExternalCommands();
-
-        assert(Core::singletonRef_s);
-        Core::singletonRef_s = 0;
+        // Clean up class hierarchy stuff (identifiers, XMLPort, configValues, consoleCommand)
+        Identifier::destroyAllIdentifiers();
+
         delete this->signalHandler_;
-    }
-
-    /**
-        @brief Function to collect the SetConfigValue-macro calls.
-    */
-    void Core::setConfigValues()
-    {
-#ifdef NDEBUG
-        const unsigned int defaultLevelConsole = 1;
-        const unsigned int defaultLevelLogfile = 3;
-        const unsigned int defaultLevelShell   = 1;
-#else
-        const unsigned int defaultLevelConsole = 3;
-        const unsigned int defaultLevelLogfile = 4;
-        const unsigned int defaultLevelShell   = 3;
-#endif
-        SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
-            .description("The maximal level of debug output shown in the console").callback(this, &Core::debugLevelChanged);
-        SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
-            .description("The maximal level of debug output shown in the logfile").callback(this, &Core::debugLevelChanged);
-        SetConfigValue(softDebugLevelShell_, defaultLevelShell)
-            .description("The maximal level of debug output shown in the ingame shell").callback(this, &Core::debugLevelChanged);
-
-        SetConfigValue(language_, Language::getLanguage().defaultLanguage_).description("The language of the ingame text").callback(this, &Core::languageChanged);
-        SetConfigValue(bInitializeRandomNumberGenerator_, true).description("If true, all random actions are different each time you start the game").callback(this, &Core::initializeRandomNumberGenerator);
-
-        SetConfigValue(mediaPathString_, mediaPath_g.string())
-            .description("Relative path to the game data.").callback(this, &Core::mediaPathChanged);
-    }
-
-    /**
-        @brief Callback function if the debug level has changed.
-    */
-    void Core::debugLevelChanged()
-    {
-        // softDebugLevel_ is the maximum of the 3 variables
-        this->softDebugLevel_ = this->softDebugLevelConsole_;
-        if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
-            this->softDebugLevel_ = this->softDebugLevelLogfile_;
-        if (this->softDebugLevelShell_ > this->softDebugLevel_)
-            this->softDebugLevel_ = this->softDebugLevelShell_;
-
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
-    }
-
-    /**
-        @brief Callback function if the language has changed.
-    */
-    void Core::languageChanged()
-    {
-        // Read the translation file after the language was configured
-        Language::getLanguage().readTranslatedLanguageFile();
-    }
-
-    /**
-    @brief
-        Callback function if the media path has changed.
-    */
-    void Core::mediaPathChanged()
-    {
-        mediaPath_g = boost::filesystem::path(this->mediaPathString_);
-    }
-
-    /**
-        @brief Returns the softDebugLevel for the given device (returns a default-value if the class ist right about to be created).
+
+        // Don't assign singletonRef_s with NULL! Recreation is not supported
+    }
+
+    /**
+        @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).
         @param device The device
         @return The softDebugLevel
     */
-    int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
+    /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
     {
         switch (device)
         {
         case OutputHandler::LD_All:
-            return Core::getInstance().softDebugLevel_;
+            return Core::getInstance().configuration_->softDebugLevel_;
         case OutputHandler::LD_Console:
-            return Core::getInstance().softDebugLevelConsole_;
+            return Core::getInstance().configuration_->softDebugLevelConsole_;
         case OutputHandler::LD_Logfile:
-            return Core::getInstance().softDebugLevelLogfile_;
+            return Core::getInstance().configuration_->softDebugLevelLogfile_;
         case OutputHandler::LD_Shell:
-            return Core::getInstance().softDebugLevelShell_;
+            return Core::getInstance().configuration_->softDebugLevelShell_;
         default:
             assert(0);
@@ -288,24 +353,24 @@
         @param level The level
     */
-     void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
-     {
+    /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
+    {
         if (device == OutputHandler::LD_All)
-            Core::getInstance().softDebugLevel_ = level;
+            Core::getInstance().configuration_->softDebugLevel_ = level;
         else if (device == OutputHandler::LD_Console)
-            Core::getInstance().softDebugLevelConsole_ = level;
+            Core::getInstance().configuration_->softDebugLevelConsole_ = level;
         else if (device == OutputHandler::LD_Logfile)
-            Core::getInstance().softDebugLevelLogfile_ = level;
+            Core::getInstance().configuration_->softDebugLevelLogfile_ = level;
         else if (device == OutputHandler::LD_Shell)
-            Core::getInstance().softDebugLevelShell_ = level;
+            Core::getInstance().configuration_->softDebugLevelShell_ = level;
 
         OutputHandler::setSoftDebugLevel(device, level);
-     }
+    }
 
     /**
         @brief Returns the configured language.
     */
-    const std::string& Core::getLanguage()
-    {
-        return Core::getInstance().language_;
+    /*static*/ const std::string& Core::getLanguage()
+    {
+        return Core::getInstance().configuration_->language_;
     }
 
@@ -313,66 +378,40 @@
         @brief Sets the language in the config-file back to the default.
     */
-    void Core::resetLanguage()
-    {
-        Core::getInstance().resetLanguageIntern();
-    }
-
-    /**
-        @brief Sets the language in the config-file back to the default.
-    */
-    void Core::resetLanguageIntern()
-    {
-        ResetConfigValue(language_);
-    }
-
-    /**
-    @brief
-        Temporary sets the media path
-    @param path
-        The new media path
-    */
-    void Core::_tsetMediaPath(const std::string& path)
-    {
-        ModifyConfigValue(mediaPathString_, tset, path);
+    /*static*/ void Core::resetLanguage()
+    {
+        Core::getInstance().configuration_->resetLanguage();
+    }
+
+    /*static*/ void Core::tsetMediaPath(const std::string& path)
+    {
+        getInstance().configuration_->tsetMediaPath(path);
     }
 
     /*static*/ const boost::filesystem::path& Core::getMediaPath()
     {
-        return mediaPath_g;
+        return getInstance().configuration_->mediaPath_;
     }
     /*static*/ std::string Core::getMediaPathString()
     {
-        return mediaPath_g.string() + '/';
+        return getInstance().configuration_->mediaPath_.string() + '/';
     }
 
     /*static*/ const boost::filesystem::path& Core::getConfigPath()
     {
-        return configPath_g;
+        return getInstance().configuration_->configPath_;
     }
     /*static*/ std::string Core::getConfigPathString()
     {
-        return configPath_g.string() + '/';
+        return getInstance().configuration_->configPath_.string() + '/';
     }
 
     /*static*/ const boost::filesystem::path& Core::getLogPath()
     {
-        return logPath_g;
+        return getInstance().configuration_->logPath_;
     }
     /*static*/ std::string Core::getLogPathString()
     {
-        return logPath_g.string() + '/';
-    }
-
-    void Core::initializeRandomNumberGenerator()
-    {
-        static bool bInitialized = false;
-        if (!bInitialized && this->bInitializeRandomNumberGenerator_)
-        {
-            srand(static_cast<unsigned int>(time(0)));
-            rand();
-            bInitialized = true;
-        }
-    }
-
+        return getInstance().configuration_->logPath_.string() + '/';
+    }
 
     /**
@@ -388,8 +427,9 @@
     void Core::setThreadAffinity(int limitToCPU)
     {
+#ifdef ORXONOX_PLATFORM_WINDOWS
+
         if (limitToCPU <= 0)
             return;
 
-#ifdef ORXONOX_PLATFORM_WINDOWS
         unsigned int coreNr = limitToCPU - 1;
         // Get the current process core mask
@@ -465,7 +505,7 @@
 #endif
 
-        executablePath_g = boost::filesystem::path(buffer);
+        configuration_->executablePath_ = boost::filesystem::path(buffer);
 #ifndef ORXONOX_PLATFORM_APPLE
-        executablePath_g = executablePath_g.branch_path(); // remove executable name
+        configuration_->executablePath_ = configuration_->executablePath_.branch_path(); // remove executable name
 #endif
     }
@@ -481,11 +521,11 @@
     void Core::checkDevBuild()
     {
-        if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me"))
+        if (boost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me"))
         {
             COUT(1) << "Running from the build tree." << std::endl;
             Core::isDevBuild_ = true;
-            mediaPath_g  = ORXONOX_MEDIA_DEV_PATH;
-            configPath_g = ORXONOX_CONFIG_DEV_PATH;
-            logPath_g    = ORXONOX_LOG_DEV_PATH;
+            configuration_->mediaPath_  = ORXONOX_MEDIA_DEV_PATH;
+            configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH;
+            configuration_->logPath_    = ORXONOX_LOG_DEV_PATH;
         }
         else
@@ -494,18 +534,19 @@
             // Also set the root path
             boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH);
-            rootPath_g = executablePath_g;
-            while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) && !rootPath_g.empty())
-                rootPath_g = rootPath_g.branch_path();
-            if (rootPath_g.empty())
+            configuration_->rootPath_ = configuration_->executablePath_;
+            while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_)
+                   && !configuration_->rootPath_.empty())
+                configuration_->rootPath_ = configuration_->rootPath_.branch_path();
+            if (configuration_->rootPath_.empty())
                 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
 
             // Using paths relative to the install prefix, complete them
-            mediaPath_g  = rootPath_g / ORXONOX_MEDIA_INSTALL_PATH;
-            configPath_g = rootPath_g / ORXONOX_CONFIG_INSTALL_PATH;
-            logPath_g    = rootPath_g / ORXONOX_LOG_INSTALL_PATH;
+            configuration_->mediaPath_  = configuration_->rootPath_ / ORXONOX_MEDIA_INSTALL_PATH;
+            configuration_->configPath_ = configuration_->rootPath_ / ORXONOX_CONFIG_INSTALL_PATH;
+            configuration_->logPath_    = configuration_->rootPath_ / ORXONOX_LOG_INSTALL_PATH;
 #else
             // There is no root path, so don't set it at all
 
-            mediaPath_g  = ORXONOX_MEDIA_INSTALL_PATH;
+            configuration_->mediaPath_  = ORXONOX_MEDIA_INSTALL_PATH;
 
             // Get user directory
@@ -520,6 +561,6 @@
             userDataPath /= ".orxonox";
 
-            configPath_g = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
-            logPath_g    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
+            configuration_->configPath_ = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
+            configuration_->logPath_    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
 #endif
         }
@@ -529,6 +570,6 @@
         {
             std::string directory(CommandLine::getValue("writingPathSuffix").getString());
-            configPath_g = configPath_g / directory;
-            logPath_g    = logPath_g    / directory;
+            configuration_->configPath_ = configuration_->configPath_ / directory;
+            configuration_->logPath_    = configuration_->logPath_    / directory;
         }
     }
@@ -544,6 +585,6 @@
     {
         std::vector<std::pair<boost::filesystem::path, std::string> > directories;
-        directories.push_back(std::make_pair(boost::filesystem::path(configPath_g), "config"));
-        directories.push_back(std::make_pair(boost::filesystem::path(logPath_g), "log"));
+        directories.push_back(std::make_pair(boost::filesystem::path(configuration_->configPath_), "config"));
+        directories.push_back(std::make_pair(boost::filesystem::path(configuration_->logPath_), "log"));
 
         for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin();
Index: code/trunk/src/core/Core.h
===================================================================
--- code/trunk/src/core/Core.h	(revision 3214)
+++ code/trunk/src/core/Core.h	(revision 3280)
@@ -43,9 +43,10 @@
 
 #include <cassert>
-#include "OrxonoxClass.h"
 #include "util/OutputHandler.h"
 
 namespace orxonox
 {
+    class CoreConfiguration;
+
     /**
     @brief
@@ -55,5 +56,5 @@
         It determines those by the use of platform specific functions.
     */
-    class _CoreExport Core : public OrxonoxClass
+    class _CoreExport Core
     {
         public:
@@ -65,8 +66,7 @@
                 GeneralException
             */
-            Core();
+            Core(int argc, char** argv);
             ~Core();
 
-            void initialise(int argc, char** argv);
             void setConfigValues();
 
@@ -80,6 +80,5 @@
             static void  resetLanguage();
 
-            static void tsetMediaPath(const std::string& path)
-            { assert(singletonRef_s); singletonRef_s->_tsetMediaPath(path); }
+            static void tsetMediaPath(const std::string& path);
             //! Returns the path to the config files as boost::filesystem::path
             static const boost::filesystem::path& getMediaPath();
@@ -103,11 +102,4 @@
             void setThreadAffinity(int limitToCPU);
 
-            void resetLanguageIntern();
-            void initializeRandomNumberGenerator();
-            void debugLevelChanged();
-            void languageChanged();
-            void mediaPathChanged();
-            void _tsetMediaPath(const std::string& path);
-
             // Singletons
             ConfigFileManager*    configFileManager_;
@@ -119,13 +111,6 @@
             TclThreadManager*     tclThreadManager_;
 
-            int softDebugLevel_;                            //!< The debug level
-            int softDebugLevelConsole_;                     //!< The debug level for the console
-            int softDebugLevelLogfile_;                     //!< The debug level for the logfile
-            int softDebugLevelShell_;                       //!< The debug level for the ingame shell
-            std::string language_;                          //!< The language
-            bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
-            std::string mediaPathString_;                   //!< Path to the data/media file folder as string
             bool isDevBuild_;                               //!< True for builds in the build directory (not installed)
-            bool loaded_;                                   //!< Only true if constructor was interrupted
+            CoreConfiguration*    configuration_;
 
             static Core* singletonRef_s;
Index: code/trunk/src/core/CorePrereqs.h
===================================================================
--- code/trunk/src/core/CorePrereqs.h	(revision 3214)
+++ code/trunk/src/core/CorePrereqs.h	(revision 3280)
@@ -74,5 +74,5 @@
     namespace KeybindMode
     {
-        enum Enum
+        enum Value
         {
             OnPress,
@@ -165,4 +165,5 @@
     // game states
     class Game;
+    struct GameStateConstrParams;
     class GameState;
     struct GameStateTreeNode;
Index: code/trunk/src/core/Executor.cc
===================================================================
--- code/trunk/src/core/Executor.cc	(revision 3214)
+++ code/trunk/src/core/Executor.cc	(revision 3280)
@@ -99,13 +99,13 @@
 
             // assign all given arguments to the multitypes
-            for (unsigned int i = 0; i < min(tokens.size(), (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)
+            for (unsigned int i = 0; i < std::min(tokens.size(), (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)
                 param[i] = tokens[i];
 
             // fill the remaining multitypes with default values
-            for (unsigned int i = tokens.size(); i < min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)
+            for (unsigned int i = tokens.size(); i < std::min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)
                 param[i] = this->defaultValue_[i];
 
             // evaluate the param types through the functor
-            for (unsigned int i = 0; i < min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)
+            for (unsigned int i = 0; i < std::min(paramCount, (unsigned int)MAX_FUNCTOR_ARGUMENTS); i++)
                 this->functor_->evaluateParam(i, param[i]);
 
Index: code/trunk/src/core/Executor.h
===================================================================
--- code/trunk/src/core/Executor.h	(revision 3214)
+++ code/trunk/src/core/Executor.h	(revision 3280)
@@ -33,7 +33,10 @@
 #include "CorePrereqs.h"
 
+#include <algorithm>
+#include <string>
+
 #include "util/Debug.h"
 #include "util/Math.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "util/SubString.h"
 #include "Functor.h"
@@ -101,5 +104,5 @@
             COUT(5) << tokens[i]; \
         } \
-        COUT(5) << ") and " << max((int)paramCount - (int)tokens.size(), 0) << " default values ("; \
+        COUT(5) << ") and " << std::max((int)paramCount - (int)tokens.size(), 0) << " default values ("; \
         for (unsigned int i = tokens.size(); i < paramCount; i++) \
         { \
@@ -175,5 +178,5 @@
             inline bool hasReturnvalue() const
                 { return this->functor_->hasReturnvalue(); }
-            inline FunctionType getType() const
+            inline FunctionType::Value getType() const
                 { return this->functor_->getType(); }
             inline const MultiType& getReturnvalue() const
@@ -201,5 +204,5 @@
                     return this->defaultValue_[index];
 
-                return MT_null;
+                return MT_Type::Null;
             }
 
Index: code/trunk/src/core/Functor.h
===================================================================
--- code/trunk/src/core/Functor.h	(revision 3214)
+++ code/trunk/src/core/Functor.h	(revision 3280)
@@ -35,5 +35,5 @@
 #include "util/Debug.h"
 #include "util/MultiType.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 
 namespace orxonox
@@ -41,10 +41,13 @@
     const unsigned int MAX_FUNCTOR_ARGUMENTS = 5;
 
-    enum FunctionType
+    namespace FunctionType
     {
-        FT_MEMBER,
-        FT_CONSTMEMBER,
-        FT_STATIC
-    };
+        enum Value
+        {
+            Member,
+            ConstMember,
+            Static
+        };
+    }
 
 
@@ -98,9 +101,9 @@
             virtual ~Functor() {}
 
-            virtual void operator()(const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;
+            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
 
             inline unsigned int getParamCount() const { return this->numParams_; }
             inline bool hasReturnvalue() const { return this->hasReturnValue_; }
-            inline FunctionType getType() const { return this->type_; }
+            inline FunctionType::Value getType() const { return this->type_; }
             inline const MultiType& getReturnvalue() const { return this->returnedValue_; }
 
@@ -113,5 +116,5 @@
             unsigned int numParams_;
             bool hasReturnValue_;
-            FunctionType type_;
+            FunctionType::Value type_;
             MultiType returnedValue_;
 
@@ -124,5 +127,5 @@
         public:
             virtual ~FunctorStatic() {}
-            virtual void operator()(const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;
+            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
     };
 
@@ -139,8 +142,8 @@
             virtual ~FunctorMember() {}
 
-            virtual void operator()(T* object, const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;
-            virtual void operator()(const T* object, const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) = 0;
-
-            virtual void operator()(const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null)
+            virtual void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
+            virtual void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
+
+            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null)
             {
                 if (this->bConstObject_)
@@ -322,5 +325,5 @@
                 this->numParams_ = numparams; \
                 this->hasReturnValue_ = returnvalue; \
-                this->type_ = FT_STATIC; \
+                this->type_ = FunctionType::Static; \
                 this->functionPointer_ = functionPointer; \
                 \
@@ -329,5 +332,5 @@
             } \
     \
-            void operator()(const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \
+            void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
             { \
                 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
@@ -363,14 +366,14 @@
                 this->numParams_ = numparams; \
                 this->hasReturnValue_ = returnvalue; \
-                this->type_ = FT_MEMBER; \
+                this->type_ = FunctionType::Member; \
                 this->functionPointer_ = functionPointer; \
             } \
     \
-            void operator()(T* object, const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \
+            void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
             { \
                 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
             } \
     \
-            void operator()(const T* object, const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \
+            void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
             { \
                 COUT(1) << "An error occurred in Functor.h:" << std::endl; \
@@ -396,14 +399,14 @@
                 this->numParams_ = numparams; \
                 this->hasReturnValue_ = returnvalue; \
-                this->type_ = FT_CONSTMEMBER; \
+                this->type_ = FunctionType::ConstMember; \
                 this->functionPointer_ = functionPointer; \
             } \
     \
-            void operator()(T* object, const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \
+            void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
             { \
                 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
             } \
     \
-            void operator()(const T* object, const MultiType& param1 = MT_null, const MultiType& param2 = MT_null, const MultiType& param3 = MT_null, const MultiType& param4 = MT_null, const MultiType& param5 = MT_null) \
+            void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
             { \
                 FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
Index: code/trunk/src/core/Game.cc
===================================================================
--- code/trunk/src/core/Game.cc	(revision 3214)
+++ code/trunk/src/core/Game.cc	(revision 3280)
@@ -58,5 +58,13 @@
     SetConsoleCommandShortcutExternAlias(stop_game, "exit");
 
-    struct _CoreExport GameStateTreeNode
+    std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s;
+    Game* Game::singletonRef_s = 0;
+
+
+    /**
+    @brief
+        Represents one node of the game state tree.
+    */
+    struct GameStateTreeNode
     {
         GameState* state_;
@@ -65,6 +73,32 @@
     };
 
-    std::map<std::string, GameState*> Game::allStates_s;
-    Game* Game::singletonRef_s = 0;
+
+    /**
+    @brief
+        Another helper class for the Game singleton: we cannot derive
+        Game from OrxonoxClass because we need to handle the Identifier
+        destruction in the Core destructor.
+    */
+    class GameConfiguration : public OrxonoxClass
+    {
+    public:
+        GameConfiguration()
+        {
+            RegisterRootObject(GameConfiguration);
+            this->setConfigValues();
+        }
+
+        void setConfigValues()
+        {
+            SetConfigValue(statisticsRefreshCycle_, 250000)
+                .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
+            SetConfigValue(statisticsAvgLength_, 1000000)
+                .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
+        }
+
+        unsigned int statisticsRefreshCycle_;
+        unsigned int statisticsAvgLength_;
+    };
+
 
     /**
@@ -74,8 +108,16 @@
     Game::Game(int argc, char** argv)
     {
-        assert(singletonRef_s == 0);
+        if (singletonRef_s != 0)
+        {
+            COUT(0) << "Error: The Game singleton cannot be recreated! Shutting down." << std::endl;
+            abort();
+        }
         singletonRef_s = this;
 
-        this->abort_ = false;
+        this->bAbort_ = false;
+        bChangingState_ = false;
+
+        // Create an empty root state
+        declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
 
         // reset statistics
@@ -87,13 +129,28 @@
         this->avgTickTime_ = 0.0f;
 
-
         // Set up a basic clock to keep time
         this->gameClock_ = new Clock();
 
-        this->core_ = new orxonox::Core();
-        this->core_->initialise(argc, argv);
-
-        RegisterRootObject(Game);
-        this->setConfigValues();
+        // Create the Core
+        this->core_ = new Core(argc, argv);
+
+        // After the core has been created, we can safely instantiate the GameStates
+        for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
+            it != gameStateDeclarations_s.end(); ++it)
+        {
+            // Only create the states appropriate for the game mode
+            //if (GameMode::showsGraphics || !it->second.bGraphicsMode)
+            GameStateConstrParams params = { it->second.stateName, it->second.bIgnoreTickTime };
+            gameStates_[getLowercase(it->second.stateName)] = GameStateFactory::fabricate(it->second.className, params);
+        }
+
+        // The empty root state is ALWAYS loaded!
+        this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
+        this->rootStateNode_->state_ = getState("emptyRootGameState");
+        this->activeStateNode_ = this->rootStateNode_;
+        this->activeStates_.push_back(this->rootStateNode_->state_);
+
+        // Do this after the Core creation!
+        this->configuration_ = new GameConfiguration();
     }
 
@@ -103,36 +160,20 @@
     Game::~Game()
     {
-        // Destroy pretty much everyhting left
+        // Destroy the configuration helper class instance
+        delete this->configuration_;
+
+        // Destroy the GameStates (note that the nodes still point to them, but doesn't matter)
+        for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin();
+            it != gameStates_.end(); ++it)
+            delete it->second;
+
+        // Destroy the Core and with it almost everything
         delete this->core_;
-
         delete this->gameClock_;
 
-        assert(singletonRef_s);
-        singletonRef_s = 0;
-    }
-
-    void Game::setConfigValues()
-    {
-        SetConfigValue(statisticsRefreshCycle_, 250000)
-            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
-        SetConfigValue(statisticsAvgLength_, 1000000)
-            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
-        SetConfigValue(levelName_, "presentation_dm.oxw")
-            .description("Sets the preselection of the level in the main menu.");
-    }
-
-    void Game::setLevel(std::string levelName)
-    {
-        ModifyConfigValue(levelName_, set, levelName);
-    }
-
-    std::string Game::getLevel()
-    {
-        std::string levelName;
-        CommandLine::getValue("level", &levelName);
-        if (levelName == "")
-            return levelName_;
-        else
-            return levelName;
+        // Take care of the GameStateFactories
+        GameStateFactory::destroyFactories();
+
+        // Don't assign singletonRef_s with NULL! Recreation is not supported
     }
 
@@ -147,12 +188,10 @@
     void Game::run()
     {
-        // Always start with the ROOT state
-        this->requestedStateNodes_.push_back(this->rootStateNode_);
-        this->activeStateNode_ = this->rootStateNode_;
-        this->loadState(this->rootStateNode_->state_);
+        if (this->requestedStateNodes_.empty())
+            COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl;
 
         // START GAME
         this->gameClock_->capture(); // first delta time should be about 0 seconds
-        while (!this->abort_ && !this->activeStates_.empty())
+        while (!this->bAbort_ && (!this->activeStates_.empty() || this->requestedStateNodes_.size() > 0))
         {
             this->gameClock_->capture();
@@ -160,48 +199,97 @@
 
             // STATISTICS
-            statisticsTickInfo tickInfo = {currentTime, 0};
+            StatisticsTickInfo tickInfo = {currentTime, 0};
             statisticsTickTimes_.push_back(tickInfo);
             this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
 
             // UPDATE STATE STACK
-            while (this->requestedStateNodes_.size() > 1)
-            {
-                // Note: this->requestedStateNodes_.front() is the currently active state node
-                std::vector<shared_ptr<GameStateTreeNode> >::iterator it = this->requestedStateNodes_.begin() + 1;
-                if (*it == this->activeStateNode_->parent_.lock())
+            while (this->requestedStateNodes_.size() > 0)
+            {
+                shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
+                assert(this->activeStateNode_);
+                if (!this->activeStateNode_->parent_.expired() && requestedStateNode == this->activeStateNode_->parent_.lock())
                     this->unloadState(this->activeStateNode_->state_);
                 else // has to be child
-                    this->loadState((*it)->state_);
-                this->activeStateNode_ = *it;
+                {
+                    try
+                    {
+                        this->loadState(requestedStateNode->state_);
+                    }
+                    catch (const std::exception& ex)
+                    {
+                        COUT(1) << "Error: Loading GameState '" << requestedStateNode->state_->getName() << "' failed: " << ex.what() << std::endl;
+                        // All scheduled operations have now been rendered inert --> flush them and issue a warning
+                        if (this->requestedStateNodes_.size() > 1)
+                            COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
+                        this->requestedStateNodes_.clear();
+                        break;
+                    }
+                }
+                this->activeStateNode_ = requestedStateNode;
                 this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
             }
 
-            // UPDATE, bottom to top in the stack
-            this->core_->update(*this->gameClock_);
-            for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin();
+            // UPDATE, Core first
+            try
+            {
+                this->core_->update(*this->gameClock_);
+            }
+            catch (...)
+            {
+                COUT(0) << "An exception occured while ticking the Core. This should really never happen!" << std::endl;
+                COUT(0) << "Closing the program." << std::endl;
+                this->stop();
+                break;
+            }
+
+            // UPDATE, GameStates bottom to top in the stack
+            // Note: The first element is the empty root state, which doesn't need ticking
+            for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin() + 1;
                 it != this->activeStates_.end(); ++it)
             {
-                // Add tick time for most of the states
-                uint64_t timeBeforeTick;
-                if ((*it)->getCountTickTime())
-                    timeBeforeTick = this->gameClock_->getRealMicroseconds();
-                
-                (*it)->update(*this->gameClock_);
-
-                if ((*it)->getCountTickTime())
-                    this->addTickTime(static_cast<uint32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
+                bool threwException = false;
+                try
+                {
+                    // Add tick time for most of the states
+                    uint64_t timeBeforeTick;
+                    if (!(*it)->ignoreTickTime())
+                        timeBeforeTick = this->gameClock_->getRealMicroseconds();
+                    (*it)->update(*this->gameClock_);
+                    if (!(*it)->ignoreTickTime())
+                        this->addTickTime(static_cast<uint32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
+                }
+                catch (const std::exception& ex)
+                {
+                    threwException = true;
+                    COUT(0) << "Exception while ticking: " << ex.what() << std::endl;
+                }
+                catch (...)
+                {
+                    threwException = true;
+                }
+                if (threwException)
+                {
+                    COUT(1) << "An exception occured while ticking GameState '" << (*it)->getName() << "'. This should really never happen!" << std::endl;
+                    COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
+                    if ((*it)->getParent() != NULL)
+                        this->requestState((*it)->getParent()->getName());
+                    else
+                        this->stop();
+                    break;
+                }
+
             }
 
             // STATISTICS
-            if (this->periodTime_ > statisticsRefreshCycle_)
-            {
-                std::list<statisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
+            if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
+            {
+                std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
                 assert(it != this->statisticsTickTimes_.end());
-                int64_t lastTime = currentTime - this->statisticsAvgLength_;
+                int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
                 if ((int64_t)it->tickTime < lastTime)
                 {
                     do
                     {
-                        assert(this->periodTickTime_ > it->tickLength);
+                        assert(this->periodTickTime_ >= it->tickLength);
                         this->periodTickTime_ -= it->tickLength;
                         ++it;
@@ -215,12 +303,12 @@
                 this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
 
-                this->periodTime_ -= this->statisticsRefreshCycle_;
+                this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
             }
         }
 
         // UNLOAD all remaining states
-        while (!this->activeStates_.empty())
+        while (this->activeStates_.size() > 1)
             this->unloadState(this->activeStates_.back());
-        this->activeStateNode_.reset();
+        this->activeStateNode_ = this->rootStateNode_;
         this->requestedStateNodes_.clear();
     }
@@ -228,5 +316,5 @@
     void Game::stop()
     {
-        this->abort_ = true;
+        this->bAbort_ = true;
     }
 
@@ -244,13 +332,18 @@
     {
         GameState* state = this->getState(name);
-        if (state == NULL || this->activeStateNode_ == NULL)
+        if (state == NULL)
             return;
 
-        shared_ptr<GameStateTreeNode> requestedNode;
-
-        // this->requestedStateNodes_.back() is the currently active state
-        shared_ptr<GameStateTreeNode> lastRequestedNode = this->requestedStateNodes_.back();
-
-        // Already the active node?
+        //if (this->bChangingState_)
+        //{
+        //    COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
+        //    return;
+        //}
+
+        shared_ptr<GameStateTreeNode> lastRequestedNode;
+        if (this->requestedStateNodes_.empty())
+            lastRequestedNode = this->activeStateNode_;
+        else
+            lastRequestedNode = this->requestedStateNodes_.back();
         if (state == lastRequestedNode->state_)
         {
@@ -260,26 +353,31 @@
 
         // Check children first
+        std::vector<shared_ptr<GameStateTreeNode> > requestedNodes;
         for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
         {
             if (lastRequestedNode->children_[i]->state_ == state)
             {
-                requestedNode = lastRequestedNode->children_[i];
+                requestedNodes.push_back(lastRequestedNode->children_[i]);
                 break;
             }
         }
 
-        // Check parent and all its grand parents
-        shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode;
-        while (requestedNode == NULL && currentNode != NULL)
-        {
-            if (currentNode->state_ == state)
-                requestedNode = currentNode;
-            currentNode = currentNode->parent_.lock();
-        }
-
-        if (requestedNode == NULL)
+        if (requestedNodes.empty())
+        {
+            // Check parent and all its grand parents
+            shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode;
+            while (currentNode != NULL)
+            {
+                if (currentNode->state_ == state)
+                    break;
+                currentNode = currentNode->parent_.lock();
+                requestedNodes.push_back(currentNode);
+            }
+        }
+
+        if (requestedNodes.empty())
             COUT(1) << "Error: Requested GameState transition is not allowed. Ignoring." << std::endl;
         else
-            this->requestedStateNodes_.push_back(requestedNode);
+            this->requestedStateNodes_.insert(requestedStateNodes_.end(), requestedNodes.begin(), requestedNodes.end());
     }
 
@@ -293,14 +391,19 @@
     void Game::popState()
     {
-        if (this->activeStateNode_ != NULL && this->requestedStateNodes_.back()->parent_.lock())
-            this->requestState(this->requestedStateNodes_.back()->parent_.lock()->state_->getName());
+        shared_ptr<GameStateTreeNode> lastRequestedNode;
+        if (this->requestedStateNodes_.empty())
+            lastRequestedNode = this->activeStateNode_;
         else
-            COUT(2) << "Warning: Could not pop GameState. Ignoring." << std::endl;
+            lastRequestedNode = this->requestedStateNodes_.back();
+        if (lastRequestedNode != this->rootStateNode_)
+            this->requestState(lastRequestedNode->parent_.lock()->state_->getName());
+        else
+            COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl;
     }
 
     GameState* Game::getState(const std::string& name)
     {
-        std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(name));
-        if (it != allStates_s.end())
+        std::map<std::string, GameState*>::const_iterator it = gameStates_.find(getLowercase(name));
+        if (it != gameStates_.end())
             return it->second;
         else
@@ -325,58 +428,37 @@
             while(pos < str.size() && str[pos] != ' ')
                 ++pos;
-            stateStrings.push_back(std::pair<std::string, unsigned>(
-                str.substr(startPos, pos - startPos), indentation));
+            stateStrings.push_back(std::make_pair(str.substr(startPos, pos - startPos), indentation));
         }
         unsigned int currentLevel = 0;
-        shared_ptr<GameStateTreeNode> currentNode;
+        shared_ptr<GameStateTreeNode> currentNode = this->rootStateNode_;
         for (std::vector<std::pair<std::string, unsigned> >::const_iterator it = stateStrings.begin(); it != stateStrings.end(); ++it)
         {
             std::string newStateName = it->first;
-            unsigned newLevel = it->second;
+            unsigned newLevel = it->second + 1; // empty root is 0
             GameState* newState = this->getState(newStateName);
             if (!newState)
-                ThrowException(GameState, std::string("GameState with name '") + newStateName + "' not found!");
-            if (newLevel == 0)
-            {
-                // root
-                if (this->rootStateNode_ != NULL)
-                    ThrowException(GameState, "No two root GameStates are allowed!");
-                shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode);
-                newNode->state_ = newState;
-                this->rootStateNode_ = newNode;
-                currentNode = this->rootStateNode_;
-            }
-            else if (currentNode)
-            {
-                shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode);
-                newNode->state_ = newState;
-                if (newLevel < currentLevel)
-                {
-                    // Get down the hierarchy
-                    do
-                        currentNode = currentNode->parent_.lock();
-                    while (newLevel < --currentLevel);
-                }
-                if (newLevel == currentLevel)
-                {
-                    // same level
-                    newNode->parent_ = currentNode->parent_;
-                    newNode->parent_.lock()->children_.push_back(newNode);
-                }
-                else if (newLevel == currentLevel + 1)
-                {
-                    // child
-                    newNode->parent_ = currentNode;
-                    currentNode->children_.push_back(newNode);
-                }
-                else
-                    ThrowException(GameState, "Indentation error while parsing the hierarchy.");
-                currentNode = newNode;
-                currentLevel = newLevel;
+                ThrowException(GameState, "GameState with name '" << newStateName << "' not found!");
+            if (newState == this->rootStateNode_->state_)
+                ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy...");
+            shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode);
+            newNode->state_ = newState;
+
+            if (newLevel <= currentLevel)
+            {
+                do
+                    currentNode = currentNode->parent_.lock();
+                while (newLevel <= --currentLevel);
+            }
+            if (newLevel == currentLevel + 1)
+            {
+                // Add the child
+                newNode->parent_ = currentNode;
+                currentNode->children_.push_back(newNode);
+                currentNode->state_->addChild(newNode->state_);
             }
             else
-            {
-                ThrowException(GameState, "No root GameState specified!");
-            }
+                ThrowException(GameState, "Indentation error while parsing the hierarchy.");
+            currentNode = newNode;
+            currentLevel = newLevel;
         }
     }
@@ -386,38 +468,46 @@
     void Game::loadState(GameState* state)
     {
+        this->bChangingState_ = true;
+        state->activate();
         if (!this->activeStates_.empty())
             this->activeStates_.back()->activity_.topState = false;
-        state->activate();
+        this->activeStates_.push_back(state);
         state->activity_.topState = true;
-        this->activeStates_.push_back(state);
+        this->bChangingState_ = false;
     }
 
     void Game::unloadState(orxonox::GameState* state)
     {
+        this->bChangingState_ = true;
         state->activity_.topState = false;
-        state->deactivate();
         this->activeStates_.pop_back();
         if (!this->activeStates_.empty())
             this->activeStates_.back()->activity_.topState = true;
-    }
-
-    /*static*/ bool Game::addGameState(GameState* state)
-    {
-        std::map<std::string, GameState*>::const_iterator it = allStates_s.find(getLowercase(state->getName()));
-        if (it == allStates_s.end())
-            allStates_s[getLowercase(state->getName())] = state;
-        else
-            ThrowException(GameState, "Cannot add two GameStates with the same name to 'Game'.");
-
-        // just a required dummy return value
-        return true;
-    }
-
-    /*static*/ void Game::destroyStates()
-    {
-        // Delete all GameStates created by the macros
-        for (std::map<std::string, GameState*>::const_iterator it = allStates_s.begin(); it != allStates_s.end(); ++it)
+        try
+        {
+            state->deactivate();
+        }
+        catch (const std::exception& ex)
+        {
+            COUT(2) << "Warning: Unloading GameState '" << state->getName() << "' threw an exception: " << ex.what() << std::endl;
+            COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
+        }
+        this->bChangingState_ = false;
+    }
+
+    std::map<std::string, Game::GameStateFactory*> Game::GameStateFactory::factories_s;
+
+    /*static*/ GameState* Game::GameStateFactory::fabricate(const std::string& className, const GameStateConstrParams& params)
+    {
+        std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.find(className);
+        assert(it != factories_s.end());
+        return it->second->fabricate(params);
+    }
+
+    /*static*/ void Game::GameStateFactory::destroyFactories()
+    {
+        for (std::map<std::string, GameStateFactory*>::const_iterator it = factories_s.begin(); it != factories_s.end(); ++it)
             delete it->second;
-        allStates_s.clear();
+        factories_s.clear();
     }
 }
Index: code/trunk/src/core/Game.h
===================================================================
--- code/trunk/src/core/Game.h	(revision 3214)
+++ code/trunk/src/core/Game.h	(revision 3280)
@@ -46,5 +46,6 @@
 #include <boost/preprocessor/cat.hpp>
 
-#include "OrxonoxClass.h"
+#include "util/Debug.h"
+#include "util/StringUtils.h"
 
 /**
@@ -53,10 +54,11 @@
     and every following paramter is a constructor argument (which is usually non existent)
 */
-#define AddGameState(classname, ...) \
-    static bool BOOST_PP_CAT(bGameStateDummy_##classname, __LINE__) = orxonox::Game::addGameState(new classname(__VA_ARGS__))
+#define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
+    static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
 
-// tolua_begin
 namespace orxonox
 {
+    class GameConfiguration;
+
     /**
     @brief
@@ -64,13 +66,8 @@
     */
     class _CoreExport Game
-    // tolua_end
-        : public OrxonoxClass
-    // tolua_begin
     {
-    //tolua_end
     public:
         Game(int argc, char** argv);
         ~Game();
-        void setConfigValues();
 
         void setStateHierarchy(const std::string& str);
@@ -91,13 +88,39 @@
         void addTickTime(uint32_t length);
 
-        static bool addGameState(GameState* state);
-        static void destroyStates();
-        static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; } //tolua_export
-
-        void setLevel(std::string levelName); //tolua_export
-        std::string getLevel(); //tolua_export
+        template <class T>
+        static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
+        static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
 
     private:
-        struct statisticsTickInfo
+        class _CoreExport GameStateFactory
+        {
+        public:
+            virtual ~GameStateFactory() { }
+            static GameState* fabricate(const std::string& className, const GameStateConstrParams& params);
+            template <class T>
+            static void createFactory(const std::string& className)
+                { factories_s[className] = new TemplateGameStateFactory<T>(); }
+            static void destroyFactories();
+        private:
+            virtual GameState* fabricate(const GameStateConstrParams& params) = 0;
+            static std::map<std::string, GameStateFactory*> factories_s;
+        };
+        template <class T>
+        class TemplateGameStateFactory : public GameStateFactory
+        {
+        public:
+            GameState* fabricate(const GameStateConstrParams& params)
+                { return new T(params); }
+        };
+
+        struct GameStateInfo
+        {
+            std::string stateName;
+            std::string className;
+            bool bIgnoreTickTime;
+            bool bGraphicsMode;
+        };
+
+        struct StatisticsTickInfo
         {
             uint64_t    tickTime;
@@ -110,5 +133,6 @@
         void unloadState(GameState* state);
 
-        std::vector<GameState*>         activeStates_;
+        std::map<std::string, GameState*>    gameStates_;
+        std::vector<GameState*>              activeStates_;
         boost::shared_ptr<GameStateTreeNode> rootStateNode_;
         boost::shared_ptr<GameStateTreeNode> activeStateNode_;
@@ -117,10 +141,12 @@
         Core*                           core_;
         Clock*                          gameClock_;
+        GameConfiguration*              configuration_;
 
-        bool                            abort_;
+        bool                            bChangingState_;
+        bool                            bAbort_;
 
         // variables for time statistics
         uint64_t                        statisticsStartTime_;
-        std::list<statisticsTickInfo>   statisticsTickTimes_;
+        std::list<StatisticsTickInfo>   statisticsTickTimes_;
         uint32_t                        periodTime_;
         uint32_t                        periodTickTime_;
@@ -128,14 +154,33 @@
         float                           avgTickTime_;
 
-        // config values
-        unsigned int                    statisticsRefreshCycle_;
-        unsigned int                    statisticsAvgLength_;
-        std::string                     levelName_;
+        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
+        static Game* singletonRef_s;        //!< Pointer to the Singleton
+    };
 
-        static std::map<std::string, GameState*> allStates_s;
-        static Game* singletonRef_s;        //!< Pointer to the Singleton
-        // tolua_begin
-    };
+    template <class T>
+    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
+    {
+        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(getLowercase(stateName));
+        if (it == gameStateDeclarations_s.end())
+        {
+            GameStateInfo& info = gameStateDeclarations_s[getLowercase(stateName)];
+            info.stateName = stateName;
+            info.className = className;
+            info.bIgnoreTickTime = bIgnoreTickTime;
+            info.bGraphicsMode = bGraphicsMode;
+        }
+        else
+        {
+            COUT(0) << "Error: Cannot declare two GameStates with the same name." << std::endl;
+            COUT(0) << "       Ignoring second one ('" << stateName << "')." << std::endl;
+        }
+
+        // Create a factory to delay GameState creation
+        GameStateFactory::createFactory<T>(className);
+
+        // just a required dummy return value
+        return true;
+    }
 }
-//tolua_end
+
 #endif /* _Game_H__ */
Index: code/trunk/src/core/GameState.cc
===================================================================
--- code/trunk/src/core/GameState.cc	(revision 3214)
+++ code/trunk/src/core/GameState.cc	(revision 3280)
@@ -45,7 +45,7 @@
         Constructor only initialises variables and sets the name permanently.
     */
-    GameState::GameState(const std::string& name, bool countTickTime)
-        : name_(name)
-        , bCountTickTime_(countTickTime)
+    GameState::GameState(const GameStateConstrParams& params)
+        : name_(params.name)
+        , bIgnoreTickTime_(params.bIgnoreTickTime)
         , parent_(0)
     {
Index: code/trunk/src/core/GameState.h
===================================================================
--- code/trunk/src/core/GameState.h	(revision 3214)
+++ code/trunk/src/core/GameState.h	(revision 3280)
@@ -45,4 +45,14 @@
     /**
     @brief
+        Helper class to group construction parameters for better genericity.
+    */
+    struct GameStateConstrParams
+    {
+        std::string name;
+        bool bIgnoreTickTime;
+    };
+
+    /**
+    @brief
         An implementation of a tree to manage game states.
         This leads to a certain hierarchy that is created at runtime.
@@ -77,5 +87,5 @@
 
     public:
-        GameState(const std::string& name, bool countTicktime = true);
+        GameState(const GameStateConstrParams& params);
         virtual ~GameState();
 
@@ -84,5 +94,5 @@
         GameState* getParent()       const { return this->parent_; }
 
-        bool getCountTickTime()      const { return this->bCountTickTime_; }
+        bool ignoreTickTime()        const { return this->bIgnoreTickTime_; }
 
         void addChild(GameState* state);
@@ -90,7 +100,7 @@
 
     protected:
-        virtual void activate() = 0;
-        virtual void deactivate() = 0;
-        virtual void update(const Clock& time) = 0;
+        virtual void activate() { }
+        virtual void deactivate() { }
+        virtual void update(const Clock& time) { }
 
     private:
@@ -103,5 +113,5 @@
         const std::string                        name_;
         State                                    activity_;
-        const bool                               bCountTickTime_;
+        const bool                               bIgnoreTickTime_;
         GameState*                               parent_;
         std::map<std::string, GameState*>        children_;
Index: code/trunk/src/core/IRC.cc
===================================================================
--- code/trunk/src/core/IRC.cc	(revision 3214)
+++ code/trunk/src/core/IRC.cc	(revision 3280)
@@ -68,5 +68,5 @@
         {   COUT(1) << "Error while initializing Tcl (IRC): " << e.what();   }
 
-        this->nickname_ = "orx" + getConvertedValue<int, std::string>((unsigned int)rand());
+        this->nickname_ = "orx" + multi_cast<std::string>(static_cast<unsigned int>(rand()));
         TclThreadManager::execute(threadID, "set nickname " + this->nickname_);
         TclThreadManager::execute(threadID, "source irc.tcl");
Index: code/trunk/src/core/Identifier.cc
===================================================================
--- code/trunk/src/core/Identifier.cc	(revision 3214)
+++ code/trunk/src/core/Identifier.cc	(revision 3280)
@@ -36,5 +36,5 @@
 #include <ostream>
 
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "ConfigValueContainer.h"
 #include "ConsoleCommand.h"
Index: code/trunk/src/core/Language.cc
===================================================================
--- code/trunk/src/core/Language.cc	(revision 3214)
+++ code/trunk/src/core/Language.cc	(revision 3280)
@@ -194,5 +194,5 @@
         @return The filename
     */
-    const std::string Language::getFilename(const std::string& language)
+    std::string Language::getFilename(const std::string& language)
     {
         return std::string("translation_" + language + ".lang");
Index: code/trunk/src/core/Language.h
===================================================================
--- code/trunk/src/core/Language.h	(revision 3214)
+++ code/trunk/src/core/Language.h	(revision 3280)
@@ -114,5 +114,5 @@
     class _CoreExport Language
     {
-        friend class Core;
+        friend class CoreConfiguration;
 
         public:
@@ -130,5 +130,5 @@
             void readTranslatedLanguageFile();
             void writeDefaultLanguageFile() const;
-            static const std::string getFilename(const std::string& language);
+            static std::string getFilename(const std::string& language);
             LanguageEntry* createEntry(const LanguageEntryLabel& label, const std::string& entry);
 
Index: code/trunk/src/core/LuaBind.cc
===================================================================
--- code/trunk/src/core/LuaBind.cc	(revision 3214)
+++ code/trunk/src/core/LuaBind.cc	(revision 3280)
@@ -38,5 +38,5 @@
 
 #include "util/Debug.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "ToluaBindCore.h"
 #include "Core.h"
Index: code/trunk/src/core/OrxonoxClass.cc
===================================================================
--- code/trunk/src/core/OrxonoxClass.cc	(revision 3214)
+++ code/trunk/src/core/OrxonoxClass.cc	(revision 3280)
@@ -78,40 +78,40 @@
 
     /** @brief Returns true if the objects class is of the given type or a derivative. */
-    bool OrxonoxClass::isA(const SubclassIdentifier<class B>* identifier)
+    template <class B> bool OrxonoxClass::isA(const SubclassIdentifier<B>* identifier)
         { return this->getIdentifier()->isA(identifier->getIdentifier()); }
     /** @brief Returns true if the objects class is exactly of the given type. */
-    bool OrxonoxClass::isExactlyA(const SubclassIdentifier<class B>* identifier)
+    template <class B> bool OrxonoxClass::isExactlyA(const SubclassIdentifier<B>* identifier)
         { return this->getIdentifier()->isExactlyA(identifier->getIdentifier()); }
     /** @brief Returns true if the objects class is a child of the given type. */
-    bool OrxonoxClass::isChildOf(const SubclassIdentifier<class B>* identifier)
+    template <class B> bool OrxonoxClass::isChildOf(const SubclassIdentifier<B>* identifier)
         { return this->getIdentifier()->isChildOf(identifier->getIdentifier()); }
     /** @brief Returns true if the objects class is a direct child of the given type. */
-    bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<class B>* identifier)
+    template <class B> bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<B>* identifier)
         { return this->getIdentifier()->isDirectChildOf(identifier->getIdentifier()); }
     /** @brief Returns true if the objects class is a parent of the given type. */
-    bool OrxonoxClass::isParentOf(const SubclassIdentifier<class B>* identifier)
+    template <class B> bool OrxonoxClass::isParentOf(const SubclassIdentifier<B>* identifier)
         { return this->getIdentifier()->isParentOf(identifier->getIdentifier()); }
     /** @brief Returns true if the objects class is a direct parent of the given type. */
-    bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<class B>* identifier)
+    template <class B> bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<B>* identifier)
         { return this->getIdentifier()->isDirectParentOf(identifier->getIdentifier()); }
 
 
     /** @brief Returns true if the objects class is of the given type or a derivative. */
-    bool OrxonoxClass::isA(const SubclassIdentifier<class B> identifier)
+    template <class B> bool OrxonoxClass::isA(const SubclassIdentifier<B> identifier)
         { return this->getIdentifier()->isA(identifier.getIdentifier()); }
     /** @brief Returns true if the objects class is exactly of the given type. */
-    bool OrxonoxClass::isExactlyA(const SubclassIdentifier<class B> identifier)
+    template <class B> bool OrxonoxClass::isExactlyA(const SubclassIdentifier<B> identifier)
         { return this->getIdentifier()->isExactlyA(identifier.getIdentifier()); }
     /** @brief Returns true if the objects class is a child of the given type. */
-    bool OrxonoxClass::isChildOf(const SubclassIdentifier<class B> identifier)
+    template <class B> bool OrxonoxClass::isChildOf(const SubclassIdentifier<B> identifier)
         { return this->getIdentifier()->isChildOf(identifier.getIdentifier()); }
     /** @brief Returns true if the objects class is a direct child of the given type. */
-    bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<class B> identifier)
+    template <class B> bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<B> identifier)
         { return this->getIdentifier()->isDirectChildOf(identifier.getIdentifier()); }
     /** @brief Returns true if the objects class is a parent of the given type. */
-    bool OrxonoxClass::isParentOf(const SubclassIdentifier<class B> identifier)
+    template <class B> bool OrxonoxClass::isParentOf(const SubclassIdentifier<B> identifier)
         { return this->getIdentifier()->isParentOf(identifier.getIdentifier()); }
     /** @brief Returns true if the objects class is a direct parent of the given type. */
-    bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<class B> identifier)
+    template <class B> bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<B> identifier)
         { return this->getIdentifier()->isDirectParentOf(identifier.getIdentifier()); }
 
Index: code/trunk/src/core/OrxonoxClass.h
===================================================================
--- code/trunk/src/core/OrxonoxClass.h	(revision 3214)
+++ code/trunk/src/core/OrxonoxClass.h	(revision 3280)
@@ -80,17 +80,17 @@
             bool isDirectParentOf(const Identifier* identifier);
 
-            bool isA(const SubclassIdentifier<class B>* identifier);
-            bool isExactlyA(const SubclassIdentifier<class B>* identifier);
-            bool isChildOf(const SubclassIdentifier<class B>* identifier);
-            bool isDirectChildOf(const SubclassIdentifier<class B>* identifier);
-            bool isParentOf(const SubclassIdentifier<class B>* identifier);
-            bool isDirectParentOf(const SubclassIdentifier<class B>* identifier);
+            template <class B> bool isA(const SubclassIdentifier<B>* identifier);
+            template <class B> bool isExactlyA(const SubclassIdentifier<B>* identifier);
+            template <class B> bool isChildOf(const SubclassIdentifier<B>* identifier);
+            template <class B> bool isDirectChildOf(const SubclassIdentifier<B>* identifier);
+            template <class B> bool isParentOf(const SubclassIdentifier<B>* identifier);
+            template <class B> bool isDirectParentOf(const SubclassIdentifier<B>* identifier);
 
-            bool isA(const SubclassIdentifier<class B> identifier);
-            bool isExactlyA(const SubclassIdentifier<class B> identifier);
-            bool isChildOf(const SubclassIdentifier<class B> identifier);
-            bool isDirectChildOf(const SubclassIdentifier<class B> identifier);
-            bool isParentOf(const SubclassIdentifier<class B> identifier);
-            bool isDirectParentOf(const SubclassIdentifier<class B> identifier);
+            template <class B> bool isA(const SubclassIdentifier<B> identifier);
+            template <class B> bool isExactlyA(const SubclassIdentifier<B> identifier);
+            template <class B> bool isChildOf(const SubclassIdentifier<B> identifier);
+            template <class B> bool isDirectChildOf(const SubclassIdentifier<B> identifier);
+            template <class B> bool isParentOf(const SubclassIdentifier<B> identifier);
+            template <class B> bool isDirectParentOf(const SubclassIdentifier<B> identifier);
 
             bool isA(const OrxonoxClass* object);
Index: code/trunk/src/core/Shell.cc
===================================================================
--- code/trunk/src/core/Shell.cc	(revision 3214)
+++ code/trunk/src/core/Shell.cc	(revision 3280)
@@ -78,4 +78,8 @@
         OutputHandler::getOutStream().setOutputBuffer(&this->outputBuffer_);
 
+        // Get a config file for the command history
+        this->commandHistoryConfigFileType_ = ConfigFileManager::getInstance().getNewConfigFileType();
+        ConfigFileManager::getInstance().setFilename(this->commandHistoryConfigFileType_, "commandHistory.ini");
+
         this->setConfigValues();
 
@@ -93,7 +97,9 @@
     void Shell::setConfigValues()
     {
-        SetConfigValue(maxHistoryLength_, 100).callback(this, &Shell::commandHistoryLengthChanged);
-        SetConfigValue(historyOffset_, 0).callback(this, &Shell::commandHistoryOffsetChanged);
-        SetConfigValueVector(commandHistory_, std::vector<std::string>());
+        SetConfigValueGeneric(commandHistoryConfigFileType_, maxHistoryLength_, 100)
+            .callback(this, &Shell::commandHistoryLengthChanged);
+        SetConfigValueGeneric(commandHistoryConfigFileType_, historyOffset_, 0)
+            .callback(this, &Shell::commandHistoryOffsetChanged);
+        SetConfigValueVectorGeneric(commandHistoryConfigFileType_, commandHistory_, std::vector<std::string>());
     }
 
Index: code/trunk/src/core/Shell.h
===================================================================
--- code/trunk/src/core/Shell.h	(revision 3214)
+++ code/trunk/src/core/Shell.h	(revision 3280)
@@ -37,7 +37,8 @@
 #include <vector>
 
+#include "util/OutputBuffer.h"
+#include "input/InputBuffer.h"
 #include "OrxonoxClass.h"
-#include "input/InputBuffer.h"
-#include "util/OutputBuffer.h"
+#include "ConfigFileManager.h"
 
 namespace orxonox
@@ -145,4 +146,6 @@
             bool bAddOutputLevel_;
 
+            ConfigFileType commandHistoryConfigFileType_;
+
             static Shell* singletonRef_s;
     };
Index: code/trunk/src/core/TclBind.cc
===================================================================
--- code/trunk/src/core/TclBind.cc	(revision 3214)
+++ code/trunk/src/core/TclBind.cc	(revision 3280)
@@ -34,5 +34,5 @@
 
 #include "util/Debug.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "CommandExecutor.h"
 #include "ConsoleCommand.h"
Index: code/trunk/src/core/TclThreadManager.cc
===================================================================
--- code/trunk/src/core/TclThreadManager.cc	(revision 3214)
+++ code/trunk/src/core/TclThreadManager.cc	(revision 3280)
@@ -94,5 +94,5 @@
         boost::mutex::scoped_lock bundles_lock(TclThreadManager::getInstance().bundlesMutex_);
         TclThreadManager::getInstance().threadCounter_++;
-        std::string name = getConvertedValue<unsigned int, std::string>(TclThreadManager::getInstance().threadCounter_);
+        std::string name = multi_cast<std::string>(TclThreadManager::getInstance().threadCounter_);
 
         TclInterpreterBundle* bundle = new TclInterpreterBundle;
@@ -192,5 +192,5 @@
         {
             boost::mutex::scoped_lock queue_lock(TclThreadManager::getInstance().orxonoxInterpreterBundle_.queueMutex_);
-            output += getConvertedValue<unsigned int, std::string>(TclThreadManager::getInstance().orxonoxInterpreterBundle_.queue_.size());
+            output += multi_cast<std::string>(TclThreadManager::getInstance().orxonoxInterpreterBundle_.queue_.size());
         }
         output += "\t\t";
@@ -201,9 +201,9 @@
         for (std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = TclThreadManager::getInstance().interpreterBundles_.begin(); it != TclThreadManager::getInstance().interpreterBundles_.end(); ++it)
         {
-            std::string output = getConvertedValue<unsigned int, std::string>((*it).first);
+            std::string output = multi_cast<std::string>((*it).first);
             output += "\t\t";
             {
                 boost::mutex::scoped_lock queue_lock((*it).second->queueMutex_);
-                output += getConvertedValue<unsigned int, std::string>((*it).second->queue_.size());
+                output += multi_cast<std::string>((*it).second->queue_.size());
             }
             output += "\t\t";
@@ -342,5 +342,5 @@
         else
         {
-            this->error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(threadID) + " existing.");
+            this->error("Error: No Tcl-interpreter with ID " + multi_cast<std::string>(threadID) + " existing.");
             return 0;
         }
@@ -355,5 +355,5 @@
                 output += " ";
 
-            output += getConvertedValue<unsigned int, std::string>(*it);
+            output += multi_cast<std::string>(*it);
         }
         return output;
@@ -444,5 +444,5 @@
             if (bundle->queue_.size() >= TCLTHREADMANAGER_MAX_QUEUE_LENGTH)
             {
-                this->error("Error: Queue of Tcl-interpreter " + getConvertedValue<unsigned int, std::string>(threadID) + " is full, couldn't add command.");
+                this->error("Error: Queue of Tcl-interpreter " + multi_cast<std::string>(threadID) + " is full, couldn't add command.");
                 return;
             }
@@ -492,5 +492,5 @@
         if (std::find(target->queriers_.begin(), target->queriers_.end(), target->id_) != target->queriers_.end())
         {
-            this->error("Error: Circular query (" + this->dumpList(target->queriers_) + " -> " + getConvertedValue<unsigned int, std::string>(target->id_) + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target->id_) + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(querier->id_) + ".");
+            this->error("Error: Circular query (" + this->dumpList(target->queriers_) + " -> " + multi_cast<std::string>(target->id_) + "), couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target->id_) + " from other interpreter with ID " + multi_cast<std::string>(querier->id_) + ".");
             return false;
         }
@@ -585,5 +585,5 @@
                     else
                     {
-                        this->error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(threadID) + ", interpreter is busy right now.");
+                        this->error("Error: Couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(threadID) + ", interpreter is busy right now.");
                     }
                 }
@@ -665,9 +665,9 @@
         catch (Tcl::tcl_error const &e)
         {
-            TclThreadManager::getInstance().error("Tcl (ID " + getConvertedValue<unsigned int, std::string>(interpreterBundle->id_) + ") error: " + e.what());
+            TclThreadManager::getInstance().error("Tcl (ID " + multi_cast<std::string>(interpreterBundle->id_) + ") error: " + e.what());
         }
         catch (std::exception const &e)
         {
-            TclThreadManager::getInstance().error("Error while executing Tcl (ID " + getConvertedValue<unsigned int, std::string>(interpreterBundle->id_) + "): " + e.what());
+            TclThreadManager::getInstance().error("Error while executing Tcl (ID " + multi_cast<std::string>(interpreterBundle->id_) + "): " + e.what());
         }
 
Index: code/trunk/src/core/input/Button.cc
===================================================================
--- code/trunk/src/core/input/Button.cc	(revision 3214)
+++ code/trunk/src/core/input/Button.cc	(revision 3280)
@@ -37,5 +37,5 @@
 #include "util/Convert.h"
 #include "util/SubString.h"
-#include "util/String.h"
+#include "util/StringUtils.h"
 #include "util/Debug.h"
 #include "core/ConsoleCommand.h"
@@ -127,5 +127,5 @@
                     '\\', false, '"', false, '(', ')', false, '\0');
 
-                KeybindMode::Enum mode = KeybindMode::None;
+                KeybindMode::Value mode = KeybindMode::None;
                 float paramModifier = 1.0f;
                 std::string commandStr = "";
Index: code/trunk/src/core/input/Button.h
===================================================================
--- code/trunk/src/core/input/Button.h	(revision 3214)
+++ code/trunk/src/core/input/Button.h	(revision 3280)
@@ -54,5 +54,5 @@
         void parse();
         void readConfigValue(ConfigFileType configFile);
-        bool execute(KeybindMode::Enum mode, float abs = 1.0f, float rel = 1.0f);
+        bool execute(KeybindMode::Value mode, float abs = 1.0f, float rel = 1.0f);
 
         //! Container to allow for better configValue support
@@ -79,5 +79,5 @@
     };
 
-    inline bool Button::execute(KeybindMode::Enum mode, float abs, float rel)
+    inline bool Button::execute(KeybindMode::Value mode, float abs, float rel)
     {
         // execute all the parsed commands in the string
Index: code/trunk/src/core/input/InputManager.cc
===================================================================
--- code/trunk/src/core/input/InputManager.cc	(revision 3214)
+++ code/trunk/src/core/input/InputManager.cc	(revision 3280)
@@ -43,5 +43,5 @@
 #include "util/Convert.h"
 #include "util/Exception.h"
-#include "util/Debug.h"
+#include "util/ScopeGuard.h"
 #include "core/Clock.h"
 #include "core/CoreIncludes.h"
@@ -70,5 +70,5 @@
     SetConsoleCommand(InputManager, ungrabMouse, true);
 #endif
-    SetCommandLineSwitch(keyboard_no_grab);
+    SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
 
     EmptyHandler InputManager::EMPTY_HANDLER;
@@ -177,7 +177,10 @@
             windowHndStr << (unsigned int)windowHnd_;
             paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
+#if defined(ORXONOX_PLATFORM_WINDOWS)
             //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 ORXONOX_PLATFORM_LINUX
+            //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
+            //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
+#elif defined(ORXONOX_PLATFORM_LINUX)
             paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
             paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
@@ -191,8 +194,20 @@
 #endif
 
-            inputSystem_ = OIS::InputManager::createInputSystem(paramList);
-            CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
-
-            _initialiseKeyboard();
+            try
+            {
+                inputSystem_ = OIS::InputManager::createInputSystem(paramList);
+                // Exception-safety
+                Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, inputSystem_);
+                CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
+
+                _initialiseKeyboard();
+
+                // Nothing below should throw anymore, dismiss the guard
+                guard.Dismiss();
+            }
+            catch (OIS::Exception& ex)
+            {
+                ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
+            }
 
             _initialiseMouse();
@@ -200,5 +215,5 @@
             if (joyStickSupport)
                 _initialiseJoySticks();
-            // Do this anyway to also inform everything when a joystick was detached.
+            // Do this anyway to also inform when a joystick was detached.
             _configureJoySticks();
 
@@ -273,5 +288,5 @@
         else
         {
-            ThrowException(InitialisationFailed, "No keyboard found!");
+            ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
         }
     }
@@ -301,5 +316,5 @@
             else
             {
-                CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl;
+                CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
             }
         }
@@ -307,5 +322,5 @@
         {
             CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
-                << "OIS error message: \"" << ex.eText << "\"" << std::endl;
+                << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl;
             mouse_ = 0;
         }
@@ -345,8 +360,4 @@
             }
         }
-        else
-        {
-            //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
-        }
     }
 
@@ -528,41 +539,38 @@
         if (internalState_ != Uninitialised)
         {
+            CCOUT(3) << "Destroying ..." << std::endl;
+
+            // kick all active states 'nicely'
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                rit != activeStates_.rend(); ++rit)
+            {
+                (*rit).second->onLeave();
+            }
+
+            // Destroy calibrator helper handler and state
+            delete keyDetector_;
+            requestDestroyState("calibrator");
+            // Destroy KeyDetector and state
+            delete calibratorCallbackBuffer_;
+            requestDestroyState("detector");
+            // destroy the empty InputState
+            _destroyState(this->stateEmpty_);
+
+            // destroy all user InputStates
+            while (inputStatesByName_.size() > 0)
+                _destroyState((*inputStatesByName_.rbegin()).second);
+
+            // destroy the devices
+            _destroyKeyboard();
+            _destroyMouse();
+            _destroyJoySticks();
+
             try
             {
-                CCOUT(3) << "Destroying ..." << std::endl;
-
-                // kick all active states 'nicely'
-                for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
-                    rit != activeStates_.rend(); ++rit)
-                {
-                    (*rit).second->onLeave();
-                }
-
-                // Destroy calibrator helper handler and state
-                delete keyDetector_;
-                requestDestroyState("calibrator");
-                // Destroy KeyDetector and state
-                delete calibratorCallbackBuffer_;
-                requestDestroyState("detector");
-                // destroy the empty InputState
-                _destroyState(this->stateEmpty_);
-
-                // destroy all user InputStates
-                while (inputStatesByName_.size() > 0)
-                    _destroyState((*inputStatesByName_.rbegin()).second);
-
-                // destroy the devices
-                _destroyKeyboard();
-                _destroyMouse();
-                _destroyJoySticks();
-
                 OIS::InputManager::destroyInputSystem(inputSystem_);
-
-                CCOUT(3) << "Destroying done." << std::endl;
-            }
-            catch (OIS::Exception& ex)
-            {
-                CCOUT(1) << "An exception has occured while destroying:\n" << ex.what()
-                         << "This could lead to a possible memory/resource leak!" << std::endl;
+            }
+            catch (...)
+            {
+                CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl;
             }
         }
@@ -578,8 +586,15 @@
     {
         assert(inputSystem_);
-        if (keyboard_)
-            inputSystem_->destroyInputObject(keyboard_);
-        keyboard_ = 0;
-        CCOUT(4) << "Keyboard destroyed." << std::endl;
+        try
+        {
+            if (keyboard_)
+                inputSystem_->destroyInputObject(keyboard_);
+            keyboard_ = 0;
+            CCOUT(4) << "Keyboard destroyed." << std::endl;
+        }
+        catch (...)
+        {
+            CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl;
+        }
     }
 
@@ -591,8 +606,15 @@
     {
         assert(inputSystem_);
-        if (mouse_)
-            inputSystem_->destroyInputObject(mouse_);
-        mouse_ = 0;
-        CCOUT(4) << "Mouse destroyed." << std::endl;
+        try
+        {
+            if (mouse_)
+                inputSystem_->destroyInputObject(mouse_);
+            mouse_ = 0;
+            CCOUT(4) << "Mouse destroyed." << std::endl;
+        }
+        catch (...)
+        {
+            CCOUT(1) << "Mouse destruction failed! Potential resource leak!" << std::endl;
+        }
     }
 
@@ -607,6 +629,15 @@
             assert(inputSystem_);
             for (unsigned int i = 0; i < joySticksSize_; i++)
-                if (joySticks_[i] != 0)
-                    inputSystem_->destroyInputObject(joySticks_[i]);
+            {
+                try
+                {
+                    if (joySticks_[i] != 0)
+                        inputSystem_->destroyInputObject(joySticks_[i]);
+                }
+                catch (...)
+                {
+                    CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
+                }
+            }
 
             joySticks_.clear();
Index: code/trunk/src/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/core/input/KeyBinder.cc	(revision 3214)
+++ code/trunk/src/core/input/KeyBinder.cc	(revision 3280)
@@ -96,6 +96,6 @@
         }
 
-        // Get a new ConfigFileType from the ConfigFileManager
-        this->configFile_ = ConfigFileManager::getInstance().getNewConfigFileType();
+        // We might not even load any bindings at all (KeyDetector for instance)
+        this->configFile_ = ConfigFileType::NoType;
 
         // initialise joy sticks separatly to allow for reloading
@@ -187,5 +187,5 @@
         for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
         {
-            std::string deviceNumber = convertToString(iDev);
+            std::string deviceNumber = multi_cast<std::string>(iDev);
             // joy stick buttons
             for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
@@ -249,4 +249,10 @@
         if (filename.empty())
             return;
+
+        if (this->configFile_ == ConfigFileType::NoType)
+        {
+            // Get a new ConfigFileType from the ConfigFileManager
+            this->configFile_ = ConfigFileManager::getInstance().getNewConfigFileType();
+        }
 
         ConfigFileManager::getInstance().setFilename(this->configFile_, filename);
