Index: /code/branches/FICN/src/orxonox/core/CMakeLists.txt
===================================================================
--- /code/branches/FICN/src/orxonox/core/CMakeLists.txt	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/CMakeLists.txt	(revision 704)
@@ -13,4 +13,5 @@
   DebugLevel.cc
   OutputHandler.cc
+  Language.cc
 )
 
Index: /code/branches/FICN/src/orxonox/core/ClassFactory.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/ClassFactory.h	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/ClassFactory.h	(revision 704)
@@ -60,5 +60,5 @@
             ClassFactory() {}                               // Don't create
             ClassFactory(const ClassFactory& factory) {}    // Don't copy
-            ~ClassFactory() {}                              // Don't delete
+            virtual ~ClassFactory() {}                      // Don't delete
 
             static T* createNewObject();
Index: /code/branches/FICN/src/orxonox/core/ConfigValueContainer.cc
===================================================================
--- /code/branches/FICN/src/orxonox/core/ConfigValueContainer.cc	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/ConfigValueContainer.cc	(revision 704)
@@ -647,9 +647,10 @@
 
     /**
-        @brief Sets the value of the variable back to the default value.
+        @brief Sets the value of the variable back to the default value and resets the config-file entry.
     */
     void ConfigValueContainer::resetConfigValue()
     {
-        parseSting(this->defvalueString_);
+        this->parseSting(this->defvalueString_);
+        this->resetConfigFileEntry();
     }
 
@@ -854,6 +855,4 @@
     void ConfigValueContainer::readConfigFile(const std::string& filename)
     {
-        ConfigValueContainer::finishedReadingConfigFile(true);
-
         // This creates the file if it's not existing
         std::ofstream createFile;
@@ -865,4 +864,10 @@
         file.open(filename.c_str(), std::fstream::in);
 
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open config-file " << filename << " to read the config values!" << std::endl;
+            return;
+        }
+
         char line[1024];
 
@@ -887,4 +892,6 @@
 
         file.close();
+
+        ConfigValueContainer::finishedReadingConfigFile(true);
     }
 
@@ -903,7 +910,13 @@
         file.open(filename.c_str(), std::fstream::out);
 
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open config-file " << filename << " to write the config values!" << std::endl;
+            return;
+        }
+
         // Iterate through the list an write the lines into the file
         std::list<std::string>::iterator it;
-        for(it = ConfigValueContainer::getConfigFileLines().begin(); it != ConfigValueContainer::getConfigFileLines().end(); ++it)
+        for (it = ConfigValueContainer::getConfigFileLines().begin(); it != ConfigValueContainer::getConfigFileLines().end(); ++it)
         {
             file << (*it) << std::endl;
Index: /code/branches/FICN/src/orxonox/core/ConfigValueContainer.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/ConfigValueContainer.h	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/ConfigValueContainer.h	(revision 704)
@@ -135,4 +135,8 @@
             void resetConfigValue();
 
+            static std::string getStrippedLine(const std::string& line);
+            static bool isEmpty(const std::string& line);
+            static bool isComment(const std::string& line);
+
         private:
             bool parseSting(const std::string& input, int defvalue);
@@ -155,7 +159,4 @@
             std::string parseValueString(bool bStripped = true);
 
-            static std::string getStrippedLine(const std::string& line);
-            static bool isEmpty(const std::string& line);
-            static bool isComment(const std::string& line);
             static void readConfigFile(const std::string& filename);
             static void writeConfigFile(const std::string& filename);
Index: /code/branches/FICN/src/orxonox/core/CoreIncludes.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/CoreIncludes.h	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/CoreIncludes.h	(revision 704)
@@ -144,5 +144,5 @@
 
 /**
-    @brief Sets the variable back to the previously defined default-value.
+    @brief Sets the variable and the config-file entry back to the previously defined default-value.
     @param varname The name of the variable
 */
@@ -152,5 +152,5 @@
     { \
         container##varname##reset->resetConfigValue(); \
-        varname = container##varname->getValue(varname); \
+        varname = container##varname##reset->getValue(varname); \
     } \
     else \
Index: /code/branches/FICN/src/orxonox/core/DebugLevel.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/DebugLevel.h	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/DebugLevel.h	(revision 704)
@@ -53,5 +53,5 @@
             explicit DebugLevel(bool& bReturnSoftDebugLevel);
             DebugLevel(const DebugLevel& dl) {} // don't copy
-            ~DebugLevel() {}                    // don't delete
+            virtual ~DebugLevel() {}            // don't delete
 
             int softDebugLevel_;                            //!< The debug level
Index: /code/branches/FICN/src/orxonox/core/Language.cc
===================================================================
--- /code/branches/FICN/src/orxonox/core/Language.cc	(revision 704)
+++ /code/branches/FICN/src/orxonox/core/Language.cc	(revision 704)
@@ -0,0 +1,234 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include <fstream>
+
+#include "Language.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###      LanguageEntry      ###
+    // ###############################
+    LanguageEntry::LanguageEntry(const std::string& fallbackEntry)
+    {
+        RegisterRootObject(LanguageEntry);
+
+        this->fallbackEntry_ = fallbackEntry;
+        this->translatedEntry_ = fallbackEntry;
+    }
+
+    void LanguageEntry::setTranslation(const std::string& translation)
+    {
+        if (translation.compare("") != 0)
+            this->translatedEntry_ = translation;
+        else
+            this->translatedEntry_ = this->fallbackEntry_;
+    }
+
+    void LanguageEntry::setDefault(const std::string& fallbackEntry)
+    {
+        if (this->translatedEntry_.compare(this->fallbackEntry_) == 0)
+            this->translatedEntry_ = fallbackEntry;
+
+        this->fallbackEntry_ = fallbackEntry;
+    }
+
+    // ###############################
+    // ###        Language         ###
+    // ###############################
+    Language::Language()
+    {
+        RegisterRootObject(Language);
+        this->defaultLanguage_ = "default";
+        this->defaultTranslation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
+        this->readDefaultLanguageFile();
+
+        this->setConfigValues();
+    }
+
+    void Language::setConfigValues()
+    {
+        SetConfigValue(language_, this->defaultLanguage_);
+        this->readTranslatedLanguageFile();
+    }
+
+    Language& Language::getLanguage()
+    {
+        static Language theOnlyLanguageObject = Language();
+        return theOnlyLanguageObject;
+    }
+
+    void Language::createEntry(const LanguageEntryName& name, const std::string& entry)
+    {
+        if (!this->languageEntries_[name])
+        {
+            LanguageEntry* newEntry = new LanguageEntry(entry);
+            newEntry->setName(name);
+            this->languageEntries_[name] = newEntry;
+        }
+        else
+        {
+            COUT(2) << "Warning: Language entry " << name << " is duplicate in " << getFileName(this->defaultLanguage_) << "!" << std::endl;
+        }
+    }
+
+    void Language::addEntry(const LanguageEntryName& name, const std::string& entry)
+    {
+        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(name);
+        if (!it->second)
+            this->createEntry(name, entry);
+        else if (it->second->getDefault().compare(entry) == 0)
+            return;
+        else
+            it->second->setDefault(entry);
+
+        this->writeDefaultLanguageFile();
+    }
+
+    const std::string& Language::getTranslation(const LanguageEntryName& name) const
+    {
+        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(name);
+        if (it->second)
+            return it->second->getTranslation();
+        else
+        {
+            COUT(2) << "Error: Language entry \"" << name << "\" not found!" << std::endl;
+            return this->defaultTranslation_;
+        }
+    }
+
+    const std::string Language::getFileName(const std::string& language)
+    {
+        return std::string("translation_" + language + ".lang");
+    }
+
+    void Language::readDefaultLanguageFile()
+    {
+        COUT(4) << "Read default language file." << std::endl;
+
+        // This creates the file if it's not existing
+        std::ofstream createFile;
+        createFile.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::app);
+        createFile.close();
+
+        // Open the file
+        std::ifstream file;
+        file.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open file " << getFileName(this->defaultLanguage_) << " to read the default language entries!" << std::endl;
+            return;
+        }
+
+        char line[1024];
+
+        // Iterate through the file and create the LanguageEntries
+        while (file.good() && !file.eof())
+        {
+            file.getline(line, 1024);
+            std::string lineString = std::string(line);
+            if (lineString.compare("") != 0)
+            {
+                unsigned int pos = lineString.find('=');
+                if (pos < lineString.size() && lineString.size() >= 3)
+                    this->createEntry(lineString.substr(0, pos), lineString.substr(pos + 1));
+                else
+                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(this->defaultLanguage_) << std::endl;
+            }
+        }
+
+        file.close();
+    }
+
+    void Language::readTranslatedLanguageFile()
+    {
+        COUT(4) << "Read translated language file (" << this->language_ << ")." << std::endl;
+
+        // Open the file
+        std::ifstream file;
+        file.open(getFileName(this->language_).c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open file " << getFileName(this->language_) << " to read the translated language entries!" << std::endl;
+            ResetConfigValue(language_);
+            COUT(3) << "Info: Reset language to " << this->defaultLanguage_ << "." << std::endl;
+            return;
+        }
+
+        char line[1024];
+
+        // Iterate through the file and create the LanguageEntries
+        while (file.good() && !file.eof())
+        {
+            file.getline(line, 1024);
+            std::string lineString = std::string(line);
+            if (lineString.compare("") != 0)
+            {
+                unsigned int pos = lineString.find('=');
+                if (pos < lineString.size() && lineString.size() >= 3)
+                {
+                    std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(lineString.substr(0, pos));
+                    if (it->second)
+                        it->second->setTranslation(lineString.substr(pos + 1));
+                    else
+                        COUT(2) << "Warning: Unknown language entry \"" << lineString.substr(0, pos) << "\" in " << getFileName(this->language_) << std::endl;
+                }
+                else
+                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFileName(this->language_) << std::endl;
+            }
+        }
+
+        file.close();
+    }
+
+    void Language::writeDefaultLanguageFile() const
+    {
+        COUT(4) << "Write default language file." << std::endl;
+
+        // Open the file
+        std::ofstream file;
+        file.open(getFileName(this->defaultLanguage_).c_str(), std::fstream::out);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open file " << getFileName(this->defaultLanguage_) << " to write the default language entries!" << std::endl;
+            return;
+        }
+
+        // Iterate through the list an write the lines into the file
+        for (Iterator<LanguageEntry> it = ObjectList<LanguageEntry>::start(); it; ++it)
+        {
+            file << it->getName() << "=" << it->getDefault() << std::endl;
+        }
+
+        file.close();
+    }
+}
Index: /code/branches/FICN/src/orxonox/core/Language.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/Language.h	(revision 704)
+++ /code/branches/FICN/src/orxonox/core/Language.h	(revision 704)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Language_H__
+#define _Language_H__
+
+#include <string>
+#include <map>
+
+#include "CorePrereqs.h"
+
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    typedef std::string LanguageEntryName;
+
+    class _CoreExport LanguageEntry : public OrxonoxClass
+    {
+        public:
+            explicit LanguageEntry(const std::string& fallbackEntry);
+            void setTranslation(const std::string& translation);
+            void setDefault(const std::string& fallbackEntry);
+
+            inline const std::string& getTranslation()
+                { return this->translatedEntry_; }
+
+            inline const std::string& getDefault()
+                { return this->fallbackEntry_; }
+
+        private:
+            std::string fallbackEntry_;
+            std::string translatedEntry_;
+    };
+
+    class _CoreExport Language : public OrxonoxClass
+    {
+        public:
+            static Language& getLanguage();
+            void setConfigValues();
+            void addEntry(const LanguageEntryName& name, const std::string& entry);
+            const std::string& getTranslation(const LanguageEntryName& name) const;
+
+        private:
+            Language();
+            Language(const Language& language) {}   // don't copy
+            virtual ~Language() {};                 // don't delete
+
+            void readDefaultLanguageFile();
+            void readTranslatedLanguageFile();
+            void writeDefaultLanguageFile() const;
+            static const std::string getFileName(const std::string& language);
+            void createEntry(const LanguageEntryName& name, const std::string& entry);
+
+            std::string language_;
+            std::string defaultLanguage_;
+            std::string defaultTranslation_;
+            std::map<std::string, LanguageEntry*> languageEntries_;
+    };
+}
+
+#endif /* _Language_H__ */
Index: /code/branches/FICN/src/orxonox/core/MetaObjectList.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/MetaObjectList.h	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/MetaObjectList.h	(revision 704)
@@ -65,5 +65,5 @@
         public:
             MetaObjectListElement(ObjectList<T>* list, ObjectListElement<T>* element);
-            ~MetaObjectListElement();
+            virtual ~MetaObjectListElement();
 
             ObjectListElement<T>* element_;         //!< The list element, containing the object
Index: /code/branches/FICN/src/orxonox/core/OutputHandler.h
===================================================================
--- /code/branches/FICN/src/orxonox/core/OutputHandler.h	(revision 703)
+++ /code/branches/FICN/src/orxonox/core/OutputHandler.h	(revision 704)
@@ -110,5 +110,5 @@
             explicit OutputHandler(const std::string& logfilename);
             OutputHandler(const OutputHandler& oh) {}; // don't copy
-            ~OutputHandler();
+            virtual ~OutputHandler();
             std::ofstream logfile_;     //!< The logfile where the output is logged
             std::string logfilename_;   //!< The name of the logfile
