Index: code/trunk/src/libraries/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/CMakeLists.txt	(revision 5774)
+++ code/trunk/src/libraries/CMakeLists.txt	(revision 5781)
@@ -26,3 +26,5 @@
 
 ADD_SUBDIRECTORY(core)
+ADD_SUBDIRECTORY(network)
+ADD_SUBDIRECTORY(tools)
 ADD_SUBDIRECTORY(util)
Index: code/trunk/src/libraries/core/ArgumentCompleter.h
===================================================================
--- code/trunk/src/libraries/core/ArgumentCompleter.h	(revision 5781)
+++ code/trunk/src/libraries/core/ArgumentCompleter.h	(revision 5781)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArgumentCompleter_H__
+#define _ArgumentCompleter_H__
+
+#include "CorePrereqs.h"
+#include "ArgumentCompletionListElement.h"
+
+namespace orxonox
+{
+    class _CoreExport ArgumentCompleter
+    {
+        public:
+            ArgumentCompleter(ArgumentCompletionList (*function) (void)) : paramCount_(0), function_0_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1)) : paramCount_(1), function_1_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2)) : paramCount_(2), function_2_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3)) : paramCount_(3), function_3_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4)) : paramCount_(4), function_4_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5)) : paramCount_(5), function_5_(function) {}
+
+            ArgumentCompletionList operator()(const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "")
+            {
+                switch (this->paramCount_)
+                {
+                    case 0:
+                        return (*this->function_0_)();
+                    case 1:
+                        return (*this->function_1_)(param1);
+                    case 2:
+                        return (*this->function_2_)(param1, param2);
+                    case 3:
+                        return (*this->function_3_)(param1, param2, param3);
+                    case 4:
+                        return (*this->function_4_)(param1, param2, param3, param4);
+                    case 5:
+                        return (*this->function_5_)(param1, param2, param3, param4, param5);
+                    default:
+                        return ArgumentCompletionList();
+                }
+            }
+
+        private:
+            unsigned char paramCount_;
+            ArgumentCompletionList (*function_0_) (void);
+            ArgumentCompletionList (*function_1_) (const std::string& param1);
+            ArgumentCompletionList (*function_2_) (const std::string& param1, const std::string& param2);
+            ArgumentCompletionList (*function_3_) (const std::string& param1, const std::string& param2, const std::string& param3);
+            ArgumentCompletionList (*function_4_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4);
+            ArgumentCompletionList (*function_5_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5);
+    };
+}
+
+#endif /* _ArgumentCompleter_H__ */
Index: code/trunk/src/libraries/core/ArgumentCompletionFunctions.cc
===================================================================
--- code/trunk/src/libraries/core/ArgumentCompletionFunctions.cc	(revision 5781)
+++ code/trunk/src/libraries/core/ArgumentCompletionFunctions.cc	(revision 5781)
@@ -0,0 +1,150 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ArgumentCompletionFunctions.h"
+
+#include <map>
+#include <boost/version.hpp>
+#include <boost/filesystem.hpp>
+
+#include "util/Convert.h"
+#include "util/StringUtils.h"
+#include "Identifier.h"
+#include "ConfigValueContainer.h"
+#include "TclThreadManager.h"
+
+// Boost 1.36 has some issues with deprecated functions that have been omitted
+#if (BOOST_VERSION == 103600)
+#  define BOOST_LEAF_FUNCTION filename
+#else
+#  define BOOST_LEAF_FUNCTION leaf
+#endif
+
+namespace orxonox
+{
+    namespace autocompletion
+    {
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(fallback)()
+        {
+            return ArgumentCompletionList();
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment)
+        {
+            ArgumentCompletionList dirlist;
+            ArgumentCompletionList filelist;
+
+            try
+            {
+                boost::filesystem::path input(fragment);
+                boost::filesystem::path startdirectory(input.branch_path());
+
+                if (!boost::filesystem::exists(startdirectory))
+                {
+                    startdirectory = ".";
+                }
+#ifdef ORXONOX_PLATFORM_WINDOWS
+                else
+                {
+                    std::string dir = startdirectory.string();
+                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
+                        startdirectory = dir + '/';
+                }
+#endif
+
+                boost::filesystem::directory_iterator file(startdirectory);
+                boost::filesystem::directory_iterator end;
+
+                while (file != end)
+                {
+                    if (boost::filesystem::is_directory(*file))
+                        dirlist.push_back(ArgumentCompletionListElement((*file).string() + '/', getLowercase((*file).string()) + '/', (*file).BOOST_LEAF_FUNCTION() + '/'));
+                    else
+                        filelist.push_back(ArgumentCompletionListElement((*file).string(), getLowercase((*file).string()), (*file).BOOST_LEAF_FUNCTION()));
+                    ++file;
+                }
+            }
+            catch (...) {}
+
+            filelist.insert(filelist.begin(), dirlist.begin(), dirlist.end());
+            return filelist;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(configvalueclasses)()
+        {
+            ArgumentCompletionList classlist;
+
+            for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getIdentifierMapBegin(); it != Identifier::getIdentifierMapEnd(); ++it)
+                if ((*it).second->hasConfigValues())
+                    classlist.push_back(ArgumentCompletionListElement((*it).second->getName(), getLowercase((*it).first)));
+
+            return classlist;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(configvalues)(const std::string& fragment, const std::string& classname)
+        {
+            ArgumentCompletionList configvalues;
+            std::map<std::string, Identifier*>::const_iterator identifier = Identifier::getIdentifierMap().find(classname);
+
+            if (identifier != Identifier::getIdentifierMapEnd() && (*identifier).second->hasConfigValues())
+            {
+                for (std::map<std::string, ConfigValueContainer*>::const_iterator it = (*identifier).second->getConfigValueMapBegin(); it != (*identifier).second->getConfigValueMapEnd(); ++it)
+                    configvalues.push_back(ArgumentCompletionListElement((*it).second->getName(), getLowercase((*it).first)));
+            }
+
+            return configvalues;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(configvalue)(const std::string& fragment, const std::string& varname, const std::string& classname)
+        {
+            ArgumentCompletionList oldvalue;
+            std::map<std::string, Identifier*>::const_iterator identifier = Identifier::getLowercaseIdentifierMap().find(getLowercase(classname));
+            if (identifier != Identifier::getLowercaseIdentifierMapEnd())
+            {
+                std::map<std::string, ConfigValueContainer*>::const_iterator variable = (*identifier).second->getLowercaseConfigValueMap().find(getLowercase(varname));
+                if (variable != (*identifier).second->getLowercaseConfigValueMapEnd())
+                {
+                    std::string valuestring = (*variable).second->toString();
+                    oldvalue.push_back(ArgumentCompletionListElement(valuestring, getLowercase(valuestring), "Old value: " + valuestring));
+                }
+            }
+            return oldvalue;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)()
+        {
+            std::list<unsigned int> threadnumbers = TclThreadManager::getInstance().getThreadList();
+            ArgumentCompletionList threads;
+
+            for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it)
+                threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it)));
+
+            return threads;
+        }
+    }
+}
Index: code/trunk/src/libraries/core/ArgumentCompletionFunctions.h
===================================================================
--- code/trunk/src/libraries/core/ArgumentCompletionFunctions.h	(revision 5781)
+++ code/trunk/src/libraries/core/ArgumentCompletionFunctions.h	(revision 5781)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArgumentCompletionFunctions_H__
+#define _ArgumentCompletionFunctions_H__
+
+#include "CorePrereqs.h"
+#include "ArgumentCompleter.h"
+
+
+#define ARGUMENT_COMPLETION_FUNCTION_DECLARATION(functionname) \
+    _CoreExport ArgumentCompleter* functionname(); \
+    _CoreExport ArgumentCompletionList acf_##functionname
+
+#define ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(functionname) \
+    ArgumentCompleter* functionname() \
+    { \
+        static ArgumentCompleter completer = ArgumentCompleter(&acf_##functionname); \
+        return &completer; \
+    } \
+    \
+    ArgumentCompletionList acf_##functionname
+
+
+namespace orxonox
+{
+    namespace autocompletion
+    {
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(fallback)();
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(files)(const std::string& fragment);
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(configvalueclasses)();
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(configvalues)(const std::string& fragment, const std::string& classname);
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(configvalue)(const std::string& fragment, const std::string& varname, const std::string& classname);
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(tclthreads)();
+    }
+}
+
+#endif /* _ArgumentCompletionFunctions_H__ */
Index: code/trunk/src/libraries/core/ArgumentCompletionListElement.h
===================================================================
--- code/trunk/src/libraries/core/ArgumentCompletionListElement.h	(revision 5781)
+++ code/trunk/src/libraries/core/ArgumentCompletionListElement.h	(revision 5781)
@@ -0,0 +1,73 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArgumentCompletionListElement_H__
+#define _ArgumentCompletionListElement_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+#include <string>
+
+namespace orxonox
+{
+    const int ACL_MODE_NORMAL    = 1;
+    const int ACL_MODE_LOWERCASE = 2;
+    const int ACL_MODE_DISPLAY   = 4;
+
+    typedef std::list<ArgumentCompletionListElement> ArgumentCompletionList;
+
+    class _CoreExport ArgumentCompletionListElement
+    {
+        public:
+            ArgumentCompletionListElement(const std::string& normalcase) : mode_(ACL_MODE_NORMAL), normalCase_(normalcase) {}
+            ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase) : mode_(ACL_MODE_NORMAL | ACL_MODE_LOWERCASE), normalCase_(normalcase), lowerCase_(lowercase) {}
+            ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase, const std::string& display) : mode_(ACL_MODE_NORMAL | ACL_MODE_LOWERCASE | ACL_MODE_DISPLAY), normalCase_(normalcase), lowerCase_(lowercase), display_(display) {}
+
+            const std::string& getString() const
+                { return this->normalCase_; }
+            const std::string& getComparable() const
+                { if (this->mode_ & ACL_MODE_LOWERCASE) { return this->lowerCase_; } else { return this->normalCase_; } }
+            const std::string& getDisplay() const
+                { if (this->mode_ & ACL_MODE_DISPLAY) { return this->display_; } else { return this->normalCase_; } }
+
+            bool lowercaseComparison() const
+                { return (this->mode_ & ACL_MODE_LOWERCASE); }
+
+            bool operator<(const ArgumentCompletionListElement& other) const
+                { return (this->getComparable() < other.getComparable()); }
+
+        private:
+            unsigned char mode_;
+            std::string normalCase_;
+            std::string lowerCase_;
+            std::string display_;
+    };
+}
+
+#endif /* _ArgumentCompletionListElement_H__ */
Index: code/trunk/src/libraries/core/BaseObject.cc
===================================================================
--- code/trunk/src/libraries/core/BaseObject.cc	(revision 5774)
+++ code/trunk/src/libraries/core/BaseObject.cc	(revision 5781)
@@ -33,5 +33,17 @@
 
 #include "BaseObject.h"
+
+#include <tinyxml/tinyxml.h>
+
+#include "util/StringUtils.h"
 #include "CoreIncludes.h"
+#include "Event.h"
+#include "EventIncludes.h"
+#include "Functor.h"
+#include "Iterator.h"
+#include "Template.h"
+#include "XMLFile.h"
+#include "XMLNameListener.h"
+#include "XMLPort.h"
 
 namespace orxonox
@@ -47,4 +59,29 @@
 
         this->bInitialized_ = true;
+
+        this->bActive_ = true;
+        this->bVisible_ = true;
+        this->oldGametype_ = 0;
+
+        this->lastLoadedXMLElement_ = 0;
+
+        this->functorSetMainState_ = 0;
+        this->functorGetMainState_ = 0;
+
+        this->setCreator(creator);
+        if (this->creator_)
+        {
+            this->setFile(this->creator_->getFile());
+            this->setNamespace(this->creator_->getNamespace());
+            this->setScene(this->creator_->getScene());
+            this->setGametype(this->creator_->getGametype());
+        }
+        else
+        {
+            this->file_ = 0;
+            this->namespace_ = 0;
+            this->scene_ = 0;
+            this->gametype_ = 0;
+        }
     }
 
@@ -56,5 +93,250 @@
         if (this->isInitialized())
         {
-        }
+            for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
+                (*it)->unregisterEventListener(this);
+
+            for (std::map<BaseObject*, std::string>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
+                it->first->removeEvent(this);
+
+            if (this->functorSetMainState_)
+                delete this->functorSetMainState_;
+            if (this->functorGetMainState_)
+                delete this->functorGetMainState_;
+        }
+    }
+
+    /**
+        @brief XML loading and saving.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+        @return The XML-element
+    */
+    void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortParam(BaseObject, "name", setXMLName, getName, xmlelement, mode);
+        XMLPortParam(BaseObject, "visible", setVisible, isVisible, xmlelement, mode);
+        XMLPortParam(BaseObject, "active", setActive, isActive, xmlelement, mode);
+        XMLPortParam(BaseObject, "mainstate", setMainStateName, getMainStateName, xmlelement, mode);
+
+        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
+
+        Element* events = xmlelement.FirstChildElement("events", false);
+
+        if (events)
+        {
+            std::list<std::string> eventnames;
+
+            if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
+            {
+                for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++)
+                    eventnames.push_back(child->Value());
+            }
+            else if (mode == XMLPort::SaveObject)
+            {
+                for (std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->getIdentifier()->getXMLPortEventMapBegin(); it != this->getIdentifier()->getXMLPortEventMapEnd(); ++it)
+                    eventnames.push_back(it->first);
+            }
+
+            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
+            {
+                std::string sectionname = (*it);
+                ExecutorMember<BaseObject>* loadexecutor = createExecutor(createFunctor(&BaseObject::addEvent), std::string( "BaseObject" ) + "::" + "addEvent");
+                ExecutorMember<BaseObject>* saveexecutor = createExecutor(createFunctor(&BaseObject::getEvent), std::string( "BaseObject" ) + "::" + "getEvent");
+                loadexecutor->setDefaultValue(1, sectionname);
+
+                XMLPortClassObjectContainer<BaseObject, BaseObject>* container = 0;
+                container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(this->getIdentifier()->getXMLPortEventContainer(sectionname));
+                if (!container)
+                {
+                    container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(sectionname, this->getIdentifier(), loadexecutor, saveexecutor, false, true);
+                    this->getIdentifier()->addXMLPortEventContainer(sectionname, container);
+                }
+                container->port(this, *events, mode);
+            }
+        }
+    }
+
+    /**
+        @brief Loads the name of the object through XML and calls all XMLNameListener.
+        @param name The name of the object
+    */
+    void BaseObject::setXMLName(const std::string& name)
+    {
+        this->setName(name);
+
+        for (ObjectList<XMLNameListener>::iterator it = ObjectList<XMLNameListener>::begin(); it != ObjectList<XMLNameListener>::end(); ++it)
+            it->loadedNewXMLName(this);
+    }
+
+    /**
+        @brief Returns the levelfile that loaded this object.
+        @return The levelfile
+    */
+    const std::string& BaseObject::getFilename() const
+    {
+        if (this->file_)
+            return this->file_->getFilename();
+        else
+            return BLANKSTRING;
+    }
+
+    /**
+        @brief Adds a Template to the object.
+        @param name The name of the Template
+    */
+    void BaseObject::addTemplate(const std::string& name)
+    {
+        Template* temp = Template::getTemplate(name);
+        if (temp)
+            this->addTemplate(temp);
+        else
+            COUT(1) << "Error: \"" << name << "\" is not a valid Template name (in class: " << this->getIdentifier()->getName() << ", name: " << this->getName() << ")." << std::endl;
+    }
+
+    /**
+        @brief Adds a Template to the object.
+        @param temp The Template
+    */
+    void BaseObject::addTemplate(Template* temp)
+    {
+        this->templates_.insert(temp);
+        temp->applyOn(this);
+    }
+
+    /**
+        @brief Returns the Template with the given index.
+        @param index The index
+    */
+    Template* BaseObject::getTemplate(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::set<Template*>::const_iterator it = this->templates_.begin(); it != this->templates_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            i++;
+        }
+        return 0;
+    }
+
+    void BaseObject::addEvent(BaseObject* event, const std::string& sectionname)
+    {
+        event->registerEventListener(this, sectionname);
+        this->events_.push_back(event);
+    }
+
+    void BaseObject::removeEvent(BaseObject* event)
+    {
+        this->events_.remove(event);
+    }
+
+    BaseObject* BaseObject::getEvent(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+
+    void BaseObject::addEventContainer(const std::string& sectionname, EventContainer* container)
+    {
+        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
+        if (it != this->eventContainers_.end())
+        {
+            COUT(2) << "Warning: Overwriting EventContainer in class " << this->getIdentifier()->getName() << "." << std::endl;
+            delete (it->second);
+        }
+
+        this->eventContainers_[sectionname] = container;
+    }
+
+    EventContainer* BaseObject::getEventContainer(const std::string& sectionname) const
+    {
+        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
+        if (it != this->eventContainers_.end())
+            return ((*it).second);
+        else
+            return 0;
+    }
+
+    void BaseObject::fireEvent()
+    {
+        this->fireEvent(true);
+        this->fireEvent(false);
+    }
+
+    void BaseObject::fireEvent(bool activate)
+    {
+        this->fireEvent(activate, this);
+    }
+
+    void BaseObject::fireEvent(bool activate, BaseObject* originator)
+    {
+        Event event(activate, originator);
+
+        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
+        {
+            event.sectionname_ = it->second;
+            it->first->processEvent(event);
+        }
+    }
+
+    void BaseObject::fireEvent(Event& event)
+    {
+        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
+            it->first->processEvent(event);
+    }
+
+    void BaseObject::processEvent(Event& event)
+    {
+        ORXONOX_SET_EVENT(BaseObject, "activity", setActive, event);
+        ORXONOX_SET_EVENT(BaseObject, "visibility", setVisible, event);
+    }
+
+    void BaseObject::setMainStateName(const std::string& name)
+    {
+        if (this->mainStateName_ != name)
+        {
+            this->mainStateName_ = name;
+            if (this->functorSetMainState_)
+                delete this->functorSetMainState_;
+            if (this->functorGetMainState_)
+                delete this->functorGetMainState_;
+            this->changedMainState();
+            if (!this->functorSetMainState_)
+                COUT(2) << "Warning: \"" << name << "\" is not a valid MainState." << std::endl;
+        }
+    }
+
+    void BaseObject::setMainState(bool state)
+    {
+        if (this->functorSetMainState_)
+            (*this->functorSetMainState_)(state);
+        else
+            COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
+    }
+
+    bool BaseObject::getMainState() const
+    {
+        if (this->functorGetMainState_)
+        {
+            (*this->functorGetMainState_)();
+            return this->functorGetMainState_->getReturnvalue();
+        }
+        else
+        {
+            COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
+            return false;
+        }
+    }
+
+    void BaseObject::changedMainState()
+    {
+        SetMainState(BaseObject, "activity",   setActive,  isActive);
+        SetMainState(BaseObject, "visibility", setVisible, isVisible);
     }
 }
Index: code/trunk/src/libraries/core/BaseObject.h
===================================================================
--- code/trunk/src/libraries/core/BaseObject.h	(revision 5774)
+++ code/trunk/src/libraries/core/BaseObject.h	(revision 5781)
@@ -37,26 +37,177 @@
 #define _BaseObject_H__
 
+#define SetMainState(classname, statename, setfunction, getfunction) \
+    if (this->getMainStateName() == statename) \
+    { \
+        this->functorSetMainState_ = createFunctor(&classname::setfunction)->setObject(this); \
+        this->functorGetMainState_ = createFunctor(&classname::getfunction)->setObject(this); \
+    }
+
+
 #include "CorePrereqs.h"
+
+#include <map>
+#include <list>
+
+#include "util/mbool.h"
 #include "OrxonoxClass.h"
+#include "Super.h"
 
 namespace orxonox
 {
+    class Scene;
+    class Gametype;
+
     //! The BaseObject is the parent of all classes representing an instance in the game.
     class _CoreExport BaseObject : virtual public OrxonoxClass
     {
+        template <class T> friend class XMLPortClassParamContainer;
+
         public:
             BaseObject(BaseObject* creator);
             virtual ~BaseObject();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
 
             /** @brief Returns if the object was initialized (passed the object registration). @return True was the object is initialized */
             inline bool isInitialized() const { return this->bInitialized_; }
 
+            /** @brief Sets the name of the object. @param name The name */
+            inline void setName(const std::string& name) { this->oldName_ = this->name_; this->name_ = name; this->changedName(); }
+            /** @brief Returns the name of the object. */
+            inline const std::string& getName() const { return this->name_; }
+            /** @brief Returns the old name of the object. */
+            inline const std::string& getOldName() const { return this->oldName_; }
+            /** @brief This function gets called if the name of the object changes. */
+            virtual void changedName() {}
+
+            /** @brief Sets the state of the objects activity. @param bActive True = active */
+            inline void setActive(bool bActive)
+            {
+                if (this->bActive_ != bActive)
+                {
+                    this->bActive_ = bActive;
+                    this->changedActivity();
+                }
+            }
+            /** @brief Returns the state of the objects activity. @return The state of the activity */
+            inline const mbool& isActive() const { return this->bActive_; }
+            /** @brief This function gets called if the activity of the object changes. */
+            virtual void changedActivity() {}
+
+            /** @brief Sets the state of the objects visibility. @param bVisible True = visible */
+            inline void setVisible(bool bVisible)
+            {
+                if (this->bVisible_ != bVisible)
+                {
+                    this->bVisible_ = bVisible;
+                    this->changedVisibility();
+                }
+            }
+            /** @brief Returns the state of the objects visibility. @return The state of the visibility */
+            inline const mbool& isVisible() const { return this->bVisible_; }
+            /** @brief This function gets called if the visibility of the object changes. */
+            virtual void changedVisibility() {}
+
+            void setMainState(bool state);
+            bool getMainState() const;
+
+            void setMainStateName(const std::string& name);
+            inline const std::string& getMainStateName() const { return this->mainStateName_; }
+            virtual void changedMainState();
+
+            /** @brief Sets a pointer to the xml file that loaded this object. @param file The pointer to the XMLFile */
+            inline void setFile(const XMLFile* file) { this->file_ = file; }
+            /** @brief Returns a pointer to the XMLFile that loaded this object. @return The XMLFile */
+            inline const XMLFile* getFile() const { return this->file_; }
+            const std::string& getFilename() const;
+
+            void addTemplate(const std::string& name);
+            void addTemplate(Template* temp);
+            /** @brief Returns the set of all aplied templates. */
+            inline const std::set<Template*>& getTemplates() const
+                { return this->templates_; }
+
+            virtual inline void setNamespace(Namespace* ns) { this->namespace_ = ns; }
+            inline Namespace* getNamespace() const { return this->namespace_; }
+
             inline void setCreator(BaseObject* creator) { this->creator_ = creator; }
             inline BaseObject* getCreator() const { return this->creator_; }
 
+            inline void setScene(Scene* scene) { this->scene_ = scene; }
+            inline Scene* getScene() const { return this->scene_; }
+
+            inline void setGametype(Gametype* gametype)
+            {
+                if (gametype != this->gametype_)
+                {
+                    this->oldGametype_ = this->gametype_;
+                    this->gametype_ = gametype;
+                    this->changedGametype();
+                }
+            }
+            inline Gametype* getGametype() const { return this->gametype_; }
+            inline Gametype* getOldGametype() const { return this->oldGametype_; }
+            virtual void changedGametype() {}
+
+            void fireEvent();
+            void fireEvent(bool activate);
+            void fireEvent(bool activate, BaseObject* originator);
+            void fireEvent(Event& event);
+
+            virtual void processEvent(Event& event);
+
+            inline void registerEventListener(BaseObject* object, const std::string& sectionname)
+                { this->eventListeners_[object] = sectionname; }
+            inline void unregisterEventListener(BaseObject* object)
+                { this->eventListeners_.erase(object); }
+
+            void addEvent(BaseObject* event, const std::string& sectionname);
+            void removeEvent(BaseObject* event);
+            BaseObject* getEvent(unsigned int index) const;
+
+            void addEventContainer(const std::string& sectionname, EventContainer* container);
+            EventContainer* getEventContainer(const std::string& sectionname) const;
+
+            /** @brief Sets the indentation of the debug output in the Loader. @param indentation The indentation */
+            inline void setLoaderIndentation(const std::string& indentation) { this->loaderIndentation_ = indentation; }
+            /** @brief Returns the indentation of the debug output in the Loader. @return The indentation */
+            inline const std::string& getLoaderIndentation() const { return this->loaderIndentation_; }
+
+        protected:
+            std::string name_;                                 //!< The name of the object
+            std::string oldName_;                              //!< The old name of the object
+            mbool       bActive_;                              //!< True = the object is active
+            mbool       bVisible_;                             //!< True = the object is visible
+            std::string mainStateName_;
+            Functor*    functorSetMainState_;
+            Functor*    functorGetMainState_;
+
         private:
+            void setXMLName(const std::string& name);
+            Template* getTemplate(unsigned int index) const;
+
             bool                   bInitialized_;              //!< True if the object was initialized (passed the object registration)
+            const XMLFile*         file_;                      //!< The XMLFile that loaded this object
+            Element*               lastLoadedXMLElement_;      //!< Non 0 if the TinyXML attributes have already been copied to our own lowercase map
+            std::map<std::string, std::string> xmlAttributes_; //!< Lowercase XML attributes
+            std::string            loaderIndentation_;         //!< Indentation of the debug output in the Loader
+            Namespace*             namespace_;
             BaseObject*            creator_;
+            Scene*                 scene_;
+            Gametype*              gametype_;
+            Gametype*              oldGametype_;
+            std::set<Template*>    templates_;
+            std::map<BaseObject*,  std::string> eventListeners_;
+            std::list<BaseObject*> events_;
+            std::map<std::string, EventContainer*> eventContainers_;
     };
+
+    SUPER_FUNCTION(0, BaseObject, XMLPort, false);
+    SUPER_FUNCTION(2, BaseObject, changedActivity, false);
+    SUPER_FUNCTION(3, BaseObject, changedVisibility, false);
+    SUPER_FUNCTION(4, BaseObject, processEvent, false);
+    SUPER_FUNCTION(6, BaseObject, changedMainState, false);
+    SUPER_FUNCTION(9, BaseObject, changedName, false);
+    SUPER_FUNCTION(10, BaseObject, changedGametype, false);
 }
 
Index: code/trunk/src/libraries/core/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/core/CMakeLists.txt	(revision 5774)
+++ code/trunk/src/libraries/core/CMakeLists.txt	(revision 5781)
@@ -25,13 +25,25 @@
   DynLib.cc
   DynLibManager.cc
+  Event.cc
   Game.cc
+  GameMode.cc
   GameState.cc
+  GraphicsManager.cc
+  GUIManager.cc
   Language.cc
   LuaState.cc
+  MemoryArchive.cc
   ObjectListBase.cc
   OrxonoxClass.cc
+  Resource.cc
+  WindowEventListener.cc
 
   # command
+  ArgumentCompletionFunctions.cc
+  CommandEvaluation.cc
+  CommandExecutor.cc
   CommandLine.cc
+  ConsoleCommand.cc
+  ConsoleCommandCompilation.cc
   Executor.cc
 
@@ -43,13 +55,29 @@
   # level
   BaseObject.cc
+  ClassTreeMask.cc
+  Loader.cc
+  Namespace.cc
+  NamespaceNode.cc
+  Template.cc
+  XMLPort.cc
+  XMLNameListener.cc
 
+  # shell
+  IRC.cc
+  Shell.cc
+  TclBind.cc
+  TclThreadManager.cc
+  
   # multithreading
   Thread.cc
   ThreadPool.cc
 )
+ADD_SUBDIRECTORY(input)
 
 ORXONOX_ADD_LIBRARY(core
   FIND_HEADER_FILES
   TOLUA_FILES
+    CommandExecutor.h
+    Loader.h
     LuaState.h
   DEFINE_SYMBOL
@@ -63,5 +91,11 @@
     ${Boost_THREAD_LIBRARY}
     ${Boost_DATE_TIME_LIBRARY} # Thread dependency
+    ${CEGUI_LIBRARY}
+    ${CEGUILUA_LIBRARY}
     ${LUA_LIBRARIES}
+    cpptcl_orxonox
+    ogreceguirenderer_orxonox
+    ois_orxonox
+    tinyxml++_orxonox
     tolua++_orxonox
     util
Index: code/trunk/src/libraries/core/ClassFactory.h
===================================================================
--- code/trunk/src/libraries/core/ClassFactory.h	(revision 5774)
+++ code/trunk/src/libraries/core/ClassFactory.h	(revision 5781)
@@ -55,5 +55,5 @@
     {
         public:
-            static bool create(const std::string& name);
+            static bool create(const std::string& name, bool bLoadable = true);
             BaseObject* fabricate(BaseObject* creator);
 
@@ -73,8 +73,9 @@
     */
     template <class T>
-    bool ClassFactory<T>::create(const std::string& name)
+    bool ClassFactory<T>::create(const std::string& name, bool bLoadable)
     {
         COUT(4) << "*** ClassFactory: Create entry for " << name << " in Factory." << std::endl;
         ClassIdentifier<T>::getIdentifier(name)->addFactory(new ClassFactory<T>);
+        ClassIdentifier<T>::getIdentifier()->setLoadable(bLoadable);
         Factory::add(name, ClassIdentifier<T>::getIdentifier());
 
Index: code/trunk/src/libraries/core/ClassTreeMask.cc
===================================================================
--- code/trunk/src/libraries/core/ClassTreeMask.cc	(revision 5781)
+++ code/trunk/src/libraries/core/ClassTreeMask.cc	(revision 5781)
@@ -0,0 +1,963 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
+*/
+
+#include "ClassTreeMask.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###    ClassTreeMaskNode    ###
+    // ###############################
+    /**
+        @brief Constructor: Creates the node, sets the subclass and the rule.
+        @param subclass The subclass the rule refers to
+        @param bIncluded The rule: included (true) or excluded (false)
+    */
+    ClassTreeMaskNode::ClassTreeMaskNode(const Identifier* subclass, bool bIncluded)
+    {
+        this->subclass_ = subclass;
+        this->bIncluded_ = bIncluded;
+    }
+
+    /**
+        @brief Destructor: Deletes all subnodes.
+    */
+    ClassTreeMaskNode::~ClassTreeMaskNode()
+    {
+        // Go through the list of all subnodes and delete them
+        this->deleteAllSubnodes();
+    }
+
+    /**
+        @brief Sets the rule for the node to "included".
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMaskNode::include(bool overwrite)
+    {
+        this->setIncluded(true, overwrite);
+    }
+
+    /**
+        @brief Sets the rule for the node to "excluded".
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMaskNode::exclude(bool overwrite)
+    {
+        this->setIncluded(false, overwrite);
+    }
+
+    /**
+        @brief Sets the rule for the node to a given value and erases all following rules.
+        @param bIncluded The rule: included (true) or excluded (false)
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMaskNode::setIncluded(bool bIncluded, bool overwrite)
+    {
+        if (overwrite)
+            this->deleteAllSubnodes();
+
+        this->bIncluded_ = bIncluded;
+    }
+
+    /**
+        @brief Adds a new subnode to the list of subnodes.
+        @param subnode The new subnode
+    */
+    void ClassTreeMaskNode::addSubnode(ClassTreeMaskNode* subnode)
+    {
+        this->subnodes_.insert(this->subnodes_.end(), subnode);
+    }
+
+    /**
+        @brief Deletes all subnodes of this node.
+    */
+    void ClassTreeMaskNode::deleteAllSubnodes()
+    {
+        // Go through the list of all subnodes and delete them
+        for (std::list<ClassTreeMaskNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); )
+            delete (*(it++));
+
+        // Clear the list
+        this->subnodes_.clear();
+    }
+
+
+    // ###############################
+    // ###  ClassTreeMaskIterator  ###
+    // ###############################
+    /**
+        @brief Constructor: Initializes the iterator by creating a helper-list with the root-node and putting it to the stack.
+        @param node The root-node
+    */
+    ClassTreeMaskIterator::ClassTreeMaskIterator(ClassTreeMaskNode* node)
+    {
+        // Create a list and put the root-note into it
+        std::list<ClassTreeMaskNode*>::iterator it = this->rootlist_.insert(this->rootlist_.end(), node);
+
+        // Put the iterator to the only element of the list and the corresponding end()-iterator on the stack
+        this->nodes_.push(std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator>(it, this->rootlist_.end()));
+    }
+
+    /**
+        @brief Destructor: Does nothing.
+    */
+    ClassTreeMaskIterator::~ClassTreeMaskIterator()
+    {
+    }
+
+    /**
+        @brief Iterates through the rule-tree.
+        @return A reference to the iterator itself
+    */
+    const ClassTreeMaskIterator& ClassTreeMaskIterator::operator++()
+    {
+        // Check if the actual node has subnodes
+        if ((*this->nodes_.top().first)->subnodes_.begin() != (*this->nodes_.top().first)->subnodes_.end())
+        {
+            // Yes it has: Push an iterator, pointing at the first subnode, on the stack
+            this->nodes_.push(std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator>((*this->nodes_.top().first)->subnodes_.begin(), (*this->nodes_.top().first)->subnodes_.end()));
+        }
+        else
+        {
+            // No subnodes, meaning we reached a leaf: Go to the next node
+            do
+            {
+                // Iterate one step in the current list
+                ++this->nodes_.top().first;
+
+                // Check if we reached the end of the list (the second item in the stored pair always represents the end)
+                if (this->nodes_.top().first == this->nodes_.top().second)
+                {
+                    // Yes we've reached the end: Pop the list-iterator from the stack
+                    this->nodes_.pop();
+
+                    // Continue with the loop, meaning: Try to iterate through the previous list
+                    continue;
+                }
+
+                // If we reached this point, we aren't yet at the end of the list: Leave the loop
+                break;
+            } while (!this->nodes_.empty()); // Stop looping if the stack is empty, meaning: We've iterated to the end
+        }
+
+        // Finally return a reference to the iterator itself
+        return *this;
+    }
+
+    /**
+        @brief Returns a pointer to the ClassTreeMaskNode whereon the iterator points.
+        @return The pointer to the node
+    */
+    ClassTreeMaskNode* ClassTreeMaskIterator::operator*() const
+    {
+        return (*this->nodes_.top().first);
+    }
+
+    /**
+        @brief Returns a pointer to the ClassTreeMaskNode whereon the iterator points.
+        @return The pointer to the node
+    */
+    ClassTreeMaskNode* ClassTreeMaskIterator::operator->() const
+    {
+        return (*this->nodes_.top().first);
+    }
+
+    /**
+        @brief Returns true if the stack is empty, meaning we've reached the end of the tree.
+        @return True if we've reached the end of the tree
+    */
+    ClassTreeMaskIterator::operator bool() const
+    {
+        return (!this->nodes_.empty());
+    }
+
+    /**
+        @brief Compares the current node with the given one and returns true if they match.
+        @param compare The node to compare with
+        @return The result of the comparison (true if they match)
+    */
+    bool ClassTreeMaskIterator::operator==(ClassTreeMaskNode* compare) const
+    {
+        if (!this->nodes_.empty())
+            return ((*this->nodes_.top().first) == compare);
+        else
+            return (compare == 0);
+    }
+
+    /**
+        @brief Compares the current node with the given one and returns true if they don't match.
+        @param compare The node to compare with
+        @return The result of the comparison (true if they don't match)
+    */
+    bool ClassTreeMaskIterator::operator!=(ClassTreeMaskNode* compare) const
+    {
+        if (!this->nodes_.empty())
+            return ((*this->nodes_.top().first) != compare);
+        else
+            return (compare != 0);
+    }
+
+
+    // ###############################
+    // ###      ClassTreeMask      ###
+    // ###############################
+    /**
+        @brief Constructor: Adds the root-node of the tree with the first rule ("include everything").
+    */
+    ClassTreeMask::ClassTreeMask()
+    {
+        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
+    }
+
+    /**
+        @brief Copyconstructor: Adds the root-node of the tree with the first rule ("include everything") and adds all rules from the other mask.
+        @param other The other mask
+    */
+    ClassTreeMask::ClassTreeMask(const ClassTreeMask& other)
+    {
+        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+            this->add(it->getClass(), it->isIncluded(), false);
+    }
+
+    /**
+        @brief Destructor: Deletes the root node (which will delete all subnodes too).
+    */
+    ClassTreeMask::~ClassTreeMask()
+    {
+        delete this->root_;
+    }
+
+    /**
+        @brief Adds a new "include" rule for a given subclass to the mask.
+        @param subclass The subclass
+        @param overwrite True = overwrite previously added rules for inheriting classes
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::include(const Identifier* subclass, bool overwrite, bool clean)
+    {
+        this->add(subclass, true, overwrite, clean);
+    }
+
+    /**
+        @brief Adds a new "exclude" rule for a given subclass to the mask.
+        @param subclass The subclass
+        @param overwrite True = overwrite previously added rules for inheriting classes
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::exclude(const Identifier* subclass, bool overwrite, bool clean)
+    {
+        this->add(subclass, false, overwrite, clean);
+    }
+
+    /**
+        @brief Adds a new rule for a given subclass to the mask.
+        @param subclass The subclass
+        @param bInclude The rule: include (true) or exclude (false)
+        @param overwrite True = overwrite previously added rules for inheriting classes
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::add(const Identifier* subclass, bool bInclude, bool overwrite, bool clean)
+    {
+        // Check if the given subclass is a child of our root-class
+        if (subclass->isA(this->root_->getClass()))
+        {
+            // Yes it is: Just add the rule to the three
+            this->add(this->root_, subclass, bInclude, overwrite);
+        }
+        else
+        {
+            // No it's not: Search for classes inheriting from the given class and add the rules for them
+            for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildrenBegin(); it != subclass->getDirectChildrenEnd(); ++it)
+                if ((*it)->isA(this->root_->getClass()))
+                    if (overwrite || (!this->nodeExists(*it))) // If we don't want to overwrite, only add nodes that don't already exist
+                        this->add(this->root_, *it, bInclude, overwrite);
+        }
+
+        // Clean the rule-tree
+        if (clean)
+            this->clean();
+    }
+
+    /**
+        @brief Adds a new rule for a given subclass to a node of the internal rule-tree (recursive function).
+        @param node The node
+        @param subclass The subclass
+        @param bInclude The rule: include (true) or exclude (false)
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMask::add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude, bool overwrite)
+    {
+        // Check if the current node contains exactly the subclass we want to add
+        if (subclass == node->getClass())
+        {
+            // We're at the right place, just change the mask and return
+            node->setIncluded(bInclude, overwrite);
+            return;
+        }
+        else if (subclass->isA(node->getClass()))
+        {
+            // Search for an already existing node, containing the subclass we want to add
+            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it)
+            {
+                if (subclass->isA((*it)->getClass()))
+                {
+                    // We've found an existing node -> delegate the work with a recursive function-call and return
+                    this->add(*it, subclass, bInclude, overwrite);
+                    return;
+                }
+            }
+
+            // There is no existing node satisfying our needs -> we create a new node
+            ClassTreeMaskNode* newnode = new ClassTreeMaskNode(subclass, bInclude);
+
+            // Search for nodes that should actually be subnodes of our new node and erase them
+            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); )
+            {
+                if ((*it)->getClass()->isChildOf(subclass))
+                {
+                    // We've found a subnode: add it to the new node and erase it from the current node
+                    if (!overwrite)
+                        newnode->addSubnode(*it);
+                    else
+                        delete (*it);
+
+                    node->subnodes_.erase(it++);
+                }
+                else
+                {
+                    ++it;
+                }
+            }
+
+            // Finally add the new node as a subnode to the current node
+            node->addSubnode(newnode);
+        }
+    }
+
+    /**
+        @brief Adds a new "include" rule for a single subclass. The new rule doesn't change the mask for inheriting classes.
+        @param subclass The subclass
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::includeSingle(const Identifier* subclass, bool clean)
+    {
+        this->addSingle(subclass, true, clean);
+    }
+
+    /**
+        @brief Adds a new "exclude" rule for a single subclass. The new rule doesn't change the mask for inheriting classes.
+        @param subclass The subclass
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::excludeSingle(const Identifier* subclass, bool clean)
+    {
+        this->addSingle(subclass, false, clean);
+    }
+
+    /**
+        @brief Adds a new rule for a single subclass. The new rule doesn't change the mask for inheriting classes.
+        @param bInclude The rule: include (true) or exclude (false)
+        @param subclass The subclass
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::addSingle(const Identifier* subclass, bool bInclude, bool clean)
+    {
+        for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildrenBegin(); it != subclass->getDirectChildrenEnd(); ++it)
+            this->add(*it, this->isIncluded(*it), false, false);
+
+        this->add(subclass, bInclude, false, clean);
+    }
+
+    /**
+        @brief Resets the mask to "include everything".
+    */
+    void ClassTreeMask::reset()
+    {
+        delete this->root_;
+        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
+    }
+
+    /**
+        @brief Tells if a given subclass is included or not.
+        @param subclass The subclass
+        @return Included (true) or excluded (false)
+    */
+    bool ClassTreeMask::isIncluded(const Identifier* subclass) const
+    {
+        return this->isIncluded(this->root_, subclass);
+    }
+
+    /**
+        @brief Tells if a given subclass of a node in the rule-tree is included or not (recursive function).
+        @param node The node
+        @param subclass The subclass
+        @return Included (true) or excluded (false)
+    */
+    bool ClassTreeMask::isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const
+    {
+        // Check if the searched subclass is of the same type as the class in the current node or a derivative
+        if (subclass->isA(node->getClass()))
+        {
+            // Check for the special case
+            if (subclass == node->getClass())
+                return node->isIncluded();
+
+            // Go through the list of subnodes and look for a node containing the searched subclass and delegate the request by a recursive function-call.
+            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it)
+                if (subclass->isA((*it)->getClass()))
+                    return isIncluded(*it, subclass);
+
+            // There is no subnode containing our class -> the rule of the current node takes in effect
+            return node->isIncluded();
+        }
+        else
+        {
+            // The class is not included in the mask: return false
+            return false;
+        }
+    }
+
+    /**
+        @brief Tells if a given subclass is excluded or not.
+        @param subclass The subclass
+        @return The inverted rule: Excluded (true) or included (false)
+    */
+    bool ClassTreeMask::isExcluded(const Identifier* subclass) const
+    {
+        return (!this->isIncluded(subclass));
+    }
+
+    /**
+        @brief Removes all unneeded rules that don't change the information of the mask.
+    */
+    void ClassTreeMask::clean()
+    {
+        this->clean(this->root_);
+    }
+
+    /**
+        @brief Removes all unneded rules that don't change the information of a node of a mask (recursive function).
+        @param node The node
+    */
+    void ClassTreeMask::clean(ClassTreeMaskNode* node)
+    {
+        // Iterate through all subnodes of the given node
+        for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); )
+        {
+            // Recursive function-call: Clean the subnode
+            this->clean(*it);
+
+            // Now check if the subnode contains the same rule as the current node
+            if ((*it)->isIncluded() == node->isIncluded())
+            {
+                // It does: Move all subnodes of the redundant subnode to the current node
+                node->subnodes_.insert(node->subnodes_.end(), (*it)->subnodes_.begin(), (*it)->subnodes_.end());
+                (*it)->subnodes_.clear();
+
+                // Remove the redundant subnode from the current node
+                node->subnodes_.erase(it++);
+            }
+            else
+            {
+                // The subnode is necessary: Move on to the next subnode
+                ++it;
+            }
+        }
+    }
+
+    /**
+        @brief Checks if a node for the given subclass exists.
+        @param subclass The Identifier of the subclass
+        @return True = the node exists
+    */
+    bool ClassTreeMask::nodeExists(const Identifier* subclass)
+    {
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+            if ((*it)->getClass() == subclass)
+                return true;
+
+        return false;
+    }
+
+    /**
+        @brief Assignment operator: Adds all rules of the other mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator=(const ClassTreeMask& other)
+    {
+        // Make a copy to avoid troubles with self-assignments (like A = A).
+        ClassTreeMask temp(other);
+
+        // Removes all current rules
+        this->reset();
+
+        // Copy all rules from the other mask
+        for (ClassTreeMaskIterator it = temp.root_; it; ++it)
+            this->add(it->getClass(), it->isIncluded(), false, false);
+
+        // Return a reference to the mask itself
+        return (*this);
+    }
+
+    /**
+        @brief Compares the mask with another mask and returns true if they represent the same logic.
+        @param other The other mask
+        @return True if both masks represent the same logic
+    */
+    bool ClassTreeMask::operator==(const ClassTreeMask& other) const
+    {
+        ClassTreeMask temp1 = other;
+        ClassTreeMask temp2 = (*this);
+
+        temp1.clean();
+        temp2.clean();
+
+        ClassTreeMaskIterator it1 = temp1.root_;
+        ClassTreeMaskIterator it2 = temp2.root_;
+
+        for ( ; it1 && it2; ++it1, ++it2)
+            if (it1->getClass() != it2->getClass())
+                return false;
+
+        return true;
+    }
+
+    /**
+        @brief Compares the mask with another mask and returns true if they represent different logics.
+        @param other The other mask
+        @return True if the masks represent different logics
+    */
+    bool ClassTreeMask::operator!=(const ClassTreeMask& other) const
+    {
+        return (!((*this) == other));
+    }
+
+    /**
+        @brief Prefix operator + does nothing.
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator+() const
+    {
+        return (*this);
+    }
+
+    /**
+        @brief Prefix operator - inverts the mask.
+        @return The inverted mask
+    */
+    ClassTreeMask ClassTreeMask::operator-() const
+    {
+        return (!(*this));
+    }
+
+    /**
+        @brief Adds two masks in the sense of a union (all classes that are included in at least one of the masks will be included in the resulting mask too).
+        @param other The mask to unite with
+        @return The union
+    */
+    ClassTreeMask ClassTreeMask::operator+(const ClassTreeMask& other) const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the first mask, calculate the rule with the or-operation
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) or other.isIncluded(subclass), false, false);
+        }
+
+        // Add all nodes from the second mask, calculate the rule with the or-operation
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) or other.isIncluded(subclass), false, false);
+        }
+
+        // Drop all redundant rules
+        newmask.clean();
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Intersects two masks (only classes that are included in both masks will be included in the resulting mask too).
+        @param other The mask to intersect with
+        @return The intersection
+    */
+    ClassTreeMask ClassTreeMask::operator*(const ClassTreeMask& other) const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the first mask, calculate the rule with the and-operation
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) and other.isIncluded(subclass), false, false);
+        }
+
+        // Add all nodes from the second mask, calculate the rule with the and-operation
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) and other.isIncluded(subclass), false, false);
+        }
+
+        // Drop all redundant rules
+        newmask.clean();
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Removes all elements of the second mask from the first mask (all classes that are included in the first mask stay included, except those that are included in the second mask too).
+        @param other The mask to subtract.
+        @return The difference
+    */
+    ClassTreeMask ClassTreeMask::operator-(const ClassTreeMask& other) const
+    {
+        return ((*this) * (!other));
+    }
+
+    /**
+        @brief Inverts the mask (all included classes are now excluded and vice versa).
+        @return The complement
+    */
+    ClassTreeMask ClassTreeMask::operator!() const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the other mask, inverting the rules
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, !this->isIncluded(subclass), false, false);
+        }
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Unites this mask with another mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator+=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) + other;
+        return (*this);
+    }
+
+    /**
+        @brief Intersects this mask with another mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator*=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) * other;
+        return (*this);
+    }
+
+    /**
+        @brief Subtracts another mask from this mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator-=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) - other;
+        return (*this);
+    }
+
+    /**
+        @brief Intersects two masks (only classes that are included in both masks will be included in the resulting mask too).
+        @param other The mask to intersect with
+        @return The intersection
+    */
+    ClassTreeMask ClassTreeMask::operator&(const ClassTreeMask& other) const
+    {
+        return ((*this) * other);
+    }
+
+    /**
+        @brief Adds two masks in the sense of a union (all classes that are included in at least one of the masks will be included in the resulting mask too).
+        @param other The mask to unite with
+        @return The union
+    */
+    ClassTreeMask ClassTreeMask::operator|(const ClassTreeMask& other) const
+    {
+        return ((*this) + other);
+    }
+
+    /**
+        @brief Joins two masks in the sense of a xor (exclusivity) operation (all classes that are included in exactly one of the masks, but not in both, will be included in the resulting mask too).
+        @param other The mask to join with
+        @return The result
+    */
+    ClassTreeMask ClassTreeMask::operator^(const ClassTreeMask& other) const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the first mask, calculate the rule with the xor-operation
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) xor other.isIncluded(subclass), false, false);
+        }
+
+        // Add all nodes from the second mask, calculate the rule with the xor-operation
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) xor other.isIncluded(subclass), false, false);
+        }
+
+        // Drop all redundant rules
+        newmask.clean();
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Inverts the mask (all included classes are now excluded and vice versa).
+        @return The complement
+    */
+    ClassTreeMask ClassTreeMask::operator~() const
+    {
+        return (!(*this));
+    }
+
+    /**
+        @brief Intersects this mask with another mask (and-operation)
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator&=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) & other;
+        return (*this);
+    }
+
+    /**
+        @brief Unites this mask with another mask (or-operation).
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator|=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) | other;
+        return (*this);
+    }
+
+    /**
+        @brief Joins this mask with another mask with a xor-operation.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator^=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) ^ other;
+        return (*this);
+    }
+
+    /**
+        @brief Converts the content of a mask into a human readable string and puts it on the ostream.
+        @param out The ostream
+        @param mask The mask
+        @return A reference to the ostream
+    */
+    std::ostream& operator<<(std::ostream& out, const ClassTreeMask& mask)
+    {
+        // Iterate through all rules
+        for (ClassTreeMaskIterator it = mask.root_; it; ++it)
+        {
+            // Calculate the prefix: + means included, - means excluded
+            if (it->isIncluded())
+                out << "+";
+            else
+                out << "-";
+
+            // Put the name of the corresponding class on the stream
+            out << it->getClass()->getName() << " ";
+        }
+
+        return out;
+    }
+
+
+    // ###################################
+    // ### ClassTreeMaskObjectIterator ###
+    // ###################################
+    /**
+        @brief Initializes the iterator from a given ClassTreeMask.
+        @param mask The mask
+    */
+    const ClassTreeMaskObjectIterator& ClassTreeMaskObjectIterator::operator=(const ClassTreeMask& mask)
+    {
+        // Clear everything, use a cleaned copy of the mask
+        this->subclasses_.clear();
+        ClassTreeMask temp = mask;
+        temp.clean();
+
+        // Create the subclass-list by going through the mask-tree, starting with the root-node
+        this->create(temp.root_);
+
+        // Move the subclass-iterator to the beginning of the subclass-list
+        this->subclassIterator_ = this->subclasses_.begin();
+
+        // If there is a first subclass, move the object-iterator to the first object of this class. Else go to the end
+        if (this->subclassIterator_ != this->subclasses_.end())
+            this->objectIterator_ = (*this->subclassIterator_).first->getObjects()->begin();
+        else
+            this->objectIterator_ = ObjectList<BaseObject>::end();
+
+        // Check if the iterator points on a valid object. If not, go to the next object by calling ++
+        if (!this->objectIterator_ || ((*this->subclassIterator_).second && !this->objectIterator_->isExactlyA((*this->subclassIterator_).first)))
+            this->operator++();
+
+        return (*this);
+    }
+
+    /**
+        @brief Iterate to the next object (if any).
+        @return The iterator itself
+    */
+    const ClassTreeMaskObjectIterator& ClassTreeMaskObjectIterator::operator++()
+    {
+        if (this->objectIterator_)
+        {
+            // The iterator points on a valid object, therefore we also have a valid subclass-iterator at the moment
+            do
+            {
+                // Go to the next object
+                ++this->objectIterator_;
+
+                while (!this->objectIterator_)
+                {
+                    // We reached the end of the current objectlist - go to the next class
+                    ++this->subclassIterator_;
+
+                    // Check if there really is a next class. If yes, move the object-iterator to the first object
+                    if (this->subclassIterator_ != this->subclasses_.end())
+                        this->objectIterator_ = (*this->subclassIterator_).first->getObjects()->begin();
+                    else
+                        return (*this);
+                }
+
+            // Repeat this until we reach a valid object or the end
+            } while ((*this->subclassIterator_).second && !this->objectIterator_->isExactlyA((*this->subclassIterator_).first));
+        }
+        return (*this);
+    }
+
+    /**
+        @brief Recursive function to create the Iterators subclass-list by going through the node-tree of the mask.
+        @param node The current node
+    */
+    void ClassTreeMaskObjectIterator::create(ClassTreeMaskNode* node)
+    {
+        // Add the class of this node to the list, if the class is included
+        if (node->isIncluded())
+        {
+            // If there are some subnodes, the bool is "true", meaning we have to check for the exact clss when iterating
+            if (node->hasSubnodes())
+                this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(node->getClass(), true));
+            else
+                this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(node->getClass(), false));
+        }
+
+        // Now check if the node has subnodes
+        if (node->hasSubnodes())
+        {
+            // Get all _direct_ children of the nodes class
+            std::set<const Identifier*> directChildren = node->getClass()->getDirectChildren();
+
+            // Iterate through all subnodes
+            for (std::list<ClassTreeMaskNode*>::iterator it1 = node->subnodes_.begin(); it1 != node->subnodes_.end(); ++it1)
+            {
+                // Recursive call to this function with the subnode
+                this->create(*it1);
+
+                // Only execute the following code if the current node is included, meaning some of the subnodes might be included too
+                if (node->isIncluded())
+                {
+                    scanChildren: // This is a label for goto
+
+                    // Iterate through all direct children
+                    for (std::set<const Identifier*>::iterator it2 = directChildren.begin(); it2 != directChildren.end(); ++it2)
+                    {
+                        // Check if the subnode (it1) is a child of the directChild (it2)
+                        if ((*it1)->getClass()->isA(*it2))
+                        {
+                            // Yes it is - remove the directChild (it2) from the list, because it will already be handled by a recursive call to the create() function
+                            directChildren.erase(it2);
+
+                            // Check if the removed directChild was exactly the subnode
+                            if (!(*it1)->getClass()->isExactlyA(*it2))
+                            {
+                                // No, it wasn't exactly the subnode - therefore there are some classes between
+
+                                // Add the previously removed directChild (it2) to the subclass-list
+                                this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(*it2, true));
+
+                                // Insert all directChildren of the directChild
+                                directChildren.insert((*it2)->getDirectChildrenBegin(), (*it2)->getDirectChildrenEnd());
+
+                                // Restart the scan with the expanded set of directChildren
+                                goto scanChildren;
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // Now add all directChildren which don't have subnodes on their own to the subclass-list
+            // The bool is "false", meaning they have no subnodes and therefore need no further checks
+            if (node->isIncluded())
+                for (std::set<const Identifier*>::iterator it = directChildren.begin(); it != directChildren.end(); ++it)
+                    this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(*it, false));
+        }
+    }
+}
Index: code/trunk/src/libraries/core/ClassTreeMask.h
===================================================================
--- code/trunk/src/libraries/core/ClassTreeMask.h	(revision 5781)
+++ code/trunk/src/libraries/core/ClassTreeMask.h	(revision 5781)
@@ -0,0 +1,286 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
+
+    ClassTreeMask is a class to define a mask of the class-tree beginning with BaseObject.
+    You can include or exclude classes by calling the corresponding functions with the
+    Identifier of the class.
+
+    You can work with a ClassTreeMask in the sense of the set-theory, meaning that you can create
+    unions, intersections, complements and differences by using overloaded operators.
+
+
+
+    The ClassTreeMask is internally represented by a tree. The nodes in the tree are
+    ClassTreeMaskNodes, containing the rule (included or excluded) for this class and all
+    subclasses and a list of all subnodes. To minimize the size, the tree contains only
+    nodes changing the mask. By adding new rules, the tree gets reordered dynamically.
+
+    Adding a new rule overwrites all rules assigned to inherited classes. Use overwrite = false
+    if you don't like this feature. Useless rules that don't change the information of the mask
+    aren't saved in the internal tree. Use clean = false if you wan't to save them.
+
+    With overwrite = false and clean = false it doesn't matter in which way you create the mask.
+    You can manually drop useless rules from the tree by calling clean().
+
+
+
+    Because of the complicated shape of the internal tree, there is an iterator to iterate
+    through all ClassTreeMaskNodes of a mask. It starts with the BaseObject and moves on to
+    the first subclass until it reaches a leaf of the tree. Then the iterator moves one step
+    back and iterates to the second subclass. If there are no more subclasses, it steps another
+    step back, and so on.
+
+    Example: A and B are children of BaseObject, A1 and A2 are children of A, B1 and B2 are children of B.
+    The ClassTreeMaskIterator would move trough the tree in the following order:
+    BaseObject, A, A1, A2, B, B1, B2.
+
+    Note that the iterator doesn't move trough the whole class-tree, but only through the
+    internal tree of the mask, containing the minimal needed set of nodes to describe the mask.
+*/
+
+#ifndef _ClassTreeMask_H__
+#define _ClassTreeMask_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+#include <stack>
+#include "BaseObject.h"
+#include "Iterator.h"
+
+namespace orxonox
+{
+    // ###################################
+    // ###      ClassTreeMaskNode      ###
+    // ###################################
+    //! The ClassTreeMaskNode is a node in the internal tree of the ClassTreeMask, containing the rules of the mask.
+    /**
+        The ClassTreeMaskNode is used to store the rule (included or excluded) for a given
+        class (described by the corresponding Identifier). The nodes are used in the internal
+        tree of ClassTreeMask. To build a tree, they store a list of all subnodes.
+    */
+    class _CoreExport ClassTreeMaskNode
+    {
+        friend class ClassTreeMask;
+        friend class ClassTreeMaskIterator;
+        friend class ClassTreeMaskObjectIterator;
+
+        public:
+            ClassTreeMaskNode(const Identifier* subclass, bool bIncluded = true);
+            ~ClassTreeMaskNode();
+
+            void include(bool overwrite = true);
+            void exclude(bool overwrite = true);
+            void setIncluded(bool bIncluded, bool overwrite = true);
+
+            void addSubnode(ClassTreeMaskNode* subnode);
+
+            /** @brief Tells if the rule is "included" or not. @return The rule: true = included, false = excluded */
+            inline bool isIncluded() const { return this->bIncluded_; }
+            /** @brief Tells if the rule is "excluded" or not. @return The inverted rule: true = excluded, false = included */
+            inline bool isExcluded() const { return (!this->bIncluded_); }
+
+            /** @brief Returns the Identifier of the class the rule refers to. @return The Identifier representing the class */
+            inline const Identifier* getClass() const { return this->subclass_; }
+
+            /** @brief Returns true if the Node has some subnodes. */
+            inline bool hasSubnodes() const { return !this->subnodes_.empty(); }
+
+        private:
+            void deleteAllSubnodes();
+
+            const Identifier* subclass_;                //!< The Identifier of the subclass the rule refers to
+            bool bIncluded_;                            //!< The rule: included or excluded
+            std::list<ClassTreeMaskNode*> subnodes_;    //!< A list containing all subnodes in the tree
+    };
+
+
+    // ###################################
+    // ###    ClassTreeMaskIterator    ###
+    // ###################################
+    //! The ClassTreeMaskIterator moves through all ClassTreeMaskNodes of the internal tree of a ClassTreeMask, containing the rules.
+    /**
+        Because of the complicated shape of the internal rule-tree of ClassTreeMask, an
+        iterator is used to move through all nodes of the tree. It starts with the BaseObject
+        and moves on to the first subclass until it reaches a leaf of the tree. Then the
+        iterator moves one step back and iterates to the second subclass. If there are no more
+        subclasses, it steps another step back, and so on.
+    */
+    class _CoreExport ClassTreeMaskIterator
+    {
+        public:
+            ClassTreeMaskIterator(ClassTreeMaskNode* node);
+            ~ClassTreeMaskIterator();
+
+            const ClassTreeMaskIterator& operator++();
+            ClassTreeMaskNode* operator*() const;
+            ClassTreeMaskNode* operator->() const;
+            operator bool() const;
+            bool operator==(ClassTreeMaskNode* compare) const;
+            bool operator!=(ClassTreeMaskNode* compare) const;
+
+        private:
+            std::stack<std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator> > nodes_;    //!< A stack to store list-iterators
+            std::list<ClassTreeMaskNode*> rootlist_;                                                                            //!< A list for internal use (it only stores the root-node)
+    };
+
+
+    // ###################################
+    // ###        ClassTreeMask        ###
+    // ###################################
+    //! The ClassTreeMask is a set of rules, containing the information for each class whether it's included or not.
+    /**
+        With a ClassTreeMask, you can include or exclude subtrees of the class-tree, starting
+        with a given subclass, described by the corresponding Identifier. To minimize the size
+        of the mask, the mask saves only relevant rules. But you can manually add rules that
+        don't change the information of the mask by using clean = false. If you want to drop
+        useless rules, call the clean() function.
+    */
+    class _CoreExport ClassTreeMask
+    {
+        friend class ClassTreeMaskObjectIterator;
+
+        public:
+            ClassTreeMask();
+            ClassTreeMask(const ClassTreeMask& other);
+            ~ClassTreeMask();
+
+            void include(const Identifier* subclass, bool overwrite = true, bool clean = true);
+            void exclude(const Identifier* subclass, bool overwrite = true, bool clean = true);
+            void add(const Identifier* subclass, bool bInclude, bool overwrite = true, bool clean = true);
+
+            void includeSingle(const Identifier* subclass, bool clean = true);
+            void excludeSingle(const Identifier* subclass, bool clean = true);
+            void addSingle(const Identifier* subclass, bool bInclude, bool clean = true);
+
+            void reset();
+            void clean();
+
+            bool isIncluded(const Identifier* subclass) const;
+            bool isExcluded(const Identifier* subclass) const;
+
+            /** @brief Begin of the ClassTreeMaskObjectIterator. */
+            inline const ClassTreeMask& begin() const { return (*this); }
+            /** @brief End of the ClassTreeMaskObjectIterator. */
+            inline BaseObject*          end()   const { return 0; }
+
+            const ClassTreeMask& operator=(const ClassTreeMask& other);
+
+            bool operator==(const ClassTreeMask& other) const;
+            bool operator!=(const ClassTreeMask& other) const;
+
+            const ClassTreeMask& operator+() const;
+            ClassTreeMask operator-() const;
+
+            ClassTreeMask operator+(const ClassTreeMask& other) const;
+            ClassTreeMask operator*(const ClassTreeMask& other) const;
+            ClassTreeMask operator-(const ClassTreeMask& other) const;
+            ClassTreeMask operator!() const;
+
+            const ClassTreeMask& operator+=(const ClassTreeMask& other);
+            const ClassTreeMask& operator*=(const ClassTreeMask& other);
+            const ClassTreeMask& operator-=(const ClassTreeMask& other);
+
+            ClassTreeMask operator&(const ClassTreeMask& other) const;
+            ClassTreeMask operator|(const ClassTreeMask& other) const;
+            ClassTreeMask operator^(const ClassTreeMask& other) const;
+            ClassTreeMask operator~() const;
+
+            const ClassTreeMask& operator&=(const ClassTreeMask& other);
+            const ClassTreeMask& operator|=(const ClassTreeMask& other);
+            const ClassTreeMask& operator^=(const ClassTreeMask& other);
+
+            friend std::ostream& operator<<(std::ostream& out, const ClassTreeMask& mask);
+
+        private:
+            void add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude, bool overwrite = true);
+            bool isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const;
+            void clean(ClassTreeMaskNode* node);
+            bool nodeExists(const Identifier* subclass);
+
+            ClassTreeMaskNode* root_;   //!< The root-node of the internal rule-tree, usually BaseObject
+    };
+
+
+    // ###################################
+    // ### ClassTreeMaskObjectIterator ###
+    // ###################################
+    //! The ClassTreeMaskObjectIterator iterates through all objects of all classes, included by a ClassTreeMask.
+    /**
+        The ClassTreeMaskObjectIterator iterates through all objects of all classes,
+        included by a ClassTreeMask. This is done the following way:
+
+        ClassTreeMask mask;
+        for (ClassTreeMaskObjectIterator it = mask.begin(); it != mask.end(); ++it)
+            it->doSomething();
+
+        Note: The ClassTreeMaskObjectIterator handles all objects as BaseObjects. If
+              you want to use another class, you should use a dynamic_cast.
+
+        Performance of ClassTreeMaskObjectIterator is good as long as you don't exclude
+        subclasses of included classes. Of course you can still exlucde subclasses, but
+        if this is done more often, we need a new implementation using a second ObjectList
+        in the Identifier, containing all objects of exactly one class.
+    */
+    class _CoreExport ClassTreeMaskObjectIterator
+    {
+        public:
+            /** @brief Defaultconstructor: Does nothing. */
+            inline ClassTreeMaskObjectIterator() {}
+            /** @brief Constructor: Initializes the iterator from a given ClassTreeMask. @param mask The mask */
+            inline ClassTreeMaskObjectIterator(const ClassTreeMask& mask) { (*this) = mask; }
+
+            const ClassTreeMaskObjectIterator& operator=(const ClassTreeMask& mask);
+
+            const ClassTreeMaskObjectIterator& operator++();
+
+            /** @brief Returns true if the ClassTreeMaskObjectIterator points at the given object. @param pointer The pointer of the object */
+            inline bool operator==(BaseObject* pointer) const { return ((*this->objectIterator_) == pointer); }
+            /** @brief Returns true if the ClassTreeMaskObjectIterator doesn't point at the given object. @param pointer The pointer of the object */
+            inline bool operator!=(BaseObject* pointer) const { return ((*this->objectIterator_) != pointer); }
+            /** @brief Returns true if the ClassTreeMaskObjectIterator hasn't already reached the end. */
+            inline operator bool() const { return (this->objectIterator_); }
+            /** @brief Returns the object the ClassTreeMaskObjectIterator currently points at. */
+            inline BaseObject* operator*() const { return (*this->objectIterator_); }
+            /** @brief Returns the object the ClassTreeMaskObjectIterator currently points at. */
+            inline BaseObject* operator->() const { return (*this->objectIterator_); }
+
+        private:
+            void create(ClassTreeMaskNode* node);
+
+            std::list<std::pair<const Identifier*, bool> >           subclasses_;       //!< A list of all Identifiers through which objects the iterator should iterate
+            std::list<std::pair<const Identifier*, bool> >::iterator subclassIterator_; //!< The current class of the iterator
+            Iterator<BaseObject>                                     objectIterator_;   //!< The current object of the iterator
+    };
+}
+
+#endif /* _ClassTreeMask_H__ */
Index: code/trunk/src/libraries/core/Clock.h
===================================================================
--- code/trunk/src/libraries/core/Clock.h	(revision 5774)
+++ code/trunk/src/libraries/core/Clock.h	(revision 5781)
@@ -31,6 +31,5 @@
 
 #include "CorePrereqs.h"
-
-namespace Ogre { class Timer; }
+#include "util/OgreForwardRefs.h"
 
 namespace orxonox
Index: code/trunk/src/libraries/core/CommandEvaluation.cc
===================================================================
--- code/trunk/src/libraries/core/CommandEvaluation.cc	(revision 5781)
+++ code/trunk/src/libraries/core/CommandEvaluation.cc	(revision 5781)
@@ -0,0 +1,313 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CommandEvaluation.h"
+
+#include "util/Debug.h"
+#include "util/StringUtils.h"
+#include "ConsoleCommand.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    CommandEvaluation::CommandEvaluation()
+    {
+        this->initialize("");
+        this->state_ = CommandState::Uninitialized;
+    }
+
+    void CommandEvaluation::initialize(const std::string& command)
+    {
+        this->bNewCommand_ = true;
+        this->bCommandChanged_ = false;
+        this->originalCommand_ = command;
+        this->command_ = command;
+        this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
+
+        this->additionalParameter_ = "";
+
+        this->bEvaluatedParams_ = false;
+
+        this->listOfPossibleIdentifiers_.clear();
+        this->listOfPossibleFunctions_.clear();
+        this->listOfPossibleArguments_.clear();
+
+        this->functionclass_ = 0;
+        this->function_ = 0;
+        this->possibleArgument_ = "";
+        this->argument_ = "";
+
+        this->errorMessage_ = "";
+        this->state_ = CommandState::Empty;
+    }
+
+    bool CommandEvaluation::isValid() const
+    {
+        return (this->function_);
+    }
+
+    bool CommandEvaluation::execute() const
+    {
+        if (!this->isValid())
+            return false;
+
+        if (this->bEvaluatedParams_ && this->function_)
+        {
+            COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << " " << this->param_[0] << " " << this->param_[1] << " " << this->param_[2] << " " << this->param_[3] << " " << this->param_[4] << std::endl;
+            (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
+            return true;
+        }
+
+        if (!this->bCommandChanged_ || nocaseCmp(removeTrailingWhitespaces(this->command_), removeTrailingWhitespaces(this->originalCommand_)) == 0)
+        {
+            COUT(4) << "CE_execute: " << this->command_ << "\n";
+
+            unsigned int startindex = this->getStartindex();
+            if (this->commandTokens_.size() > startindex)
+                return this->function_->parse(removeSlashes(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter()));
+            else
+                return this->function_->parse(removeSlashes(this->additionalParameter_));
+        }
+
+        return false;
+    }
+
+    std::string CommandEvaluation::complete()
+    {
+        if (!this->bNewCommand_)
+        {
+            switch (this->state_)
+            {
+                case CommandState::Uninitialized:
+                    break;
+                case CommandState::Empty:
+                    break;
+                case CommandState::ShortcutOrIdentifier:
+                    if (this->function_)
+                    {
+                        if (this->function_->getParamCount() == 0)
+                            return (this->command_ = this->function_->getName());
+                        else
+                            return (this->command_ = this->function_->getName() + " ");
+                    }
+                    else if (this->functionclass_)
+                        return (this->command_ = this->functionclass_->getName() + " ");
+                    break;
+                case CommandState::Function:
+                    if (this->function_)
+                    {
+                        if (this->function_->getParamCount() == 0)
+                            return (this->command_ = this->functionclass_->getName() + " " + this->function_->getName());
+                        else
+                            return (this->command_ = this->functionclass_->getName() + " " + this->function_->getName() + " ");
+                    }
+                    break;
+                case CommandState::ParamPreparation:
+                case CommandState::Params:
+                {
+                    if (this->argument_ == "" && this->possibleArgument_ == "")
+                        break;
+
+                    unsigned int maxIndex = this->commandTokens_.size();
+                    if (this->command_[this->command_.size() - 1] != ' ')
+                        maxIndex -= 1;
+                    std::string whitespace = "";
+
+                    if (this->possibleArgument_ != "")
+                    {
+                        this->argument_ = this->possibleArgument_;
+                        if (this->function_->getParamCount() > (maxIndex + 1 - this->getStartindex()))
+                            whitespace = " ";
+                    }
+
+                    return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + " " + this->argument_ + whitespace);
+                    break;
+                }
+                case CommandState::Finished:
+                    break;
+                case CommandState::Error:
+                    break;
+            }
+        }
+        this->bNewCommand_ = false;
+        return this->command_;
+    }
+
+    std::string CommandEvaluation::hint() const
+    {
+        switch (this->state_)
+        {
+            case CommandState::Uninitialized:
+                break;
+            case CommandState::Empty:
+            case CommandState::ShortcutOrIdentifier:
+                if (this->listOfPossibleFunctions_.size() == 0)
+                    return CommandEvaluation::dump(this->listOfPossibleIdentifiers_);
+                else if (this->listOfPossibleIdentifiers_.size() == 0)
+                    return CommandEvaluation::dump(this->listOfPossibleFunctions_);
+                else
+                    return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_));
+                break;
+            case CommandState::Function:
+                return CommandEvaluation::dump(this->listOfPossibleFunctions_);
+                break;
+            case CommandState::ParamPreparation:
+            case CommandState::Params:
+                if (this->listOfPossibleArguments_.size() > 0)
+                    return CommandEvaluation::dump(this->listOfPossibleArguments_);
+                else
+                    return CommandEvaluation::dump(this->function_);
+            case CommandState::Finished:
+                if (this->function_)
+                    return CommandEvaluation::dump(this->function_);
+                break;
+            case CommandState::Error:
+                return this->errorMessage_;
+                break;
+        }
+
+        return "";
+    }
+
+    void CommandEvaluation::evaluateParams()
+    {
+        this->bEvaluatedParams_ = false;
+
+        for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
+            this->param_[i] = MT_Type::Null;
+
+        if (!this->isValid())
+            return;
+
+        unsigned int startindex = this->getStartindex();
+
+        if (this->commandTokens_.size() <= startindex)
+        {
+            if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " "))
+                this->bEvaluatedParams_ = true;
+        }
+        else if (this->commandTokens_.size() > startindex)
+        {
+            if (this->function_->evaluate(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter(), this->param_, " "))
+                this->bEvaluatedParams_ = true;
+        }
+    }
+
+    void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiType param)
+    {
+        if (index < MAX_FUNCTOR_ARGUMENTS)
+            this->param_[index] = param;
+    }
+
+    MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const
+    {
+        if (index < MAX_FUNCTOR_ARGUMENTS)
+            return this->param_[index];
+
+        return MT_Type::Null;
+    }
+
+    bool CommandEvaluation::hasReturnvalue() const
+    {
+        if (this->function_)
+            return this->function_->hasReturnvalue();
+
+        return MT_Type::Null;
+    }
+
+    MultiType CommandEvaluation::getReturnvalue() const
+    {
+        if (this->function_)
+            return this->function_->getReturnvalue();
+
+        return MultiType();
+    }
+
+
+    unsigned int CommandEvaluation::getStartindex() const
+    {
+        if (this->functionclass_ && this->function_)
+            return 2;
+        else if (this->function_)
+            return 1;
+        else
+            return 0;
+    }
+
+    std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
+    {
+        std::string output = "";
+        for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                output += " ";
+
+            output += *(*it).second;
+        }
+        return output;
+    }
+
+    std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
+    {
+        std::string output = "";
+        for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                output += " ";
+
+            output += (*it).getDisplay();
+        }
+        return output;
+    }
+
+    std::string CommandEvaluation::dump(const ConsoleCommand* command)
+    {
+        std::string output = command->getName();
+        if (command->getParamCount() > 0)
+            output += ": ";
+
+        for (unsigned int i = 0; i < command->getParamCount(); i++)
+        {
+            if (i != 0)
+                output += " ";
+
+            if (command->defaultValueSet(i))
+                output += "[";
+            else
+                output += "{";
+
+            output += command->getTypenameParam(i);
+
+            if (command->defaultValueSet(i))
+                output += "=" + command->getDefaultValue(i).getString() + "]";
+            else
+                output += "}";
+        }
+        return output;
+    }
+}
Index: code/trunk/src/libraries/core/CommandEvaluation.h
===================================================================
--- code/trunk/src/libraries/core/CommandEvaluation.h	(revision 5781)
+++ code/trunk/src/libraries/core/CommandEvaluation.h	(revision 5781)
@@ -0,0 +1,124 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CommandEvaluation_H__
+#define _CommandEvaluation_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include <list>
+
+#include "ArgumentCompletionListElement.h"
+#include "util/SubString.h"
+#include "util/MultiType.h"
+
+namespace orxonox
+{
+    namespace CommandState
+    {
+        enum Value
+        {
+            Uninitialized,
+            Empty,
+            ShortcutOrIdentifier,
+            Function,
+            ParamPreparation,
+            Params,
+            Finished,
+            Error
+        };
+    }
+
+    class _CoreExport CommandEvaluation
+    {
+        friend class CommandExecutor;
+
+        public:
+            CommandEvaluation();
+
+            void initialize(const std::string& command);
+
+            bool execute() const;
+            std::string complete();
+            std::string hint() const;
+            void evaluateParams();
+
+            bool isValid() const;
+
+            inline ConsoleCommand* getConsoleCommand() const
+                { return this->function_; }
+            inline const std::string& getOriginalCommand() const
+                { return this->originalCommand_; }
+            inline const std::string& getCommand() const
+                { return this->command_; }
+
+            inline void setAdditionalParameter(const std::string& param)
+                { this->additionalParameter_ = param; this->bEvaluatedParams_ = false; }
+            inline std::string getAdditionalParameter() const
+                { return (this->additionalParameter_ != "") ? (" " + this->additionalParameter_) : ""; }
+
+            void setEvaluatedParameter(unsigned int index, MultiType param);
+            MultiType getEvaluatedParameter(unsigned int index) const;
+
+            bool hasReturnvalue() const;
+            MultiType getReturnvalue() const;
+
+        private:
+            unsigned int getStartindex() const;
+            static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list);
+            static std::string dump(const ArgumentCompletionList& list);
+            static std::string dump(const ConsoleCommand* command);
+
+
+            bool bNewCommand_;
+            bool bCommandChanged_;
+
+            std::string originalCommand_;
+            std::string command_;
+            SubString commandTokens_;
+            std::string additionalParameter_;
+
+            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleIdentifiers_;
+            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctions_;
+            ArgumentCompletionList listOfPossibleArguments_;
+
+            Identifier* functionclass_;
+            ConsoleCommand* function_;
+            std::string possibleArgument_;
+            std::string argument_;
+
+            std::string errorMessage_;
+            CommandState::Value state_;
+
+            bool bEvaluatedParams_;
+            MultiType param_[5];
+    };
+}
+
+#endif /* _CommandEvaluation_H__ */
Index: code/trunk/src/libraries/core/CommandExecutor.cc
===================================================================
--- code/trunk/src/libraries/core/CommandExecutor.cc	(revision 5781)
+++ code/trunk/src/libraries/core/CommandExecutor.cc	(revision 5781)
@@ -0,0 +1,672 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CommandExecutor.h"
+
+#include "util/Debug.h"
+#include "util/StringUtils.h"
+#include "ConsoleCommand.h"
+#include "Identifier.h"
+#include "Language.h"
+#include "TclBind.h"
+
+namespace orxonox
+{
+    CommandExecutor& CommandExecutor::getInstance()
+    {
+        static CommandExecutor instance;
+        return instance;
+    }
+
+    CommandEvaluation& CommandExecutor::getEvaluation()
+    {
+        return CommandExecutor::getInstance().evaluation_;
+    }
+
+    const CommandEvaluation& CommandExecutor::getLastEvaluation()
+    {
+        return CommandExecutor::getInstance().evaluation_;
+    }
+
+    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command, bool bDeleteAtExit)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(command->getName());
+        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
+        {
+            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << "." << std::endl;
+        }
+
+        // Make sure we can also delete the external ConsoleCommands that don't belong to an Identifier
+        if (command && bDeleteAtExit)
+        {
+            CommandExecutor::getInstance().consoleCommandExternals_.insert(command);
+        }
+
+        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
+        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
+        return (*command);
+    }
+
+    /**
+        @brief Returns the executor of a console command shortcut with given name.
+        @brief name The name of the requested console command shortcut
+        @return The executor of the requested console command shortcut
+    */
+    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
+        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
+            return (*it).second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns the executor of a console command shortcut with given name in lowercase.
+        @brief name The name of the requested console command shortcut in lowercase
+        @return The executor of the requested console command shortcut
+    */
+    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
+        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
+            return (*it).second;
+        else
+            return 0;
+    }
+
+    bool CommandExecutor::execute(const std::string& command, bool useTcl)
+    {
+        if (useTcl)
+            return TclBind::eval(command);
+
+        CommandExecutor::parseIfNeeded(command);
+        return CommandExecutor::getEvaluation().execute();
+    }
+
+    MultiType CommandExecutor::getReturnValue()
+    {
+        return CommandExecutor::getEvaluation().getReturnvalue();
+    }
+
+    std::string CommandExecutor::getReturnValueString()
+    {
+        return CommandExecutor::getEvaluation().getReturnvalue().getString();
+    }
+
+    std::string CommandExecutor::complete(const std::string& command)
+    {
+        CommandExecutor::parseIfNeeded(command);
+        return CommandExecutor::getEvaluation().complete();
+    }
+
+    std::string CommandExecutor::hint(const std::string& command)
+    {
+        CommandExecutor::parseIfNeeded(command);
+        return CommandExecutor::getEvaluation().hint();
+    }
+
+    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
+    {
+        CommandExecutor::parse(command);
+        CommandExecutor::getEvaluation().evaluateParams();
+        return CommandExecutor::getEvaluation();
+    }
+
+    void CommandExecutor::parseIfNeeded(const std::string& command)
+    {
+        if (CommandExecutor::getEvaluation().state_ == CommandState::Uninitialized)
+        {
+            CommandExecutor::parse(command);
+        }
+        else if (CommandExecutor::getEvaluation().originalCommand_ != command)
+        {
+            if (CommandExecutor::getEvaluation().command_ == command)
+            {
+                CommandExecutor::parse(command);
+                CommandExecutor::getEvaluation().bNewCommand_ = false;
+            }
+            else
+            {
+                CommandExecutor::parse(command);
+            }
+        }
+    }
+
+    void CommandExecutor::parse(const std::string& command, bool bInitialize)
+    {
+        if (bInitialize)
+            CommandExecutor::getEvaluation().initialize(command);
+
+        CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
+        CommandExecutor::getEvaluation().command_ = command;
+
+        switch (CommandExecutor::getEvaluation().state_)
+        {
+            case CommandState::Uninitialized:
+            {
+                // Impossible
+                break;
+            }
+            case CommandState::Empty:
+            {
+                if (CommandExecutor::argumentsGiven() == 0)
+                {
+                    CommandExecutor::createListOfPossibleFunctions("");
+                    CommandExecutor::createListOfPossibleIdentifiers("");
+                    break;
+                }
+                else
+                {
+                    CommandExecutor::getEvaluation().state_ = CommandState::ShortcutOrIdentifier;
+                    // Move on to next case
+                }
+            }
+            case CommandState::ShortcutOrIdentifier:
+            {
+                if (CommandExecutor::argumentsGiven() > 1)
+                {
+                    // There's a finished first argument - check if it's a shortcut or a classname
+                    CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
+                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
+
+                    if (CommandExecutor::getEvaluation().function_)
+                    {
+                        // It's a shortcut
+                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                        CommandExecutor::getEvaluation().functionclass_ = 0;
+                        // Move on to next case
+                    }
+                    else if (CommandExecutor::getEvaluation().functionclass_)
+                    {
+                        // It's a functionname
+                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
+                        CommandExecutor::getEvaluation().function_ = 0;
+                        // Move on to next case
+                    }
+                    else
+                    {
+                        // The first argument is bad
+                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
+                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
+                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
+                        return;
+                    }
+                }
+                else
+                {
+                    // There's no finished first argument - search possible shortcuts or classnames
+                    CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0));
+                    CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0));
+
+                    unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
+                    unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size();
+
+                    if (num_functions == 1 && num_identifiers == 0)
+                    {
+                        // It's a shortcut
+                        std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
+                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
+                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
+                        {
+                            // Unfinished shortcut
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        }
+                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                        CommandExecutor::getEvaluation().functionclass_ = 0;
+                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
+                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
+                        {
+                            CommandExecutor::getEvaluation().command_ += " ";
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        }
+                        // Move on to next case
+                    }
+                    else if (num_identifiers == 1 && num_functions == 0)
+                    {
+                        // It's a classname
+                        std::string classname = *(*CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()).first;
+                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
+                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
+                        {
+                            // Unfinished classname
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        }
+                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
+                        CommandExecutor::getEvaluation().function_ = 0;
+                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
+                        // Move on to next case
+                    }
+                    else if (num_identifiers == 0 && num_functions == 0)
+                    {
+                        // No possibilities
+                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
+                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
+                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
+                        return;
+                    }
+                    else
+                    {
+                        // There are several possiblilities
+                        std::list<std::pair<const std::string*, const std::string*> > temp;
+                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end());
+                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end());
+                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp);
+                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
+                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
+                        CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        return;
+                    }
+                }
+            }
+            case CommandState::Function:
+            {
+                if (CommandExecutor::getEvaluation().functionclass_)
+                {
+                    // There is a classname - search for the commandname
+                    if (CommandExecutor::argumentsGiven() > 2)
+                    {
+                        // There is a finished second argument - check if it's a commandname
+                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
+
+                        if (CommandExecutor::getEvaluation().function_)
+                        {
+                            // It's a function
+                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                            // Move on to next case
+                        }
+                        else
+                        {
+                            // The second argument is bad
+                            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() + ".";
+                            return;
+                        }
+                    }
+                    else
+                    {
+                        // There is no finished second argument - search for possibilities
+                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
+                        unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
+
+                        if (num_functions == 1)
+                        {
+                            // It's a function
+                            std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
+                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
+                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
+                            {
+                                // Unfinished function
+                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                            }
+                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
+                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
+                            {
+                                CommandExecutor::getEvaluation().command_ += " ";
+                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                            }
+                            // Move on to next case
+                        }
+                        else if (num_functions == 0)
+                        {
+                            // No possibilities
+                            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) + ".";
+                            return;
+                        }
+                        else
+                        {
+                            // There are several possibilities
+                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
+                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                            return;
+                        }
+                    }
+                }
+                else
+                {
+                    // 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_ = CommandState::Finished;
+                    return;
+                }
+                else
+                {
+                    unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2;
+                    if (CommandExecutor::getEvaluation().functionclass_)
+                        argumentNumber -= 1;
+
+                    CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
+                    CommandExecutor::getEvaluation().state_ = CommandState::Params;
+
+                    if (CommandExecutor::getEvaluation().bCommandChanged_)
+                    {
+                        // Don't do more than one change
+                        return;
+                    }
+                }
+            }
+            case CommandState::Params:
+            {
+                if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
+                {
+                    // There is exactly one possible argument
+                    CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
+                    CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                    return;
+                }
+                else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0)
+                {
+                    // The user tries something new - we let him do
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
+                    return;
+                }
+                else
+                {
+                    // There are several possibilities
+                    unsigned int argumentNumber = CommandExecutor::argumentsGiven();
+                    if (argumentNumber > 0)
+                        --argumentNumber;
+                    if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0)
+                        --argumentNumber;
+
+                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
+                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                    return;
+                }
+            }
+            case CommandState::Finished:
+            {
+                // Nothing more to do
+                break;
+            }
+            case CommandState::Error:
+            {
+                // Bad, very bad
+                break;
+            }
+        }
+    }
+
+    unsigned int CommandExecutor::argumentsFinished()
+    {
+        unsigned int argumentsGiven = CommandExecutor::argumentsGiven();
+        if (argumentsGiven > 0)
+            return argumentsGiven - 1;
+        else
+            return 0;
+    }
+
+    unsigned int CommandExecutor::argumentsGiven()
+    {
+        if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ')
+            return CommandExecutor::getEvaluation().commandTokens_.size() + 1;
+        else
+            return CommandExecutor::getEvaluation().commandTokens_.size();
+    }
+
+    bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command)
+    {
+        if (CommandExecutor::getEvaluation().functionclass_)
+            return (CommandExecutor::argumentsGiven() > (2 + command->getParamCount()));
+        else
+            return (CommandExecutor::argumentsGiven() > (1 + command->getParamCount()));
+    }
+
+    std::string CommandExecutor::getArgument(unsigned int index)
+    {
+        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
+            return CommandExecutor::getEvaluation().commandTokens_[index];
+        else
+            return "";
+    }
+
+    std::string CommandExecutor::getLastArgument()
+    {
+        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
+    }
+
+    void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment)
+    {
+        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
+        std::string lowercase = getLowercase(fragment);
+        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
+            if ((*it).second->hasConsoleCommands())
+                if ((*it).first.find(lowercase) == 0 || fragment == "")
+                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
+    }
+
+    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
+    {
+        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
+        std::string lowercase = getLowercase(fragment);
+        if (!identifier)
+        {
+            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
+                if ((*it).first.find(lowercase) == 0 || fragment == "")
+                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
+        }
+        else
+        {
+            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
+                if ((*it).first.find(lowercase) == 0 || fragment == "")
+                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
+        }
+    }
+
+    void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param)
+    {
+        CommandExecutor::createArgumentCompletionList(command, param);
+
+        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
+        std::string lowercase = getLowercase(fragment);
+        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
+        {
+            if ((*it).lowercaseComparison())
+            {
+                if ((*it).getComparable().find(lowercase) == 0 || fragment == "")
+                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
+            }
+            else
+            {
+                if ((*it).getComparable().find(fragment) == 0 || fragment == "")
+                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
+            }
+        }
+    }
+
+    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
+    {
+        std::string lowercase = getLowercase(name);
+        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(lowercase);
+        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
+            return (*it).second;
+
+        return 0;
+    }
+
+    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
+    {
+        std::string lowercase = getLowercase(name);
+        if (!identifier)
+        {
+            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
+            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
+                return (*it).second;
+        }
+        else
+        {
+            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
+            if (it != identifier->getLowercaseConsoleCommandMapEnd())
+                return (*it).second;
+        }
+        return 0;
+    }
+
+    std::string CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
+    {
+        CommandExecutor::createArgumentCompletionList(command, param);
+
+        std::string lowercase = getLowercase(name);
+        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
+        {
+            if ((*it).lowercaseComparison())
+            {
+                if ((*it).getComparable() == lowercase)
+                    return (*it).getString();
+            }
+            else
+            {
+                if ((*it).getComparable() == name)
+                    return (*it).getString();
+            }
+        }
+
+        return "";
+    }
+
+    void CommandExecutor::createArgumentCompletionList(ConsoleCommand* command, unsigned int param)
+    {
+        std::string params[5];
+
+        unsigned int index = 0;
+        unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0);
+
+        for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i)
+        {
+            params[index] = CommandExecutor::getArgument(i);
+            ++index;
+            if (index >= 5)
+                break;
+        }
+
+        command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]);
+    }
+
+    std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list)
+    {
+        if (list.size() == 0)
+        {
+            return "";
+        }
+        else if (list.size() == 1)
+        {
+            return ((*(*list.begin()).first) + " ");
+        }
+        else
+        {
+            std::string output = "";
+            for (unsigned int i = 0; true; i++)
+            {
+                char temp = 0;
+                for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
+                {
+                    if ((*(*it).first).size() > i)
+                    {
+                        if (it == list.begin())
+                        {
+                            temp = (*(*it).first)[i];
+                        }
+                        else
+                        {
+                            if (temp != (*(*it).first)[i])
+                                return output;
+                        }
+                    }
+                    else
+                    {
+                        return output;
+                    }
+                }
+                output += temp;
+            }
+            return output;
+        }
+    }
+
+    std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list)
+    {
+        if (list.size() == 0)
+        {
+            return "";
+        }
+        else if (list.size() == 1)
+        {
+            return ((*list.begin()).getComparable() + " ");
+        }
+        else
+        {
+            std::string output = "";
+            for (unsigned int i = 0; true; i++)
+            {
+                char temp = 0;
+                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
+                {
+                    std::string argument = (*it).getComparable();
+                    if (argument.size() > i)
+                    {
+                        if (it == list.begin())
+                        {
+                            temp = argument[i];
+                        }
+                        else
+                        {
+                            if (temp != argument[i])
+                                return output;
+                        }
+                    }
+                    else
+                    {
+                        return output;
+                    }
+                }
+                output += temp;
+            }
+            return output;
+        }
+    }
+
+    void CommandExecutor::destroyExternalCommands()
+    {
+        for (std::set<ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandExternals_.begin();
+            it != CommandExecutor::getInstance().consoleCommandExternals_.end(); ++it)
+            delete *it;
+    }
+}
Index: code/trunk/src/libraries/core/CommandExecutor.h
===================================================================
--- code/trunk/src/libraries/core/CommandExecutor.h	(revision 5781)
+++ code/trunk/src/libraries/core/CommandExecutor.h	(revision 5781)
@@ -0,0 +1,114 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CommandExecutor_H__
+#define _CommandExecutor_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "util/MultiType.h"
+#include "CommandEvaluation.h"
+
+// tolua_begin
+namespace orxonox
+{
+    class _CoreExport CommandExecutor
+    {
+// tolua_end
+        public:
+            static bool execute(const std::string& command, bool useTcl = true); // tolua_export
+            static MultiType getReturnValue();
+            static std::string getReturnValueString(); // tolua_export
+
+            static std::string complete(const std::string& command);
+            static std::string hint(const std::string& command);
+
+            static CommandEvaluation evaluate(const std::string& command);
+            static const CommandEvaluation& getLastEvaluation();
+
+            static ConsoleCommand& addConsoleCommandShortcut(ConsoleCommand* command, bool bDeleteAtExit = false);
+            static ConsoleCommand* getConsoleCommandShortcut(const std::string& name);
+            static ConsoleCommand* getLowercaseConsoleCommandShortcut(const std::string& name);
+
+            /** @brief Returns the map that stores all console commands. @return The const_iterator */
+            static inline const std::map<std::string, ConsoleCommand*>& getConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_.end(); }
+
+            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            static inline const std::map<std::string, ConsoleCommand*>& getLowercaseConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end(); }
+
+            static void destroyExternalCommands();
+
+        private:
+            CommandExecutor() {}
+            CommandExecutor(const CommandExecutor& other);
+            ~CommandExecutor() {}
+
+            static CommandExecutor& getInstance();
+            static CommandEvaluation& getEvaluation();
+
+            static void parseIfNeeded(const std::string& command);
+            static void parse(const std::string& command, bool bInitialize = true);
+
+            static unsigned int argumentsFinished();
+            static unsigned int argumentsGiven();
+            static bool enoughArgumentsGiven(ConsoleCommand* command);
+            static std::string getArgument(unsigned int index);
+            static std::string getLastArgument();
+
+            static void createListOfPossibleIdentifiers(const std::string& fragment);
+            static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier = 0);
+            static void createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param);
+
+            static Identifier* getPossibleIdentifier(const std::string& name);
+            static ConsoleCommand* getPossibleCommand(const std::string& name, Identifier* identifier = 0);
+            static std::string getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param);
+
+            static void createArgumentCompletionList(ConsoleCommand* command, unsigned int param);
+            static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list);
+            static std::string getCommonBegin(const ArgumentCompletionList& list);
+
+            CommandEvaluation evaluation_;
+            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_;
+            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_LC_;
+            std::set<ConsoleCommand*>              consoleCommandExternals_;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _CommandExecutor_H__ */
Index: code/trunk/src/libraries/core/ConfigFileManager.cc
===================================================================
--- code/trunk/src/libraries/core/ConfigFileManager.cc	(revision 5774)
+++ code/trunk/src/libraries/core/ConfigFileManager.cc	(revision 5781)
@@ -34,4 +34,5 @@
 #include "util/Math.h"
 #include "util/StringUtils.h"
+#include "ConsoleCommand.h"
 #include "ConfigValueContainer.h"
 #include "Core.h"
@@ -39,4 +40,10 @@
 namespace orxonox
 {
+    SetConsoleCommandShortcutExtern(config).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
+    SetConsoleCommandShortcutExtern(tconfig).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
+    SetConsoleCommandShortcutExtern(reloadConfig);
+    SetConsoleCommandShortcutExtern(cleanConfig);
+    SetConsoleCommandShortcutExtern(loadSettings).argumentCompleter(0, autocompletion::files());
+
     bool config(const std::string& classname, const std::string& varname, const std::string& value)
     {
Index: code/trunk/src/libraries/core/ConsoleCommand.cc
===================================================================
--- code/trunk/src/libraries/core/ConsoleCommand.cc	(revision 5781)
+++ code/trunk/src/libraries/core/ConsoleCommand.cc	(revision 5781)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ConsoleCommand.h"
+
+namespace orxonox
+{
+    ConsoleCommand::ConsoleCommand(Functor* functor, const std::string& name) : Executor(functor, name)
+    {
+        this->accessLevel_ = AccessLevel::None;
+        this->argumentCompleter_[0] = 0;
+        this->argumentCompleter_[1] = 0;
+        this->argumentCompleter_[2] = 0;
+        this->argumentCompleter_[3] = 0;
+        this->argumentCompleter_[4] = 0;
+
+        this->keybindMode_ = KeybindMode::OnPress;
+        this->inputConfiguredParam_ = -1;
+    }
+
+    ConsoleCommand& ConsoleCommand::argumentCompleter(unsigned int param, ArgumentCompleter* completer)
+    {
+        if (param < 5)
+            this->argumentCompleter_[param] = completer;
+        else
+        {
+            COUT(2) << "Warning: Couldn't add autocompletion-function for param " << param << ": index out of bound." << std::endl;
+        }
+        return (*this);
+    }
+
+    ArgumentCompleter* ConsoleCommand::getArgumentCompleter(unsigned int param) const
+    {
+        if (param < 5)
+            return this->argumentCompleter_[param];
+        else
+            return 0;
+    }
+
+    void ConsoleCommand::createArgumentCompletionList(unsigned int param, const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5)
+    {
+        if (param < 5 && this->argumentCompleter_[param])
+            this->argumentList_ = (*this->argumentCompleter_[param])(param1, param2, param3, param4, param5);
+        else
+            this->argumentList_.clear();
+    }
+}
Index: code/trunk/src/libraries/core/ConsoleCommand.h
===================================================================
--- code/trunk/src/libraries/core/ConsoleCommand.h	(revision 5781)
+++ code/trunk/src/libraries/core/ConsoleCommand.h	(revision 5781)
@@ -0,0 +1,157 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ConsoleCommand_H__
+#define _ConsoleCommand_H__
+
+#include "CorePrereqs.h"
+
+#include <boost/preprocessor/cat.hpp>
+
+#include "ArgumentCompletionFunctions.h"
+#include "CommandExecutor.h"
+#include "Executor.h"
+#include "Identifier.h"
+
+
+#define SetConsoleCommand(classname, function, bCreateShortcut) \
+    SetConsoleCommandGeneric(classname, function, #function, bCreateShortcut)
+#define SetConsoleCommandAlias(classname, function, name, bCreateShortcut) \
+    SetConsoleCommandGeneric(classname, function, name, bCreateShortcut)
+
+#define SetConsoleCommandGeneric(classname, function, name, bCreateShortcut) \
+    orxonox::ConsoleCommand& BOOST_PP_CAT(classname##function##consolecommand__, __LINE__) = orxonox::ClassIdentifier<classname>::getIdentifier(#classname)->addConsoleCommand(orxonox::createConsoleCommand(orxonox::createFunctor(&classname::function), name), bCreateShortcut)
+
+
+#define SetConsoleCommandShortcut(classname, function) \
+    SetConsoleCommandShortcutAliasGeneric(classname, function, #function)
+#define SetConsoleCommandShortcutAlias(classname, function, name) \
+    SetConsoleCommandShortcutAliasGeneric(classname, function, name)
+#define SetConsoleCommandShortcutAliasGeneric(classname, function, name) \
+    SetConsoleCommandShortcutGeneric(BOOST_PP_CAT(function##consolecommand__, __LINE__), orxonox::createConsoleCommand(orxonox::createFunctor(&classname::function), name))
+
+#define SetConsoleCommandShortcutExtern(function) \
+    SetConsoleCommandShortcutExternAliasGeneric(function, #function)
+#define SetConsoleCommandShortcutExternAlias(function, name) \
+    SetConsoleCommandShortcutExternAliasGeneric(function, name)
+#define SetConsoleCommandShortcutExternAliasGeneric(function, name) \
+    SetConsoleCommandShortcutGeneric(BOOST_PP_CAT(function##consolecommand__, __LINE__), orxonox::createConsoleCommand(orxonox::createFunctor(&function), name))
+
+#define SetConsoleCommandShortcutGeneric(fakevariable, command) \
+    orxonox::ConsoleCommand& fakevariable = orxonox::CommandExecutor::addConsoleCommandShortcut(command, true)
+
+
+namespace orxonox
+{
+    namespace AccessLevel
+    {
+        enum Value
+        {
+            None,
+            User,
+            Admin,
+            Offline,
+            Debug,
+            Disabled
+        };
+    }
+
+    class _CoreExport ConsoleCommand : public Executor
+    {
+        public:
+            ConsoleCommand(Functor* functor, const std::string& name = "");
+
+            inline ConsoleCommand& description(const std::string& description)
+                { this->Executor::setDescription(description); return (*this); }
+            inline ConsoleCommand& descriptionParam(int param, const std::string& description)
+                { this->Executor::setDescriptionParam(param, description); return (*this); }
+            inline ConsoleCommand& descriptionReturnvalue(const std::string& description)
+                { this->Executor::setDescriptionReturnvalue(description); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1)
+                { this->Executor::setDefaultValues(param1); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2)
+                { this->Executor::setDefaultValues(param1, param2); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
+                { this->Executor::setDefaultValues(param1, param2, param3); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
+                { this->Executor::setDefaultValues(param1, param2, param3, param4); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
+                { this->Executor::setDefaultValues(param1, param2, param3, param4, param5); return (*this); }
+            inline ConsoleCommand& defaultValue(unsigned int index, const MultiType& param)
+                { this->Executor::setDefaultValue(index, param); return (*this); }
+
+            inline ConsoleCommand& accessLevel(AccessLevel::Value level)
+                { this->accessLevel_ = level; return (*this); }
+            inline AccessLevel::Value getAccessLevel() const
+                { return this->accessLevel_; }
+
+            ConsoleCommand& argumentCompleter(unsigned int param, ArgumentCompleter* completer);
+            ArgumentCompleter* getArgumentCompleter(unsigned int param) const;
+
+            void createArgumentCompletionList(unsigned int param, const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "");
+            const ArgumentCompletionList& getArgumentCompletionList() const
+                { return this->argumentList_; }
+            ArgumentCompletionList::const_iterator getArgumentCompletionListBegin() const
+                { return this->argumentList_.begin(); }
+            ArgumentCompletionList::const_iterator getArgumentCompletionListEnd() const
+                { return this->argumentList_.end(); }
+
+            inline ConsoleCommand& setAsInputCommand()
+            {
+                this->keybindMode(KeybindMode::OnHold);
+                this->defaultValue(0, Vector2(0.0f, 0.0f));
+                this->inputConfiguredParam(0);
+                return *this;
+            }
+
+            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
+                { this->keybindMode_ = mode; return *this; }
+            inline KeybindMode::Value getKeybindMode() const
+                { return this->keybindMode_; }
+
+            inline ConsoleCommand& inputConfiguredParam(int index)
+                { this->inputConfiguredParam_ = index; return *this; }
+            inline int getInputConfiguredParam_() const
+                { return this->inputConfiguredParam_; }
+
+        private:
+            AccessLevel::Value accessLevel_;
+            ArgumentCompleter* argumentCompleter_[5];
+            ArgumentCompletionList argumentList_;
+
+            KeybindMode::Value keybindMode_;
+            int inputConfiguredParam_;
+    };
+
+    inline ConsoleCommand* createConsoleCommand(Functor* functor, const std::string& name = "")
+    {
+        return new ConsoleCommand(functor, name);
+    }
+}
+
+#endif /* _ConsoleCommand_H__ */
Index: code/trunk/src/libraries/core/ConsoleCommandCompilation.cc
===================================================================
--- code/trunk/src/libraries/core/ConsoleCommandCompilation.cc	(revision 5781)
+++ code/trunk/src/libraries/core/ConsoleCommandCompilation.cc	(revision 5781)
@@ -0,0 +1,180 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ConsoleCommandCompilation.h"
+
+#include <fstream>
+#include <set>
+#include <string>
+
+#include "util/Debug.h"
+#include "util/ExprParser.h"
+#include "ConsoleCommand.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcutExtern(source).argumentCompleter(0, autocompletion::files());
+    SetConsoleCommandShortcutExtern(echo);
+    SetConsoleCommandShortcutExtern(puts);
+
+    SetConsoleCommandShortcutExtern(read).argumentCompleter(0, autocompletion::files());
+    SetConsoleCommandShortcutExtern(append).argumentCompleter(0, autocompletion::files());
+    SetConsoleCommandShortcutExtern(write).argumentCompleter(0, autocompletion::files());
+
+    SetConsoleCommandShortcutExtern(calculate);
+
+    void source(const std::string& filename)
+    {
+        static std::set<std::string> executingFiles;
+
+        std::set<std::string>::const_iterator it = executingFiles.find(filename);
+        if (it != executingFiles.end())
+        {
+            COUT(1) << "Error: Recurring source command in \"" << filename << "\". Stopped execution." << std::endl;
+            return;
+        }
+
+        // Open the file
+        std::ifstream file;
+        file.open(filename.c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        executingFiles.insert(filename);
+
+        // Iterate through the file and put the lines into the CommandExecutor
+        while (file.good() && !file.eof())
+        {
+            std::string line;
+            std::getline(file, line);
+            CommandExecutor::execute(line);
+        }
+
+        executingFiles.erase(filename);
+        file.close();
+    }
+
+    std::string echo(const std::string& text)
+    {
+        std::cout << text << std::endl;
+        return text;
+    }
+
+    void puts(bool newline, const std::string& text)
+    {
+        if (newline)
+        {
+            COUT(0) << stripEnclosingBraces(text) << std::endl;
+        }
+        else
+        {
+            COUT(0) << stripEnclosingBraces(text);
+        }
+    }
+
+    void write(const std::string& filename, const std::string& text)
+    {
+        std::ofstream file;
+        file.open(filename.c_str(), std::fstream::out);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't write to file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        file << text << std::endl;
+        file.close();
+    }
+
+    void append(const std::string& filename, const std::string& text)
+    {
+        std::ofstream file;
+        file.open(filename.c_str(), std::fstream::app);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't append to file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        file << text << std::endl;
+        file.close();
+    }
+
+    std::string read(const std::string& filename)
+    {
+        std::ifstream file;
+        file.open(filename.c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't read from file \"" << filename << "\"." << std::endl;
+            return "";
+        }
+
+        std::string output = "";
+        while (file.good() && !file.eof())
+        {
+            std::string line;
+            std::getline(file, line);
+            output += line;
+            output += "\n";
+        }
+
+        file.close();
+
+        return output;
+    }
+
+    float calculate(const std::string& calculation)
+    {
+        ExprParser expr(calculation);
+        if (expr.getSuccess())
+        {
+            if (expr.getResult() == 42.0)
+            {
+                COUT(3) << "Greetings from the restaurant at the end of the universe." << std::endl;
+            }
+            if (expr.getRemains() != "")
+            {
+                COUT(2) << "Warning: Expression could not be parsed to the end! Remains: '" << expr.getRemains() << "'" << std::endl;
+            }
+            return static_cast<float>(expr.getResult());
+        }
+        else
+        {
+            COUT(1) << "Error: Cannot calculate expression: Parse error." << std::endl;
+            return 0;
+        }
+    }
+}
Index: code/trunk/src/libraries/core/ConsoleCommandCompilation.h
===================================================================
--- code/trunk/src/libraries/core/ConsoleCommandCompilation.h	(revision 5781)
+++ code/trunk/src/libraries/core/ConsoleCommandCompilation.h	(revision 5781)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ConsoleCommandCompilation_H__
+#define _ConsoleCommandCompilation_H__
+
+#include "CorePrereqs.h"
+
+namespace orxonox
+{
+    _CoreExport void source(const std::string& filename);
+    _CoreExport std::string echo(const std::string& text);
+    _CoreExport void puts(bool newline, const std::string& test);
+
+    _CoreExport void write(const std::string& filename, const std::string& text);
+    _CoreExport void append(const std::string& filename, const std::string& text);
+    _CoreExport std::string read(const std::string& filename);
+
+    _CoreExport float calculate(const std::string& calculation);
+}
+
+#endif /* _ConsoleCommandCompilation_H__ */
Index: code/trunk/src/libraries/core/Core.cc
===================================================================
--- code/trunk/src/libraries/core/Core.cc	(revision 5774)
+++ code/trunk/src/libraries/core/Core.cc	(revision 5781)
@@ -63,4 +63,5 @@
 #include "util/SignalHandler.h"
 #include "Clock.h"
+#include "CommandExecutor.h"
 #include "CommandLine.h"
 #include "ConfigFileManager.h"
@@ -69,7 +70,14 @@
 #include "DynLibManager.h"
 #include "Factory.h"
+#include "GameMode.h"
+#include "GraphicsManager.h"
+#include "GUIManager.h"
 #include "Identifier.h"
 #include "Language.h"
 #include "LuaState.h"
+#include "Shell.h"
+#include "TclBind.h"
+#include "TclThreadManager.h"
+#include "input/InputManager.h"
 
 // Boost 1.36 has some issues with deprecated functions that have been omitted
@@ -109,4 +117,12 @@
             RegisterRootObject(CoreConfiguration);
             this->setConfigValues();
+
+            // External data directory only exists for dev runs
+            if (Core::isDevelopmentRun())
+            {
+                // Possible data path override by the command line
+                if (!CommandLine::getArgument("externalDataPath")->hasDefaultValue())
+                    tsetExternalDataPath(CommandLine::getValue("externalDataPath"));
+            }
         }
 
@@ -178,4 +194,15 @@
         }
 
+        /**
+        @brief
+            Temporary sets the external data path
+        @param path
+            The new data path
+        */
+        void tsetExternalDataPath(const std::string& path)
+        {
+            externalDataPath_ = boost::filesystem::path(path);
+        }
+
         void initializeRandomNumberGenerator()
         {
@@ -201,4 +228,5 @@
         boost::filesystem::path modulePath_;            //!< Path to the modules
         boost::filesystem::path dataPath_;              //!< Path to the data file folder
+        boost::filesystem::path externalDataPath_;      //!< Path to the external data file folder
         boost::filesystem::path configPath_;            //!< Path to the config file folder
         boost::filesystem::path logPath_;               //!< Path to the log file folder
@@ -209,6 +237,9 @@
         // Cleanup guard for identifier destruction (incl. XMLPort, configValues, consoleCommands)
         : identifierDestroyer_(Identifier::destroyAllIdentifiers)
+        // Cleanup guard for external console commands that don't belong to an Identifier
+        , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands)
         , configuration_(new CoreConfiguration()) // Don't yet create config values!
         , bDevRun_(false)
+        , bGraphicsLoaded_(false)
     {
         // Set the hard coded fixed paths
@@ -308,4 +339,14 @@
         // possibility to configure everything below here
         this->configuration_->initialise();
+
+        // Load OGRE excluding the renderer and the render window
+        this->graphicsManager_.reset(new GraphicsManager(false));
+
+        // initialise Tcl
+        this->tclBind_.reset(new TclBind(Core::getDataPathString()));
+        this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
+
+        // create a shell
+        this->shell_.reset(new Shell());
     }
 
@@ -316,4 +357,44 @@
     Core::~Core()
     {
+    }
+
+    void Core::loadGraphics()
+    {
+        // Any exception should trigger this, even in upgradeToGraphics (see its remarks)
+        Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics);
+
+        // Upgrade OGRE to receive a render window
+        graphicsManager_->upgradeToGraphics();
+
+        // Calls the InputManager which sets up the input devices.
+        inputManager_.reset(new InputManager());
+
+        // load the CEGUI interface
+        guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow(),
+            inputManager_->getMousePosition(), graphicsManager_->isFullScreen()));
+
+        unloader.Dismiss();
+
+        bGraphicsLoaded_ = true;
+    }
+
+    void Core::unloadGraphics()
+    {
+        this->guiManager_.reset();;
+        this->inputManager_.reset();;
+        this->graphicsManager_.reset();
+
+        // Load Ogre::Root again, but without the render system
+        try
+            { this->graphicsManager_.reset(new GraphicsManager(false)); }
+        catch (...)
+        {
+            COUT(0) << "An exception occurred during 'unloadGraphics':" << Exception::handleMessage() << std::endl
+                    << "Another exception might be being handled which may lead to undefined behaviour!" << std::endl
+                    << "Terminating the program." << std::endl;
+            abort();
+        }
+
+        bGraphicsLoaded_ = false;
     }
 
@@ -376,4 +457,9 @@
     }
 
+    /*static*/ void Core::tsetExternalDataPath(const std::string& path)
+    {
+        getInstance().configuration_->tsetExternalDataPath(path);
+    }
+
     /*static*/ const boost::filesystem::path& Core::getDataPath()
     {
@@ -383,4 +469,13 @@
     {
         return getInstance().configuration_->dataPath_.string() + '/';
+    }
+
+    /*static*/ const boost::filesystem::path& Core::getExternalDataPath()
+    {
+        return getInstance().configuration_->externalDataPath_;
+    }
+    /*static*/ std::string Core::getExternalDataPathString()
+    {
+        return getInstance().configuration_->externalDataPath_.string() + '/';
     }
 
@@ -564,4 +659,5 @@
         {
             configuration_->dataPath_  = specialConfig::dataDevDirectory;
+            configuration_->externalDataPath_ = specialConfig::externalDataDevDirectory;
             configuration_->configPath_ = specialConfig::configDevDirectory;
             configuration_->logPath_    = specialConfig::logDevDirectory;
@@ -629,8 +725,22 @@
     void Core::preUpdate(const Clock& time)
     {
+        if (this->bGraphicsLoaded_)
+        {
+            // process input events
+            this->inputManager_->update(time);
+            // process gui events
+            this->guiManager_->update(time);
+        }
+        // process thread commands
+        this->tclThreadManager_->update(time);
     }
 
     void Core::postUpdate(const Clock& time)
     {
+        if (this->bGraphicsLoaded_)
+        {
+            // Render (doesn't throw)
+            this->graphicsManager_->update(time);
+        }
     }
 }
Index: code/trunk/src/libraries/core/Core.h
===================================================================
--- code/trunk/src/libraries/core/Core.h	(revision 5774)
+++ code/trunk/src/libraries/core/Core.h	(revision 5781)
@@ -85,6 +85,9 @@
             static void  resetLanguage();
 
+            static void tsetExternalDataPath(const std::string& path);
             //! Returns the path to the data files as boost::filesystem::path
             static const boost::filesystem::path& getDataPath();
+            //! Returns the path to the external data files as boost::filesystem::path
+            static const boost::filesystem::path& getExternalDataPath();
             //! Returns the path to the config files as boost::filesystem::path
             static const boost::filesystem::path& getConfigPath();
@@ -95,4 +98,6 @@
             //! Returns the path to the data files as std::string
             static std::string getDataPathString();
+            //! Returns the path to the external data files as std::string
+            static std::string getExternalDataPathString();
             //! Returns the path to the config files as std::string
             static std::string getConfigPathString();
@@ -110,4 +115,7 @@
             void postUpdate(const Clock& time);
 
+            void loadGraphics();
+            void unloadGraphics();
+
             void setFixedPaths();
             void setConfigurablePaths();
@@ -118,9 +126,18 @@
             scoped_ptr<SignalHandler>     signalHandler_;
             SimpleScopeGuard              identifierDestroyer_;
+            SimpleScopeGuard              consoleCommandDestroyer_;
             scoped_ptr<ConfigFileManager> configFileManager_;
             scoped_ptr<Language>          languageInstance_;
             scoped_ptr<CoreConfiguration> configuration_;
+            scoped_ptr<TclBind>           tclBind_;
+            scoped_ptr<TclThreadManager>  tclThreadManager_;
+            scoped_ptr<Shell>             shell_;
+            // graphical
+            scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
+            scoped_ptr<InputManager>      inputManager_;        //!< Interface to OIS
+            scoped_ptr<GUIManager>        guiManager_;          //!< Interface to GUI
 
             bool                          bDevRun_;             //!< True for runs in the build directory (not installed)
+            bool                          bGraphicsLoaded_;
 
             static Core* singletonPtr_s;
Index: code/trunk/src/libraries/core/CoreIncludes.h
===================================================================
--- code/trunk/src/libraries/core/CoreIncludes.h	(revision 5774)
+++ code/trunk/src/libraries/core/CoreIncludes.h	(revision 5781)
@@ -80,5 +80,12 @@
 */
 #define CreateFactory(ClassName) \
-    bool bCreated##ClassName##Factory = orxonox::ClassFactory<ClassName>::create(#ClassName)
+    bool bCreated##ClassName##Factory = orxonox::ClassFactory<ClassName>::create(#ClassName, true)
+
+/**
+    @brief Creates the entry in the Factory for classes which should not be loaded through XML.
+    @param ClassName The name of the class
+*/
+#define CreateUnloadableFactory(ClassName) \
+    bool bCreated##ClassName##Factory = orxonox::ClassFactory<ClassName>::create(#ClassName, false)
 
 /**
Index: code/trunk/src/libraries/core/CorePrecompiledHeaders.h
===================================================================
--- code/trunk/src/libraries/core/CorePrecompiledHeaders.h	(revision 5774)
+++ code/trunk/src/libraries/core/CorePrecompiledHeaders.h	(revision 5781)
@@ -70,4 +70,8 @@
 #ifdef ORXONOX_COMPILER_MSVC
 
+#include <ois/OISKeyboard.h> // 15
+#include <ois/OISMouse.h>    // 15
+#include <ois/OISJoyStick.h> // 15
+
 #include "util/SubString.h"  // 14
 
Index: code/trunk/src/libraries/core/Event.cc
===================================================================
--- code/trunk/src/libraries/core/Event.cc	(revision 5781)
+++ code/trunk/src/libraries/core/Event.cc	(revision 5781)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Event.h"
+
+#include "BaseObject.h"
+#include "Executor.h"
+
+namespace orxonox
+{
+    EventContainer::~EventContainer()
+    {
+        delete this->eventfunction_;
+    }
+
+    void EventContainer::process(BaseObject* object, const Event& event)
+    {
+        if (this->bActive_)
+        {
+            COUT(2) << "Warning: Detected Event loop in section \"" << this->eventname_ << "\" of object \"" << object->getName() << "\" and fired by \"" << event.originator_->getName() << "\"" << std::endl;
+            return;
+        }
+
+        this->bActive_ = true;
+
+        if (this->eventname_ == event.sectionname_)
+        {
+            if (event.originator_->isA(this->subclass_))
+            {
+                if (event.activate_)
+                    ++this->activeEvents_;
+                else
+                {
+                    --this->activeEvents_;
+
+                    if (this->activeEvents_ < 0)
+                        this->activeEvents_ = 0;
+                }
+
+                if (this->eventfunction_->getParamCount() == 0 && event.activate_)
+                    (*this->eventfunction_)();
+                else if ((this->activeEvents_ == 1 && event.activate_) || (this->activeEvents_ == 0 && !event.activate_))
+                {
+                    if (this->eventfunction_->getParamCount() == 1)
+                        (*this->eventfunction_)(this->activeEvents_);
+                    else if (this->eventfunction_->getParamCount() >= 2 && event.castedOriginator_)
+                        (*this->eventfunction_)(this->activeEvents_, event.castedOriginator_);
+                }
+            }
+        }
+
+        this->bActive_ = false;
+    }
+}
Index: code/trunk/src/libraries/core/Event.h
===================================================================
--- code/trunk/src/libraries/core/Event.h	(revision 5781)
+++ code/trunk/src/libraries/core/Event.h	(revision 5781)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Event_H__
+#define _Event_H__
+
+#include "CorePrereqs.h"
+#include <string>
+
+namespace orxonox
+{
+    struct _CoreExport Event
+    {
+            Event(bool activate, BaseObject* originator) : activate_(activate), originator_(originator), castedOriginator_(0) {}
+
+            bool        activate_;
+            BaseObject* originator_;
+            void*       castedOriginator_;
+            std::string sectionname_;
+    };
+
+    class _CoreExport EventContainer
+    {
+        public:
+            EventContainer(const std::string& eventname, Executor* eventfunction, Identifier* subclass) : bActive_(false), eventname_(eventname), eventfunction_(eventfunction), subclass_(subclass), activeEvents_(0) {}
+            virtual ~EventContainer();
+
+            void process(BaseObject* object, const Event& event);
+
+        private:
+            bool bActive_;
+            std::string eventname_;
+            Executor* eventfunction_;
+            Identifier* subclass_;
+
+            int activeEvents_;
+    };
+}
+
+#endif /* _Event_H__ */
Index: code/trunk/src/libraries/core/EventIncludes.h
===================================================================
--- code/trunk/src/libraries/core/EventIncludes.h	(revision 5781)
+++ code/trunk/src/libraries/core/EventIncludes.h	(revision 5781)
@@ -0,0 +1,71 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventIncludes_H__
+#define _EventIncludes_H__
+
+#include "CorePrereqs.h"
+#include "Executor.h"
+
+#define ORXONOX_SET_EVENT(classname, eventname, functionname, event) \
+    ORXONOX_SET_EVENT_GENERIC(eventcontainer##classname##functionname, classname, eventname, functionname, event, BaseObject)
+
+#define ORXONOX_SET_EVENT_TEMPLATE(classname, eventname, functionname, event, ...) \
+    ORXONOX_SET_EVENT_GENERIC_TEMPLATE(eventcontainer##classname##functionname, classname, eventname, functionname, event, BaseObject, __VA_ARGS__)
+
+#define ORXONOX_SET_SUBCLASS_EVENT(classname, eventname, functionname, event, subclassname) \
+    ORXONOX_SET_EVENT_GENERIC(eventcontainer##classname##functionname, classname, eventname, functionname, event, subclassname)
+
+#define ORXONOX_SET_SUBCLASS_EVENT_TEMPLATE(classname, eventname, functionname, event, subclassname, ...) \
+    ORXONOX_SET_EVENT_GENERIC_TEMPLATE(eventcontainer##classname##functionname, classname, eventname, functionname, event, subclassname, __VA_ARGS__)
+
+#define ORXONOX_SET_EVENT_GENERIC(containername, classname, eventname, functionname, event, subclassname) \
+    orxonox::EventContainer* containername = this->getEventContainer(eventname); \
+    if (!containername) \
+    { \
+        ExecutorMember<classname>* executor = orxonox::createExecutor(orxonox::createFunctor(&classname::functionname), std::string( #classname ) + "::" + #functionname); \
+        executor->setObject(this); \
+        containername = new orxonox::EventContainer(std::string(eventname), executor, orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
+        this->addEventContainer(eventname, containername); \
+    } \
+    event.castedOriginator_ = orxonox::orxonox_cast<subclassname*>(event.originator_); \
+    containername->process(this, event)
+
+#define ORXONOX_SET_EVENT_GENERIC_TEMPLATE(containername, classname, eventname, functionname, event, subclassname, ...) \
+    orxonox::EventContainer* containername = this->getEventContainer(eventname); \
+    if (!containername) \
+    { \
+        ExecutorMember<classname>* executor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::functionname), std::string( #classname ) + "::" + #functionname); \
+        executor->setObject(this); \
+        containername = new orxonox::EventContainer(std::string(eventname), executor, orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
+        this->addEventContainer(eventname, containername); \
+    } \
+    event.castedOriginator_ = orxonox::orxonox_cast<subclassname*>(event.originator_); \
+    containername->process(this, event)
+
+#endif /* _EventIncludes_H__ */
Index: code/trunk/src/libraries/core/Factory.cc
===================================================================
--- code/trunk/src/libraries/core/Factory.cc	(revision 5774)
+++ code/trunk/src/libraries/core/Factory.cc	(revision 5781)
@@ -55,4 +55,18 @@
 
     /**
+        @brief Returns the Identifier with a given network ID.
+        @param id The network ID of the wanted Identifier
+        @return The Identifier
+    */
+    Identifier* Factory::getIdentifier(const uint32_t id)
+    {
+        std::map<uint32_t, Identifier*>::const_iterator it = getFactoryPointer()->identifierNetworkIDMap_.find(id);
+        if (it != getFactoryPointer()->identifierNetworkIDMap_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
         @brief Adds a new Identifier to both maps.
         @param name The name of the identifier
@@ -62,4 +76,25 @@
     {
         getFactoryPointer()->identifierStringMap_[name] = identifier;
+        getFactoryPointer()->identifierNetworkIDMap_[identifier->getNetworkID()] = identifier;
+    }
+
+    /**
+        @brief Removes the entry with the old network ID and adds a new one.
+        @param identifier The identifier to change
+        @param oldID The old networkID
+        @param newID The new networkID
+    */
+    void Factory::changeNetworkID(Identifier* identifier, const uint32_t oldID, const uint32_t newID)
+    {
+//        getFactoryPointer()->identifierNetworkIDMap_.erase(oldID);
+        getFactoryPointer()->identifierNetworkIDMap_[newID] = identifier;
+    }
+
+    /**
+        @brief Cleans the NetworkID map (needed on clients for correct initialization)
+    */
+    void Factory::cleanNetworkIDs()
+    {
+        getFactoryPointer()->identifierNetworkIDMap_.clear();
     }
 
Index: code/trunk/src/libraries/core/Factory.h
===================================================================
--- code/trunk/src/libraries/core/Factory.h	(revision 5774)
+++ code/trunk/src/libraries/core/Factory.h	(revision 5781)
@@ -62,4 +62,6 @@
             static Identifier* getIdentifier(const uint32_t id);
             static void add(const std::string& name, Identifier* identifier);
+            static void changeNetworkID(Identifier* identifier, const uint32_t oldID, const uint32_t newID);
+            static void cleanNetworkIDs();
             static void createClassHierarchy();
 
@@ -82,4 +84,5 @@
 
             std::map<std::string, Identifier*> identifierStringMap_;            //!< The map, mapping the name with the Identifier
+            std::map<uint32_t, Identifier*> identifierNetworkIDMap_;        //!< The map, mapping the network ID with the Identifier
     };
 
Index: code/trunk/src/libraries/core/GUIManager.cc
===================================================================
--- code/trunk/src/libraries/core/GUIManager.cc	(revision 5781)
+++ code/trunk/src/libraries/core/GUIManager.cc	(revision 5781)
@@ -0,0 +1,304 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GUIManager.h"
+
+#include <memory>
+extern "C" {
+#include <lua.h>
+}
+#include <CEGUIDefaultLogger.h>
+#include <CEGUIExceptions.h>
+#include <CEGUIInputEvent.h>
+#include <CEGUIMouseCursor.h>
+#include <CEGUIResourceProvider.h>
+#include <CEGUISystem.h>
+#include <ogreceguirenderer/OgreCEGUIRenderer.h>
+
+#include "SpecialConfig.h" // Configures the macro below
+#ifdef CEGUILUA_USE_INTERNAL_LIBRARY
+#   include <ceguilua/CEGUILua.h>
+#else
+#   include <CEGUILua.h>
+#endif
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/OrxAssert.h"
+#include "Core.h"
+#include "Clock.h"
+#include "LuaState.h"
+#include "Resource.h"
+
+namespace orxonox
+{
+    class CEGUILogger : public CEGUI::DefaultLogger
+    {
+    public:
+	    void logEvent(const CEGUI::String& message, CEGUI::LoggingLevel level = CEGUI::Standard)
+        {
+            int orxonoxLevel = CEGUI::Standard;
+            switch (level)
+            {
+                case CEGUI::Errors:      orxonoxLevel = 1; break;
+                case CEGUI::Warnings:    orxonoxLevel = 2; break;
+                case CEGUI::Standard:    orxonoxLevel = 4; break;
+                case CEGUI::Informative: orxonoxLevel = 5; break;
+                case CEGUI::Insane:      orxonoxLevel = 6; break;
+                default: OrxAssert(false, "CEGUI log level out of range, inpect immediately!");
+            }
+            OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
+                << "CEGUI: " << message << std::endl;
+
+            CEGUI::DefaultLogger::logEvent(message, level);
+        }
+    };
+
+    static CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button);
+
+    GUIManager* GUIManager::singletonPtr_s = 0;
+
+    /**
+    @brief
+        Constructs the GUIManager by starting up CEGUI
+
+        Creates the interface to Ogre, sets up the CEGUI renderer and the Lua script module together with the Lua engine.
+        The log is set up and connected to the CEGUILogger.
+        After Lua setup tolua++-elements are linked to Lua-state to give Lua access to C++-code.
+        Finally initial Lua code is executed (maybe we can do this with the CEGUI startup script automatically).
+    @param renderWindow
+        Ogre's render window. Without this, the GUI cannot be displayed.
+    @return true if success, otherwise false
+    */
+    GUIManager::GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen)
+        : renderWindow_(renderWindow)
+        , resourceProvider_(0)
+    {
+        using namespace CEGUI;
+
+        COUT(3) << "Initialising CEGUI." << std::endl;
+
+        // Note: No SceneManager specified yet
+        guiRenderer_.reset(new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
+        resourceProvider_ = guiRenderer_->createResourceProvider();
+        resourceProvider_->setDefaultResourceGroup("GUI");
+
+        // setup scripting
+        luaState_.reset(new LuaState());
+        scriptModule_.reset(new LuaScriptModule(luaState_->getInternalLuaState()));
+
+        // Create our own logger to specify the filepath
+        std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
+        ceguiLogger->setLogFilename(Core::getLogPathString() + "cegui.log");
+        // set the log level according to ours (translate by subtracting 1)
+        ceguiLogger->setLoggingLevel(
+            static_cast<LoggingLevel>(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
+        this->ceguiLogger_ = ceguiLogger.release();
+
+        // create the CEGUI system singleton
+        guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
+
+        // Initialise the basic lua code
+        rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua", "GUI");
+        this->luaState_->doFile("InitialiseGUI.lua", "GUI", false);
+
+        // Align CEGUI mouse with OIS mouse
+        guiSystem_->injectMousePosition(mousePosition.first, mousePosition.second);
+
+        // Hide the mouse cursor unless playing in fullscreen mode
+        if (!bFullScreen)
+            CEGUI::MouseCursor::getSingleton().hide();
+    }
+
+    /**
+    @brief
+        Basically shuts down CEGUI (member smart pointers) but first unloads our Tolua modules.
+    */
+    GUIManager::~GUIManager()
+    {
+    }
+
+    /**
+    @brief
+        used to tick the GUI
+    @param time
+        clock which provides time value for the GUI System
+
+        Ticking the GUI means updating it with a certain regularity.
+        The elapsed time since the last call is given in the time value provided by the clock.
+        This time value is then used to provide a fluent animation of the GUI.
+    */
+    void GUIManager::update(const Clock& time)
+    {
+        assert(guiSystem_);
+        guiSystem_->injectTimePulse(time.getDeltaTime());
+    }
+
+    /**
+    @brief
+        Tells the GUIManager which SceneManager to use
+    @param camera
+        The current camera on which the GUI should be displayed on.
+
+        In fact the GUIManager needs the SceneManager and not the Camera to display the GUI.
+        This means the GUI is not bound to a camera but rather to the SceneManager.
+        Hiding the GUI when needed can therefore not be resolved by just NOT setting the current camera.
+    */
+    void GUIManager::setCamera(Ogre::Camera* camera)
+    {
+        if (camera == NULL)
+            this->guiRenderer_->setTargetSceneManager(0);
+        else
+            this->guiRenderer_->setTargetSceneManager(camera->getSceneManager());
+    }
+
+    /**
+    @brief
+        Executes Lua code
+    @param str
+        reference to string object holding the Lua code which is to be executed
+
+        This function gives total access to the GUI. You can execute ANY Lua code here.
+    */
+    void GUIManager::executeCode(const std::string& str)
+    {
+        this->luaState_->doString(str, rootFileInfo_);
+    }
+
+    /**
+    @brief
+        Displays specified GUI on screen
+    @param name
+        The name of the GUI
+
+        The function executes the Lua function with the same name in case the GUIManager is ready.
+        For more details check out loadGUI_2.lua where the function presides.
+    */
+    void GUIManager::showGUI(const std::string& name)
+    {
+        this->luaState_->doString("showGUI(\"" + name + "\")", rootFileInfo_);
+    }
+
+    void GUIManager::keyPressed(const KeyEvent& evt)
+    {
+        guiSystem_->injectKeyDown(evt.getKeyCode());
+        guiSystem_->injectChar(evt.getText());
+    }
+    void GUIManager::keyReleased(const KeyEvent& evt)
+    {
+        guiSystem_->injectKeyUp(evt.getKeyCode());
+    }
+
+    /**
+    @brief
+        Function receiving a mouse button pressed event.
+    @param id
+        ID of the mouse button which got pressed
+
+        This function is inherited by MouseHandler and injects the event into CEGUI.
+        It is for CEGUI to process the event.
+    */
+    void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
+    {
+        try
+        {
+            guiSystem_->injectMouseButtonDown(convertButton(id));
+        }
+        catch (CEGUI::ScriptException& ex)
+        {
+            // We simply ignore the exception and proceed
+            COUT(1) << ex.getMessage() << std::endl;
+        }
+    }
+
+    /**
+    @brief
+        Function receiving a mouse button released event.
+    @param id
+        ID of the mouse button which got released
+
+        This function is inherited by MouseHandler and injects the event into CEGUI.
+        It is for CEGUI to process the event.
+    */
+    void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
+    {
+        try
+        {
+            guiSystem_->injectMouseButtonUp(convertButton(id));
+        }
+        catch (CEGUI::ScriptException& ex)
+        {
+            // We simply ignore the exception and proceed
+            COUT(1) << ex.getMessage() << std::endl;
+        }
+    }
+
+    void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        guiSystem_->injectMousePosition(static_cast<float>(abs.x), static_cast<float>(abs.y));
+    }
+    void GUIManager::mouseScrolled(int abs, int rel)
+    {
+        guiSystem_->injectMouseWheelChange(static_cast<float>(rel));
+    }
+
+    /**
+    @brief
+        converts mouse event code to CEGUI event code
+    @param button
+        code of the mouse button as we use it in Orxonox
+    @return
+        code of the mouse button as it is used by CEGUI
+
+        Simple convertion from mouse event code in Orxonox to the one used in CEGUI.
+     */
+    static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
+    {
+        switch (button)
+        {
+        case MouseButtonCode::Left:
+            return CEGUI::LeftButton;
+
+        case MouseButtonCode::Right:
+            return CEGUI::RightButton;
+
+        case MouseButtonCode::Middle:
+            return CEGUI::MiddleButton;
+
+        case MouseButtonCode::Button3:
+            return CEGUI::X1Button;
+
+        case MouseButtonCode::Button4:
+            return CEGUI::X2Button;
+
+        default:
+            return CEGUI::NoButton;
+        }
+    }
+}
Index: code/trunk/src/libraries/core/GUIManager.h
===================================================================
--- code/trunk/src/libraries/core/GUIManager.h	(revision 5781)
+++ code/trunk/src/libraries/core/GUIManager.h	(revision 5781)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GUIManager_H__
+#define _GUIManager_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include <CEGUIForwardRefs.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "util/OgreForwardRefs.h"
+#include "util/Singleton.h"
+#include "input/InputHandler.h"
+
+namespace orxonox
+{
+    class PlayerInfo; // Forward declaration
+
+    /**
+    @class GUIManager
+    @brief
+        Provides a simple interface to CEGUI with tolua methods and console commands. It also acts as a key and mouse handler.
+
+        The GUIManager is a singleton and can be called anywhere when access on the GUI is needed.
+        Creation of the GUIManager is therefore not possible and the cunstructor is private.
+
+        Since the GUI needs user input, the GUIManager implements the functions needed to act as a key and/or mouse handler.
+        Those input events are then injected into CEGUI in Lua.
+    */
+    class _CoreExport GUIManager : public Singleton<GUIManager>, public InputHandler
+    {
+        friend class Singleton<GUIManager>;
+    public:
+        GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen);
+        ~GUIManager();
+
+        void update(const Clock& time);
+
+        void showGUI(const std::string& name);
+        void executeCode(const std::string& str);
+
+        void setCamera(Ogre::Camera* camera);
+
+        static GUIManager* getInstancePtr() { return singletonPtr_s; }
+
+        inline void setPlayer(const std::string& guiname, PlayerInfo* player)
+            { this->players_[guiname] = player; }
+        inline PlayerInfo* getPlayer(const std::string& guiname) const
+            { std::map<std::string, PlayerInfo*>::const_iterator it = this->players_.find(guiname); return (it != this->players_.end()) ? it->second : 0; }
+
+    private:
+        GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
+
+        // keyHandler functions
+        void keyPressed (const KeyEvent& evt);
+        void keyReleased(const KeyEvent& evt);
+
+        // mouseHandler functions
+        void buttonPressed (MouseButtonCode::ByEnum id);
+        void buttonReleased(MouseButtonCode::ByEnum id);
+        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled (int abs, int rel);
+
+        scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_;      //!< CEGUI's interface to the Ogre Engine
+        scoped_ptr<LuaState>                 luaState_;         //!< LuaState, access point to the Lua engine
+        scoped_ptr<CEGUI::LuaScriptModule>   scriptModule_;     //!< CEGUI's script module to use Lua
+        scoped_ptr<CEGUI::System>            guiSystem_;        //!< CEGUI's main system
+        shared_ptr<ResourceInfo>             rootFileInfo_;     //!< Resource information about the root script
+        Ogre::RenderWindow*                  renderWindow_;     //!< Ogre's render window to give CEGUI access to it
+        CEGUI::ResourceProvider*             resourceProvider_; //!< CEGUI's resource provider
+        CEGUI::Logger*                       ceguiLogger_;      //!< CEGUI's logger to be able to log CEGUI errors in our log
+        std::map<std::string, PlayerInfo*>   players_;          //!< Stores the player (owner) for each gui
+
+        static GUIManager*                   singletonPtr_s;    //!< Singleton reference to GUIManager
+
+    };
+}
+
+#endif /* _GUIManager_H__ */
Index: code/trunk/src/libraries/core/Game.cc
===================================================================
--- code/trunk/src/libraries/core/Game.cc	(revision 5774)
+++ code/trunk/src/libraries/core/Game.cc	(revision 5781)
@@ -45,11 +45,17 @@
 #include "Clock.h"
 #include "CommandLine.h"
+#include "ConsoleCommand.h"
 #include "Core.h"
 #include "CoreIncludes.h"
 #include "ConfigValueIncludes.h"
+#include "GameMode.h"
 #include "GameState.h"
 
 namespace orxonox
 {
+    static void stop_game()
+        { Game::getInstance().stop(); }
+    SetConsoleCommandShortcutExternAlias(stop_game, "exit");
+
     std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
     Game* Game::singletonPtr_s = 0;
@@ -500,8 +506,43 @@
     void Game::loadGraphics()
     {
+        if (!GameMode::bShowsGraphics_s)
+        {
+            core_->loadGraphics();
+            Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
+            GameMode::bShowsGraphics_s = true;
+
+            // Construct all the GameStates that require graphics
+            for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
+                it != gameStateDeclarations_s.end(); ++it)
+            {
+                if (it->second.bGraphicsMode)
+                {
+                    // Game state loading failure is serious --> don't catch
+                    shared_ptr<GameState> gameState = GameStateFactory::fabricate(it->second);
+                    if (!constructedStates_.insert(std::make_pair(
+                        it->second.stateName, gameState)).second)
+                        assert(false); // GameState was already created!
+                }
+            }
+            graphicsUnloader.Dismiss();
+        }
     }
 
     void Game::unloadGraphics()
     {
+        if (GameMode::bShowsGraphics_s)
+        {
+            // Destroy all the GameStates that require graphics
+            for (GameStateMap::iterator it = constructedStates_.begin(); it != constructedStates_.end();)
+            {
+                if (it->second->getInfo().bGraphicsMode)
+                    constructedStates_.erase(it++);
+                else
+                    ++it;
+            }
+
+            core_->unloadGraphics();
+            GameMode::bShowsGraphics_s = false;
+        }
     }
 
@@ -522,5 +563,5 @@
         // If state requires graphics, load it
         Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
-        if (gameStateDeclarations_s[name].bGraphicsMode)
+        if (gameStateDeclarations_s[name].bGraphicsMode && !GameMode::showsGraphics())
             this->loadGraphics();
         else
Index: code/trunk/src/libraries/core/GameMode.cc
===================================================================
--- code/trunk/src/libraries/core/GameMode.cc	(revision 5781)
+++ code/trunk/src/libraries/core/GameMode.cc	(revision 5781)
@@ -0,0 +1,43 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the GameMode class.
+*/
+
+#include "GameMode.h"
+
+namespace orxonox
+{
+    bool GameMode::bShowsGraphics_s = false;
+    bool GameMode::bHasServer_s     = false;
+    bool GameMode::bIsClient_s      = false;
+    bool GameMode::bIsStandalone_s  = false;
+    bool GameMode::bIsMaster_s      = false;
+}
Index: code/trunk/src/libraries/core/GameMode.h
===================================================================
--- code/trunk/src/libraries/core/GameMode.h	(revision 5781)
+++ code/trunk/src/libraries/core/GameMode.h	(revision 5781)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the GameMode class.
+*/
+
+#ifndef _GameMode_H__
+#define _GameMode_H__
+
+#include "CorePrereqs.h"
+
+namespace orxonox
+{
+    class _CoreExport GameMode
+    {
+        friend class Game;
+
+        public:
+            static bool showsGraphics() { return bShowsGraphics_s; }
+            static bool hasServer()     { return bHasServer_s; }
+            static bool isClient()      { return bIsClient_s; }
+            static bool isStandalone()  { return bIsStandalone_s; }
+            static bool isMaster()      { return bIsMaster_s; }
+
+            static void setHasServer    (bool val) { bHasServer_s     = val; updateIsMaster(); }
+            static void setIsClient     (bool val) { bIsClient_s      = val; updateIsMaster(); }
+            static void setIsStandalone (bool val) { bIsStandalone_s  = val; updateIsMaster(); }
+
+        private:
+            GameMode();
+            GameMode(const GameMode& inst);
+            ~GameMode();
+
+            static void updateIsMaster()
+            {
+                bIsMaster_s = (bHasServer_s || bIsStandalone_s);
+            }
+
+            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
+            static bool bHasServer_s;                       //!< global variable that tells whether this is a server
+            static bool bIsClient_s;
+            static bool bIsStandalone_s;
+            static bool bIsMaster_s;
+    };
+}
+
+#endif /* _GameMode_H__ */
Index: code/trunk/src/libraries/core/GraphicsManager.cc
===================================================================
--- code/trunk/src/libraries/core/GraphicsManager.cc	(revision 5781)
+++ code/trunk/src/libraries/core/GraphicsManager.cc	(revision 5781)
@@ -0,0 +1,422 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *   Co-authors:
+ *      Felix Schulthess
+ *
+ */
+
+#include "GraphicsManager.h"
+
+#include <fstream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+#include <boost/shared_array.hpp>
+
+#include <OgreArchiveFactory.h>
+#include <OgreArchiveManager.h>
+#include <OgreFrameListener.h>
+#include <OgreRoot.h>
+#include <OgreLogManager.h>
+#include <OgreRenderWindow.h>
+#include <OgreRenderSystem.h>
+#include <OgreResourceGroupManager.h>
+#include <OgreTextureManager.h>
+#include <OgreViewport.h>
+#include <OgreWindowEventUtilities.h>
+
+#include "SpecialConfig.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "util/SubString.h"
+#include "Clock.h"
+#include "ConsoleCommand.h"
+#include "ConfigValueIncludes.h"
+#include "CoreIncludes.h"
+#include "Core.h"
+#include "Game.h"
+#include "GameMode.h"
+#include "Loader.h"
+#include "MemoryArchive.h"
+#include "WindowEventListener.h"
+#include "XMLFile.h"
+
+namespace orxonox
+{
+    class OgreWindowEventListener : public Ogre::WindowEventListener
+    {
+    public:
+        void windowResized     (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::resizeWindow(rw->getWidth(), rw->getHeight()); }
+        void windowFocusChange (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::changeWindowFocus(); }
+        void windowClosed      (Ogre::RenderWindow* rw)
+            { orxonox::Game::getInstance().stop(); }
+        void windowMoved       (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::moveWindow(); }
+    };
+
+    GraphicsManager* GraphicsManager::singletonPtr_s = 0;
+
+    /**
+    @brief
+        Non-initialising constructor.
+    */
+    GraphicsManager::GraphicsManager(bool bLoadRenderer)
+        : ogreWindowEventListener_(new OgreWindowEventListener())
+#if OGRE_VERSION < 0x010600
+        , memoryArchiveFactory_(new MemoryArchiveFactory())
+#endif
+        , renderWindow_(0)
+        , viewport_(0)
+    {
+        RegisterObject(GraphicsManager);
+
+        this->setConfigValues();
+
+        // Ogre setup procedure (creating Ogre::Root)
+        this->loadOgreRoot();
+        // load all the required plugins for Ogre
+        this->loadOgrePlugins();
+
+        // At first, add the root paths of the data directories as resource locations
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(Core::getDataPathString(), "FileSystem", "dataRoot", false);
+        // Load resources
+        resources_.reset(new XMLFile("resources.oxr", "dataRoot"));
+        resources_->setLuaSupport(false);
+        Loader::open(resources_.get());
+
+        // Only for development runs
+        if (Core::isDevelopmentRun())
+        {
+            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(Core::getExternalDataPathString(), "FileSystem", "externalDataRoot", false);
+            extResources_.reset(new XMLFile("resources.oxr", "externalDataRoot"));
+            extResources_->setLuaSupport(false);
+            Loader::open(extResources_.get());
+        }
+
+        if (bLoadRenderer)
+        {
+            // Reads the ogre config and creates the render window
+            this->upgradeToGraphics();
+        }
+    }
+
+    /**
+    @brief
+        Destruction is done by the member scoped_ptrs.
+    */
+    GraphicsManager::~GraphicsManager()
+    {
+        Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_.get());
+        // TODO: Destroy the console command
+    }
+
+    void GraphicsManager::setConfigValues()
+    {
+        SetConfigValue(ogreConfigFile_,  "ogre.cfg")
+            .description("Location of the Ogre config file");
+        SetConfigValue(ogrePluginsDirectory_, specialConfig::ogrePluginsDirectory)
+            .description("Folder where the Ogre plugins are located.");
+        SetConfigValue(ogrePlugins_, specialConfig::ogrePlugins)
+            .description("Comma separated list of all plugins to load.");
+        SetConfigValue(ogreLogFile_,     "ogre.log")
+            .description("Logfile for messages from Ogre. Use \"\" to suppress log file creation.");
+        SetConfigValue(ogreLogLevelTrivial_ , 5)
+            .description("Corresponding orxonox debug level for ogre Trivial");
+        SetConfigValue(ogreLogLevelNormal_  , 4)
+            .description("Corresponding orxonox debug level for ogre Normal");
+        SetConfigValue(ogreLogLevelCritical_, 2)
+            .description("Corresponding orxonox debug level for ogre Critical");
+    }
+
+    /**
+    @brief
+        Loads the renderer and creates the render window if not yet done so.
+    @remarks
+        This operation is irreversible without recreating the GraphicsManager!
+        So if it throws you HAVE to recreate the GraphicsManager!!!
+        It therefore offers almost no exception safety.
+    */
+    void GraphicsManager::upgradeToGraphics()
+    {
+        if (renderWindow_ != NULL)
+            return;
+
+        this->loadRenderer();
+
+#if OGRE_VERSION < 0x010600
+        // WORKAROUND: There is an incompatibility for particle scripts when trying
+        // to support both Ogre 1.4 and 1.6. The hacky solution is to create
+        // scripts for the 1.6 version and then remove the inserted "particle_system"
+        // keyword. But we need to supply these new scripts as well, which is why
+        // there is an extra Ogre::Archive dealing with it in the memory.
+        using namespace Ogre;
+        ArchiveManager::getSingleton().addArchiveFactory(memoryArchiveFactory_.get());
+        const StringVector& groups = ResourceGroupManager::getSingleton().getResourceGroups();
+        // Travers all groups
+        for (StringVector::const_iterator itGroup = groups.begin(); itGroup != groups.end(); ++itGroup)
+        {
+            FileInfoListPtr files = ResourceGroupManager::getSingleton().findResourceFileInfo(*itGroup, "*.particle");
+            for (FileInfoList::const_iterator itFile = files->begin(); itFile != files->end(); ++itFile)
+            {
+                // open file
+                Ogre::DataStreamPtr input = ResourceGroupManager::getSingleton().openResource(itFile->filename, *itGroup, false);
+                std::stringstream output;
+                // Parse file and replace "particle_system" with nothing
+                while (!input->eof())
+                {
+                    std::string line = input->getLine();
+                    size_t pos = line.find("particle_system");
+                    if (pos != std::string::npos)
+                    {
+                        // 15 is the length of "particle_system"
+                        line.replace(pos, 15, "");
+                    }
+                    output << line << std::endl;
+                }
+                // Add file to the memory archive
+                shared_array<char> data(new char[output.str().size()]);
+                // Debug optimisations
+                const std::string outputStr = output.str();
+                char* rawData = data.get();
+                for (unsigned i = 0; i < outputStr.size(); ++i)
+                    rawData[i] = outputStr[i];
+                MemoryArchive::addFile("particle_scripts_ogre_1.4_" + *itGroup, itFile->filename, data, output.str().size());
+            }
+            if (!files->empty())
+            {
+                // Declare the files, but using a new group
+                ResourceGroupManager::getSingleton().addResourceLocation("particle_scripts_ogre_1.4_" + *itGroup,
+                    "Memory", "particle_scripts_ogre_1.4_" + *itGroup);
+            }
+        }
+#endif
+
+        // Initialise all resources (do this AFTER the renderer has been loaded!)
+        // Note: You can only do this once! Ogre will check whether a resource group has
+        // already been initialised. If you need to load resources later, you will have to
+        // choose another resource group.
+        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+    }
+
+    /**
+    @brief
+        Creates the Ogre Root object and sets up the ogre log.
+    */
+    void GraphicsManager::loadOgreRoot()
+    {
+        COUT(3) << "Setting up Ogre..." << std::endl;
+
+        if (ogreConfigFile_ == "")
+        {
+            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
+            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
+        }
+        if (ogreLogFile_ == "")
+        {
+            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
+            ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
+        }
+
+        boost::filesystem::path ogreConfigFilepath(Core::getConfigPath() / this->ogreConfigFile_);
+        boost::filesystem::path ogreLogFilepath(Core::getLogPath() / this->ogreLogFile_);
+
+        // create a new logManager
+        // Ogre::Root will detect that we've already created a Log
+        ogreLogger_.reset(new Ogre::LogManager());
+        COUT(4) << "Ogre LogManager created" << std::endl;
+
+        // create our own log that we can listen to
+        Ogre::Log *myLog;
+        myLog = ogreLogger_->createLog(ogreLogFilepath.string(), true, false, false);
+        COUT(4) << "Ogre Log created" << std::endl;
+
+        myLog->setLogDetail(Ogre::LL_BOREME);
+        myLog->addListener(this);
+
+        COUT(4) << "Creating Ogre Root..." << std::endl;
+
+        // check for config file existence because Ogre displays (caught) exceptions if not
+        if (!boost::filesystem::exists(ogreConfigFilepath))
+        {
+            // create a zero sized file
+            std::ofstream creator;
+            creator.open(ogreConfigFilepath.string().c_str());
+            creator.close();
+        }
+
+        // Leave plugins file empty. We're going to do that part manually later
+        ogreRoot_.reset(new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string()));
+
+        COUT(3) << "Ogre set up done." << std::endl;
+    }
+
+    void GraphicsManager::loadOgrePlugins()
+    {
+        // just to make sure the next statement doesn't segfault
+        if (ogrePluginsDirectory_ == "")
+            ogrePluginsDirectory_ = ".";
+
+        boost::filesystem::path folder(ogrePluginsDirectory_);
+        // Do some SubString magic to get the comma separated list of plugins
+        SubString plugins(ogrePlugins_, ",", " ", false, '\\', false, '"', false, '(', ')', false, '\0');
+        // Use backslash paths on Windows! file_string() already does that though.
+        for (unsigned int i = 0; i < plugins.size(); ++i)
+            ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
+    }
+
+    void GraphicsManager::loadRenderer()
+    {
+        CCOUT(4) << "Configuring Renderer" << std::endl;
+
+        if (!ogreRoot_->restoreConfig())
+            if (!ogreRoot_->showConfigDialog())
+                ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
+
+        CCOUT(4) << "Creating render window" << std::endl;
+
+        this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
+        // Propagate the size of the new winodw
+        this->ogreWindowEventListener_->windowResized(renderWindow_);
+
+        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_.get());
+
+        // create a full screen default viewport
+        // Note: This may throw when adding a viewport with an existing z-order!
+        //       But in our case we only have one viewport for now anyway, therefore
+        //       no ScopeGuards or anything to handle exceptions.
+        this->viewport_ = this->renderWindow_->addViewport(0, 0);
+
+        Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);
+
+        // add console commands
+        FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
+        ccPrintScreen_ = createConsoleCommand(functor1->setObject(this), "printScreen");
+        CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
+    }
+
+    void GraphicsManager::update(const Clock& time)
+    {
+        Ogre::FrameEvent evt;
+        evt.timeSinceLastFrame = time.getDeltaTime();
+        evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
+
+        // don't forget to call _fireFrameStarted to OGRE to make sure
+        // everything goes smoothly
+        ogreRoot_->_fireFrameStarted(evt);
+
+        // Pump messages in all registered RenderWindows
+        // This calls the WindowEventListener objects.
+        Ogre::WindowEventUtilities::messagePump();
+        // make sure the window stays active even when not focused
+        // (probably only necessary on windows)
+        this->renderWindow_->setActive(true);
+
+        // Time before rendering
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
+        // Render frame
+        ogreRoot_->_updateAllRenderTargets();
+
+        uint64_t timeAfterTick = time.getRealMicroseconds();
+        // Subtract the time used for rendering from the tick time counter
+        Game::getInstance().subtractTickTime(timeAfterTick - timeBeforeTick);
+
+        // again, just to be sure OGRE works fine
+        ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+    }
+
+    void GraphicsManager::setCamera(Ogre::Camera* camera)
+    {
+        this->viewport_->setCamera(camera);
+    }
+
+    /**
+    @brief
+        Method called by the LogListener interface from Ogre.
+        We use it to capture Ogre log messages and handle it ourselves.
+    @param message
+        The message to be logged
+    @param lml
+        The message level the log is using
+    @param maskDebug
+        If we are printing to the console or not
+    @param logName
+        The name of this log (so you can have several listeners
+        for different logs, and identify them)
+    */
+    void GraphicsManager::messageLogged(const std::string& message,
+        Ogre::LogMessageLevel lml, bool maskDebug, const std::string& logName)
+    {
+        int orxonoxLevel;
+        switch (lml)
+        {
+        case Ogre::LML_TRIVIAL:
+            orxonoxLevel = this->ogreLogLevelTrivial_;
+            break;
+        case Ogre::LML_NORMAL:
+            orxonoxLevel = this->ogreLogLevelNormal_;
+            break;
+        case Ogre::LML_CRITICAL:
+            orxonoxLevel = this->ogreLogLevelCritical_;
+            break;
+        default:
+            orxonoxLevel = 0;
+        }
+        OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
+            << "Ogre: " << message << std::endl;
+    }
+
+    size_t GraphicsManager::getRenderWindowHandle()
+    {
+        size_t windowHnd = 0;
+        renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
+        return windowHnd;
+    }
+
+    bool GraphicsManager::isFullScreen() const
+    {
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        if (options.find("Full Screen") != options.end())
+        {
+            if (options["Full Screen"].currentValue == "Yes")
+                return true;
+            else
+                return false;
+        }
+        else
+        {
+            COUT(0) << "Could not find 'Full Screen' render system option. Fix This!!!" << std::endl;
+            return false;
+        }
+    }
+
+    void GraphicsManager::printScreen()
+    {
+        assert(this->renderWindow_);
+       
+        this->renderWindow_->writeContentsToTimestampedFile(Core::getLogPathString() + "screenShot_", ".jpg");
+    }
+}
Index: code/trunk/src/libraries/core/GraphicsManager.h
===================================================================
--- code/trunk/src/libraries/core/GraphicsManager.h	(revision 5781)
+++ code/trunk/src/libraries/core/GraphicsManager.h	(revision 5781)
@@ -0,0 +1,121 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *   Co-authors:
+ *      Felix Schulthess
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of GraphicsManager Singleton.
+ */
+
+#ifndef _GraphicsManager_H__
+#define _GraphicsManager_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <OgreLog.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Graphics engine manager class
+    */
+    class _CoreExport GraphicsManager : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
+    {
+        friend class Singleton<GraphicsManager>;
+    public:
+        GraphicsManager(bool bLoadRenderer = true);
+        ~GraphicsManager();
+
+        void setConfigValues();
+
+        void update(const Clock& time);
+
+        Ogre::Viewport* getViewport()         { return this->viewport_; }
+        Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
+        size_t getRenderWindowHandle();
+        bool isFullScreen() const;
+
+        void upgradeToGraphics();
+        bool rendererLoaded() const { return renderWindow_ != NULL; }
+
+        void setCamera(Ogre::Camera* camera);
+
+    private:
+        GraphicsManager(GraphicsManager&); // don't mess with singletons
+
+        // OGRE initialisation
+        void loadOgreRoot();
+        void loadOgrePlugins();
+        void loadRenderer();
+
+        // event from Ogre::LogListener
+        void messageLogged(const std::string& message, Ogre::LogMessageLevel lml,
+            bool maskDebug, const std::string& logName);
+
+        // console commands
+        void printScreen();
+
+        scoped_ptr<OgreWindowEventListener> ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
+#if OGRE_VERSION < 0x010600
+        scoped_ptr<MemoryArchiveFactory>    memoryArchiveFactory_;    //!< Stores the modified particle scripts
+#endif
+        scoped_ptr<Ogre::LogManager>        ogreLogger_;
+        scoped_ptr<Ogre::Root>              ogreRoot_;                //!< Ogre's root
+        Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
+        Ogre::Viewport*     viewport_;                 //!< default full size viewport
+
+        // XML files for the resources
+        shared_ptr<XMLFile> resources_;                //!< XML with resource locations
+        shared_ptr<XMLFile> extResources_;             //!< XML with resource locations in the external path (only for dev runs)
+
+        // config values
+        std::string         ogreConfigFile_;           //!< ogre config file name
+        std::string         ogrePluginsDirectory_;     //!< Directory where the Ogre plugins are located
+        std::string         ogrePlugins_;              //!< Comma separated list of all plugins to load
+        std::string         ogreLogFile_;              //!< log file name for Ogre log messages
+        int                 ogreLogLevelTrivial_;      //!< Corresponding Orxonx debug level for LL_TRIVIAL
+        int                 ogreLogLevelNormal_;       //!< Corresponding Orxonx debug level for LL_NORMAL
+        int                 ogreLogLevelCritical_;     //!< Corresponding Orxonx debug level for LL_CRITICAL
+
+        // console commands
+        ConsoleCommand*     ccPrintScreen_;
+
+        static GraphicsManager* singletonPtr_s;        //!< Pointer to the Singleton
+    };
+}
+
+#endif /* _GraphicsManager_H__ */
Index: code/trunk/src/libraries/core/IRC.cc
===================================================================
--- code/trunk/src/libraries/core/IRC.cc	(revision 5781)
+++ code/trunk/src/libraries/core/IRC.cc	(revision 5781)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "IRC.h"
+
+#include <cpptcl/cpptcl.h>
+
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "ConsoleCommand.h"
+#include "CoreIncludes.h"
+#include "TclThreadManager.h"
+
+namespace orxonox
+{
+    static const unsigned int IRC_TCL_THREADID  = 1421421421;
+
+    SetConsoleCommand(IRC, say,  true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(IRC, msg,  false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(IRC, nick, false).accessLevel(AccessLevel::User);
+
+    IRC::IRC()
+    {
+        RegisterRootObject(IRC);
+        this->interpreter_ = 0;
+    }
+
+    void IRC::initialize()
+    {
+        unsigned int threadID = IRC_TCL_THREADID;
+        this->interpreter_ = TclThreadManager::createWithId(threadID);
+
+        try
+        {
+            this->interpreter_->def("::orxonox::irc::say", IRC::tcl_say, Tcl::variadic());
+            this->interpreter_->def("::orxonox::irc::privmsg", IRC::tcl_privmsg, Tcl::variadic());
+            this->interpreter_->def("::orxonox::irc::action", IRC::tcl_action, Tcl::variadic());
+            this->interpreter_->def("::orxonox::irc::info", IRC::tcl_info, Tcl::variadic());
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl (IRC) error: " << e.what();   }
+        catch (...)
+        {   COUT(1) << "Error while initializing Tcl (IRC): " << Exception::handleMessage();   }
+
+        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");
+    }
+
+    IRC& IRC::getInstance()
+    {
+        static IRC instance;
+        return instance;
+    }
+
+    bool IRC::eval(const std::string& command)
+    {
+        if (!IRC::getInstance().interpreter_)
+        {
+            IRC::getInstance().initialize();
+            COUT(1) << "Error: IRC client wasn't yet initialized, please try again." << std::endl;
+            return false;
+        }
+
+        try
+        {
+            IRC::getInstance().interpreter_->eval(command);
+            return true;
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl (IRC) error: " << e.what();   }
+        catch (...)
+        {   COUT(1) << "Error while executing Tcl (IRC): " << Exception::handleMessage();   }
+
+        return false;
+    }
+
+    void IRC::say(const std::string& message)
+    {
+        if (IRC::eval("irk::say $conn #orxonox {" + message + "}"))
+            IRC::tcl_say(Tcl::object(), Tcl::object(IRC::getInstance().nickname_), Tcl::object(message));
+    }
+
+    void IRC::msg(const std::string& channel, const std::string& message)
+    {
+        if (IRC::eval("irk::say $conn " + channel + " {" + message + "}"))
+            IRC::tcl_privmsg(Tcl::object(channel), Tcl::object(IRC::getInstance().nickname_), Tcl::object(message));
+    }
+
+    void IRC::nick(const std::string& nickname)
+    {
+        if (IRC::eval("irk::nick $conn " + nickname))
+            IRC::getInstance().nickname_ = nickname;
+    }
+
+    void IRC::tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
+    {
+        COUT(0) << "IRC> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+
+    void IRC::tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args)
+    {
+        COUT(0) << "IRC (" << query.get() << ")> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+
+    void IRC::tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
+    {
+        COUT(0) << "IRC> * " << nick.get() << " " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+
+    void IRC::tcl_info(Tcl::object const &channel, Tcl::object const &args)
+    {
+        COUT(0) << "IRC> --> " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+}
Index: code/trunk/src/libraries/core/IRC.h
===================================================================
--- code/trunk/src/libraries/core/IRC.h	(revision 5781)
+++ code/trunk/src/libraries/core/IRC.h	(revision 5781)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _IRC_H__
+#define _IRC_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport IRC : public OrxonoxClass
+    {
+        public:
+            static IRC& getInstance();
+
+            static void say(const std::string& message);
+            static void msg(const std::string& channel, const std::string& message);
+            static void nick(const std::string& nickname);
+
+            static void tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args);
+            static void tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args);
+            static void tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args);
+            static void tcl_info(Tcl::object const &channel, Tcl::object const &args);
+
+        private:
+            static bool eval(const std::string& command);
+            void initialize();
+
+            IRC();
+            IRC(const IRC& other);
+            ~IRC() {}
+
+            Tcl::interpreter* interpreter_;
+            std::string nickname_;
+    };
+}
+
+#endif /* _IRC_H__ */
Index: code/trunk/src/libraries/core/Identifier.cc
===================================================================
--- code/trunk/src/libraries/core/Identifier.cc	(revision 5774)
+++ code/trunk/src/libraries/core/Identifier.cc	(revision 5781)
@@ -38,5 +38,7 @@
 #include "util/StringUtils.h"
 #include "ConfigValueContainer.h"
+#include "ConsoleCommand.h"
 #include "Factory.h"
+#include "XMLPort.h"
 
 namespace orxonox
@@ -59,9 +61,14 @@
         this->bSetName_ = false;
         this->factory_ = 0;
+        this->bLoadable_ = true;
 
         this->bHasConfigValues_ = false;
+        this->bHasConsoleCommands_ = false;
 
         this->children_ = new std::set<const Identifier*>();
         this->directChildren_ = new std::set<const Identifier*>();
+
+        // Default network ID is the class ID
+        this->networkID_ = this->classID_;
     }
 
@@ -78,5 +85,11 @@
             delete this->factory_;
 
+        for (std::map<std::string, ConsoleCommand*>::iterator it = this->consoleCommands_.begin(); it != this->consoleCommands_.end(); ++it)
+            delete (it->second);
         for (std::map<std::string, ConfigValueContainer*>::iterator it = this->configValues_.begin(); it != this->configValues_.end(); ++it)
+            delete (it->second);
+        for (std::map<std::string, XMLPortParamContainer*>::iterator it = this->xmlportParamContainers_.begin(); it != this->xmlportParamContainers_.end(); ++it)
+            delete (it->second);
+        for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportObjectContainers_.begin(); it != this->xmlportObjectContainers_.end(); ++it)
             delete (it->second);
     }
@@ -175,4 +188,7 @@
                 // Tell the parent we're one of it's direct children
                 (*it)->getDirectChildrenIntern().insert((*it)->getDirectChildrenIntern().end(), this);
+
+                // Create the super-function dependencies
+                (*it)->createSuperFunctionCaller();
             }
         }
@@ -224,4 +240,14 @@
 
     /**
+        @brief Sets the network ID to a new value and changes the entry in the Factory.
+        @param id The new network ID
+    */
+    void Identifier::setNetworkID(uint32_t id)
+    {
+        Factory::changeNetworkID(this, this->networkID_, id);
+        this->networkID_ = id;
+    }
+
+    /**
         @brief Returns true, if the Identifier is at least of the given type.
         @param identifier The identifier to compare with
@@ -342,4 +368,150 @@
         else
             return 0;
+    }
+
+    /**
+        @brief Adds a new console command of this class.
+        @param executor The executor of the command
+        @param bCreateShortcut If this is true a shortcut gets created so you don't have to add the classname to access this command
+        @return The executor of the command
+    */
+    ConsoleCommand& Identifier::addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(command->getName());
+        if (it != this->consoleCommands_.end())
+        {
+            COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << "." << std::endl;
+            delete (it->second);
+        }
+
+        this->bHasConsoleCommands_ = true;
+        this->consoleCommands_[command->getName()] = command;
+        this->consoleCommands_LC_[getLowercase(command->getName())] = command;
+
+        if (bCreateShortcut)
+            CommandExecutor::addConsoleCommandShortcut(command);
+
+        return (*command);
+    }
+
+    /**
+        @brief Returns the executor of a console command with given name.
+        @brief name The name of the requested console command
+        @return The executor of the requested console command
+    */
+    ConsoleCommand* Identifier::getConsoleCommand(const std::string& name) const
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(name);
+        if (it != this->consoleCommands_.end())
+            return (*it).second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns the executor of a console command with given name in lowercase.
+        @brief name The name of the requested console command in lowercae
+        @return The executor of the requested console command
+    */
+    ConsoleCommand* Identifier::getLowercaseConsoleCommand(const std::string& name) const
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_LC_.find(name);
+        if (it != this->consoleCommands_LC_.end())
+            return (*it).second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns a XMLPortParamContainer that loads a parameter of this class.
+        @param paramname The name of the parameter
+        @return The container
+    */
+    XMLPortParamContainer* Identifier::getXMLPortParamContainer(const std::string& paramname)
+    {
+        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
+        if (it != this->xmlportParamContainers_.end())
+            return ((*it).second);
+        else
+            return 0;
+    }
+
+    /**
+        @brief Adds a new XMLPortParamContainer that loads a parameter of this class.
+        @param paramname The name of the parameter
+        @param container The container
+    */
+    void Identifier::addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container)
+    {
+        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
+        if (it != this->xmlportParamContainers_.end())
+        {
+            COUT(2) << "Warning: Overwriting XMLPortParamContainer in class " << this->getName() << "." << std::endl;
+            delete (it->second);
+        }
+
+        this->xmlportParamContainers_[paramname] = container;
+    }
+
+    /**
+        @brief Returns a XMLPortObjectContainer that attaches an object to this class.
+        @param sectionname The name of the section that contains the attachable objects
+        @return The container
+    */
+    XMLPortObjectContainer* Identifier::getXMLPortObjectContainer(const std::string& sectionname)
+    {
+        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
+        if (it != this->xmlportObjectContainers_.end())
+            return ((*it).second);
+        else
+            return 0;
+    }
+
+    /**
+        @brief Adds a new XMLPortObjectContainer that attaches an object to this class.
+        @param sectionname The name of the section that contains the attachable objects
+        @param container The container
+    */
+    void Identifier::addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container)
+    {
+        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
+        if (it != this->xmlportObjectContainers_.end())
+        {
+            COUT(2) << "Warning: Overwriting XMLPortObjectContainer in class " << this->getName() << "." << std::endl;
+            delete (it->second);
+        }
+
+        this->xmlportObjectContainers_[sectionname] = container;
+    }
+
+    /**
+        @brief Returns a XMLPortEventContainer that attaches an event to this class.
+        @param sectionname The name of the section that contains the event
+        @return The container
+    */
+    XMLPortObjectContainer* Identifier::getXMLPortEventContainer(const std::string& eventname)
+    {
+        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportEventContainers_.find(eventname);
+        if (it != this->xmlportEventContainers_.end())
+            return ((*it).second);
+        else
+            return 0;
+    }
+
+    /**
+        @brief Adds a new XMLPortEventContainer that attaches an event to this class.
+        @param sectionname The name of the section that contains the event
+        @param container The container
+    */
+    void Identifier::addXMLPortEventContainer(const std::string& eventname, XMLPortObjectContainer* container)
+    {
+        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportEventContainers_.find(eventname);
+        if (it != this->xmlportEventContainers_.end())
+        {
+            COUT(2) << "Warning: Overwriting XMLPortEventContainer in class " << this->getName() << "." << std::endl;
+            delete (it->second);
+        }
+
+        this->xmlportEventContainers_[eventname] = container;
     }
 
Index: code/trunk/src/libraries/core/Identifier.h
===================================================================
--- code/trunk/src/libraries/core/Identifier.h	(revision 5774)
+++ code/trunk/src/libraries/core/Identifier.h	(revision 5781)
@@ -66,4 +66,5 @@
 #include "ObjectList.h"
 #include "ObjectListBase.h"
+#include "Super.h"
 
 namespace orxonox
@@ -106,4 +107,9 @@
             bool isDirectParentOf(const Identifier* identifier) const;
 
+            /** @brief Returns true if the class can be loaded through XML. */
+            inline bool isLoadable() const { return this->bLoadable_; }
+            /** @brief Set the class to be loadable through XML or not. */
+            inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; }
+
             /** @brief Returns the list of all existing objects of this class. @return The list */
             inline ObjectListBase* getObjects() const
@@ -175,9 +181,52 @@
 
 
+            /** @brief Returns the map that stores all console commands. @return The const_iterator */
+            inline const std::map<std::string, ConsoleCommand*>& getConsoleCommandMap() const { return this->consoleCommands_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandMapBegin() const { return this->consoleCommands_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandMapEnd() const { return this->consoleCommands_.end(); }
+
+            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            inline const std::map<std::string, ConsoleCommand*>& getLowercaseConsoleCommandMap() const { return this->consoleCommands_LC_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandMapBegin() const { return this->consoleCommands_LC_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandMapEnd() const { return this->consoleCommands_LC_.end(); }
+
+            /** @brief Returns the map that stores all XMLPort params. @return The const_iterator */
+            inline const std::map<std::string, XMLPortParamContainer*>& getXMLPortParamMap() const { return this->xmlportParamContainers_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort params. @return The const_iterator */
+            inline std::map<std::string, XMLPortParamContainer*>::const_iterator getXMLPortParamMapBegin() const { return this->xmlportParamContainers_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all XMLPort params. @return The const_iterator */
+            inline std::map<std::string, XMLPortParamContainer*>::const_iterator getXMLPortParamMapEnd() const { return this->xmlportParamContainers_.end(); }
+
+            /** @brief Returns the map that stores all XMLPort objects. @return The const_iterator */
+            inline const std::map<std::string, XMLPortObjectContainer*>& getXMLPortObjectMap() const { return this->xmlportObjectContainers_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort objects. @return The const_iterator */
+            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapBegin() const { return this->xmlportObjectContainers_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all XMLPort objects. @return The const_iterator */
+            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapEnd() const { return this->xmlportObjectContainers_.end(); }
+
+            /** @brief Returns the map that stores all XMLPort events. @return The const_iterator */
+            inline const std::map<std::string, XMLPortObjectContainer*>& getXMLPortEventMap() const { return this->xmlportEventContainers_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort events. @return The const_iterator */
+            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortEventMapBegin() const { return this->xmlportEventContainers_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all XMLPort events. @return The const_iterator */
+            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortEventMapEnd() const { return this->xmlportEventContainers_.end(); }
+
             /** @brief Returns true if this class has at least one config value. @return True if this class has at least one config value */
             inline bool hasConfigValues() const { return this->bHasConfigValues_; }
+            /** @brief Returns true if this class has at least one console command. @return True if this class has at least one console command */
+            inline bool hasConsoleCommands() const { return this->bHasConsoleCommands_; }
 
             /** @brief Returns true, if a branch of the class-hierarchy is being created, causing all new objects to store their parents. @return The status of the class-hierarchy creation */
             inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
+
+            /** @brief Returns the network ID to identify a class through the network. @return the network ID */
+            inline const uint32_t getNetworkID() const { return this->networkID_; }
+
+            /** @brief Sets the network ID to a new value. @param id The new value */
+            void setNetworkID(uint32_t id);
 
             /** @brief Returns the unique ID of the class */
@@ -187,4 +236,17 @@
             ConfigValueContainer* getConfigValueContainer(const std::string& varname);
             ConfigValueContainer* getLowercaseConfigValueContainer(const std::string& varname);
+
+            void addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container);
+            XMLPortParamContainer* getXMLPortParamContainer(const std::string& paramname);
+
+            void addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container);
+            XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
+
+            void addXMLPortEventContainer(const std::string& eventname, XMLPortObjectContainer* container);
+            XMLPortObjectContainer* getXMLPortEventContainer(const std::string& eventname);
+
+            ConsoleCommand& addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut);
+            ConsoleCommand* getConsoleCommand(const std::string& name) const;
+            ConsoleCommand* getLowercaseConsoleCommand(const std::string& name) const;
 
             void initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass);
@@ -198,4 +260,5 @@
 
             static Identifier* getIdentifierSingleton(const std::string& name, Identifier* proposal);
+            virtual void createSuperFunctionCaller() const = 0;
 
             /** @brief Returns the map that stores all Identifiers. @return The map */
@@ -242,7 +305,9 @@
             bool bCreatedOneObject_;                                       //!< True if at least one object of the given type was created (used to determine the need of storing the parents)
             bool bSetName_;                                                //!< True if the name is set
+            bool bLoadable_;                                               //!< False = it's not permitted to load the object through XML
             std::string name_;                                             //!< The name of the class the Identifier belongs to
             BaseFactory* factory_;                                         //!< The Factory, able to create new objects of the given class (if available)
             static int hierarchyCreatingCounter_s;                         //!< Bigger than zero if at least one Identifier stores its parents (its an int instead of a bool to avoid conflicts with multithreading)
+            uint32_t networkID_;                                           //!< The network ID to identify a class through the network
             const unsigned int classID_;                                   //!< Uniquely identifies a class (might not be the same as the networkID_)
             static unsigned int classIDCounter_s;                          //!< Static counter for the unique classIDs
@@ -251,4 +316,12 @@
             std::map<std::string, ConfigValueContainer*> configValues_;    //!< A map to link the string of configurable variables with their ConfigValueContainer
             std::map<std::string, ConfigValueContainer*> configValues_LC_; //!< A map to link the string of configurable variables with their ConfigValueContainer
+
+            bool bHasConsoleCommands_;                                     //!< True if this class has at least one assigned console command
+            std::map<std::string, ConsoleCommand*> consoleCommands_;       //!< All console commands of this class
+            std::map<std::string, ConsoleCommand*> consoleCommands_LC_;    //!< All console commands of this class with their names in lowercase
+
+            std::map<std::string, XMLPortParamContainer*> xmlportParamContainers_;     //!< All loadable parameters
+            std::map<std::string, XMLPortObjectContainer*> xmlportObjectContainers_;   //!< All attachable objects
+            std::map<std::string, XMLPortObjectContainer*> xmlportEventContainers_;    //!< All events
     };
 
@@ -271,4 +344,7 @@
     class ClassIdentifier : public Identifier
     {
+        #define SUPER_INTRUSIVE_DECLARATION_INCLUDE
+        #include "Super.h"
+
         public:
             static ClassIdentifier<T> *getIdentifier();
@@ -284,7 +360,9 @@
             ClassIdentifier()
             {
+                SuperFunctionInitialization<0, T>::initialize(this);
             }
             ~ClassIdentifier()
             {
+                SuperFunctionDestruction<0, T>::destroy(this);
             }
 
@@ -552,4 +630,28 @@
                 { return this->identifier_; }
 
+//            /** @brief Returns true, if the assigned identifier is at least of the given type. @param identifier The identifier to compare with */
+//            inline bool isA(const Identifier* identifier) const
+//                { return this->identifier_->isA(identifier); }
+//
+//            /** @brief Returns true, if the assigned identifier is exactly of the given type. @param identifier The identifier to compare with */
+//            inline bool isExactlyA(const Identifier* identifier) const
+//                { return this->identifier_->isExactlyA(identifier); }
+//
+//            /** @brief Returns true, if the assigned identifier is a child of the given identifier. @param identifier The identifier to compare with */
+//            inline bool isChildOf(const Identifier* identifier) const
+//                { return this->identifier_->isChildOf(identifier); }
+//
+//            /** @brief Returns true, if the assigned identifier is a direct child of the given identifier. @param identifier The identifier to compare with */
+//            inline bool isDirectChildOf(const Identifier* identifier) const
+//                { return this->identifier_->isDirectChildOf(identifier); }
+//
+//            /** @brief Returns true, if the assigned identifier is a parent of the given identifier. @param identifier The identifier to compare with */
+//            inline bool isParentOf(const Identifier* identifier) const
+//                { return this->identifier_->isParentOf(identifier); }
+//
+//            /** @brief Returns true, if the assigned identifier is a direct parent of the given identifier. @param identifier The identifier to compare with */
+//            inline bool isDirectParentOf(const Identifier* identifier) const
+//                { return this->identifier_->isDirectParentOf(identifier); }
+
         private:
             Identifier* identifier_;            //!< The assigned identifier
Index: code/trunk/src/libraries/core/Loader.cc
===================================================================
--- code/trunk/src/libraries/core/Loader.cc	(revision 5781)
+++ code/trunk/src/libraries/core/Loader.cc	(revision 5781)
@@ -0,0 +1,368 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Loader.h"
+
+#include <sstream>
+#include <tinyxml/ticpp.h>
+#include <boost/scoped_ptr.hpp>
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "BaseObject.h"
+#include "Iterator.h"
+#include "ObjectList.h"
+#include "LuaState.h"
+#include "Namespace.h"
+#include "Resource.h"
+#include "XMLFile.h"
+
+namespace orxonox
+{
+    std::vector<std::pair<const XMLFile*, ClassTreeMask> > Loader::files_s;
+    ClassTreeMask Loader::currentMask_s;
+
+    bool Loader::open(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        Loader::add(file, mask);
+        return Loader::load(file, mask);
+    }
+
+    void Loader::close()
+    {
+        Loader::unload();
+        Loader::files_s.clear();
+    }
+
+    void Loader::close(const XMLFile* file)
+    {
+        Loader::unload(file);
+        Loader::remove(file);
+    }
+
+    void Loader::add(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        if (!file)
+            return;
+        Loader::files_s.insert(Loader::files_s.end(), std::pair<const XMLFile*, ClassTreeMask>(file, mask));
+    }
+
+    void Loader::remove(const XMLFile* file)
+    {
+        if (!file)
+            return;
+        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
+        {
+            if ((*it).first == file)
+            {
+                Loader::files_s.erase(it);
+                break;
+            }
+        }
+    }
+
+    bool Loader::load(const ClassTreeMask& mask)
+    {
+        bool success = true;
+        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
+            if (!Loader::load((*it).first, (*it).second * mask))
+                success = false;
+
+        return success;
+    }
+
+    void Loader::unload(const ClassTreeMask& mask)
+    {
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); )
+        {
+            if (mask.isIncluded(it->getIdentifier()))
+                delete (*(it++));
+            else
+                ++it;
+        }
+    }
+
+    bool Loader::reload(const ClassTreeMask& mask)
+    {
+        Loader::unload(mask);
+        return Loader::load(mask);
+    }
+
+    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        if (!file)
+            return false;
+
+        Loader::currentMask_s = file->getMask() * mask;
+
+        std::string xmlInput;
+        if (file->getLuaSupport())
+        {
+            // Use the LuaState to replace the XML tags (calls our function)
+            scoped_ptr<LuaState> luaState(new LuaState());
+            luaState->setIncludeParser(&Loader::replaceLuaTags);
+            luaState->includeFile(file->getFilename(), file->getResourceGroup(), false);
+            xmlInput = luaState->getOutput().str();
+        }
+        else
+        {
+            shared_ptr<ResourceInfo> info = Resource::getInfo(file->getFilename(), file->getResourceGroup());
+            if (info == NULL)
+            {
+                COUT(1) << "Error: Could not find XML file '" << file->getFilename() << "'." << std::endl;
+                return false;
+            }
+            xmlInput = Resource::open(file->getFilename(), file->getResourceGroup())->getAsString();
+        }
+
+        try
+        {
+            COUT(0) << "Start loading " << file->getFilename() << "..." << std::endl;
+            COUT(3) << "Mask: " << Loader::currentMask_s << std::endl;
+
+            ticpp::Document xmlfile(file->getFilename());
+            xmlfile.Parse(xmlInput, true);
+
+            ticpp::Element rootElement;
+            rootElement.SetAttribute("name", "root");
+            rootElement.SetAttribute("bAutogenerated", true);
+
+            for (ticpp::Iterator<ticpp::Element> child = xmlfile.FirstChildElement(false); child != child.end(); child++)
+                rootElement.InsertEndChild(*child);
+
+            COUT(4) << "  creating root-namespace..." << std::endl;
+            Namespace* rootNamespace = new Namespace(0);
+            rootNamespace->setLoaderIndentation("    ");
+            rootNamespace->setFile(file);
+            rootNamespace->setNamespace(rootNamespace);
+            rootNamespace->setRoot(true);
+            rootNamespace->XMLPort(rootElement, XMLPort::LoadObject);
+
+            COUT(0) << "Finished loading " << file->getFilename() << "." << std::endl;
+
+            COUT(4) << "Namespace-tree:" << std::endl << rootNamespace->toString("  ") << std::endl;
+
+            return true;
+        }
+        catch (ticpp::Exception& ex)
+        {
+            COUT(1) << std::endl;
+            COUT(1) << "An XML-error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
+            COUT(1) << ex.what() << std::endl;
+            COUT(1) << "Loading aborted." << std::endl;
+            return false;
+        }
+        catch (Exception& ex)
+        {
+            COUT(1) << std::endl;
+            COUT(1) << "A loading-error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
+            COUT(1) << ex.what() << std::endl;
+            COUT(1) << "Loading aborted." << std::endl;
+            return false;
+        }
+        catch (...)
+        {
+            COUT(1) << std::endl;
+            COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
+            COUT(1) << Exception::handleMessage() << std::endl;
+            COUT(1) << "Loading aborted." << std::endl;
+            return false;
+        }
+    }
+
+    void Loader::unload(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        if (!file)
+            return;
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it; )
+        {
+            if ((it->getFile() == file) && mask.isIncluded(it->getIdentifier()))
+                delete (*(it++));
+            else
+                ++it;
+        }
+    }
+
+    bool Loader::reload(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        Loader::unload(file, mask);
+        return Loader::load(file, mask);
+    }
+
+    std::string Loader::replaceLuaTags(const std::string& text)
+    {
+        // chreate map with all Lua tags
+        std::map<size_t, bool> luaTags;
+        {
+            size_t pos = 0;
+            while ((pos = text.find("<?lua", pos)) != std::string::npos)
+                luaTags[pos++] = true;
+        }
+        {
+            size_t pos = 0;
+            while ((pos = text.find("?>", pos)) != std::string::npos)
+                luaTags[pos++] = false;
+        }
+
+        // erase all tags from the map that are between two quotes
+        {
+            std::map<size_t, bool>::iterator it = luaTags.begin();
+            std::map<size_t, bool>::iterator it2 = it;
+            bool bBetweenQuotes = false;
+            size_t pos = 0;
+            while ((pos = getNextQuote(text, pos)) != std::string::npos)
+            {
+                while ((it != luaTags.end()) && (it->first < pos))
+                {
+                    if (bBetweenQuotes)
+                    {
+                        it2++;
+                        if(it->second && !(it2->second) && it2->first < pos)
+                            it = ++it2;
+                        else
+                            luaTags.erase(it++);
+                    }
+                    else
+                        ++it;
+                }
+                bBetweenQuotes = !bBetweenQuotes;
+                pos++;
+            }
+        }
+
+        // check whether on every opening <?lua tag a closing ?> tag follows
+        {
+            bool expectedValue = true;
+            for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
+            {
+                if (it->second == expectedValue)
+                    expectedValue = !expectedValue;
+                else
+                {
+                    expectedValue = false;
+                    break;
+                }
+            }
+            if (!expectedValue)
+            {
+                COUT(2) << "Warning: Error in level file" << std::endl;
+                // todo: errorhandling
+                return "";
+            }
+        }
+
+        // Use a stringstream object to speed up the parsing
+        std::ostringstream output;
+
+        // cut the original string into pieces and put them together with print() instead of lua tags
+        {
+            std::map<size_t, bool>::iterator it = luaTags.begin();
+            bool bInPrintFunction = true;
+            size_t start = 0;
+            size_t end = 0;
+
+            do
+            {
+                if (it != luaTags.end())
+                    end = (*(it++)).first;
+                else
+                    end = std::string::npos;
+
+                unsigned int equalSignCounter = 0;
+
+                if (bInPrintFunction)
+                {
+                    // count ['='[ and ]'='] and replace tags with print([[ and ]])
+                    std::string temp = text.substr(start, end - start);
+                    {
+                    size_t pos = 0;
+                    while ((pos = temp.find('[', pos)) != std::string::npos)
+                    {
+                        unsigned int tempCounter = 1;
+                        size_t tempPos = pos++;
+                        while(temp[++tempPos] == '=')
+                        {
+                            tempCounter++;
+                        }
+                        if(temp[tempPos] != '[')
+                        {
+                            tempCounter = 0;
+                        }
+                        else if(tempCounter == 0)
+                        {
+                            tempCounter = 1;
+                        }
+                        if (tempCounter > equalSignCounter)
+                            equalSignCounter = tempCounter;
+                        }
+                    }
+                    {
+                        size_t pos = 0;
+                        while ((pos = temp.find(']', pos)) != std::string::npos)
+                        {
+                            unsigned int tempCounter = 1;
+                            size_t tempPos = pos++;
+                            while(temp[++tempPos] == '=')
+                            {
+                                tempCounter++;
+                            }
+                            if(temp[tempPos] != ']')
+                            {
+                                tempCounter = 0;
+                            }
+                            else if(tempCounter == 0)
+                            {
+                                tempCounter = 1;
+                            }
+                            if (tempCounter > equalSignCounter)
+                                equalSignCounter = tempCounter;
+                        }
+                    }
+                    std::string equalSigns = "";
+                    for(unsigned int i = 0; i < equalSignCounter; i++)
+                    {
+                        equalSigns += "=";
+                    }
+                    output << "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
+                    start = end + 5;
+                }
+                else
+                {
+                    output << text.substr(start, end - start);
+                    start = end + 2;
+                }
+
+                bInPrintFunction = !bInPrintFunction;
+            }
+            while (end != std::string::npos);
+        }
+
+        return output.str();
+    }
+}
Index: code/trunk/src/libraries/core/Loader.h
===================================================================
--- code/trunk/src/libraries/core/Loader.h	(revision 5781)
+++ code/trunk/src/libraries/core/Loader.h	(revision 5781)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Loader_H__
+#define _Loader_H__
+
+#include "CorePrereqs.h"
+
+#include <vector>
+#include "ClassTreeMask.h"
+
+namespace orxonox
+{
+    class _CoreExport Loader
+    {
+        public:
+            static bool open(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static void close();
+            static void close(const XMLFile* file);
+
+            static void add(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static void remove(const XMLFile* file);
+
+            static bool load(const ClassTreeMask& mask = ClassTreeMask());
+            static void unload(const ClassTreeMask& mask = ClassTreeMask());
+            static bool reload(const ClassTreeMask& mask = ClassTreeMask());
+
+            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+
+            static std::string replaceLuaTags(const std::string& text);
+
+            static ClassTreeMask currentMask_s;
+
+        private:
+            static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s;
+    };
+}
+
+#endif /* _Loader_H__ */
Index: code/trunk/src/libraries/core/LuaState.cc
===================================================================
--- code/trunk/src/libraries/core/LuaState.cc	(revision 5774)
+++ code/trunk/src/libraries/core/LuaState.cc	(revision 5781)
@@ -30,5 +30,4 @@
 #include "LuaState.h"
 
-#include <boost/filesystem.hpp>
 #include <tolua/tolua++.h>
 extern "C" {
@@ -39,4 +38,5 @@
 #include "util/Debug.h"
 #include "Core.h"
+#include "Resource.h"
 #include "ToluaBindCore.h"
 
@@ -71,4 +71,6 @@
         // Create dummy file info
         sourceFileInfo_.reset(new ResourceInfo());
+        sourceFileInfo_->group = "General";
+        sourceFileInfo_->size = 0;
 
         // Push 'this' pointer
@@ -85,8 +87,9 @@
     }
 
-    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename, bool bSearchOtherPaths)
+    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
     {
         shared_ptr<ResourceInfo> sourceInfo;
-        sourceInfo = this->getFileInfo(filename);
+        if (resourceGroup != "NoResourceGroupProvided")
+            sourceInfo = Resource::getInfo(filename, resourceGroup);
 
         // Continue search if not explicitely forbidden
@@ -94,9 +97,9 @@
         {
             // Call might be relative to the file currently being processed
-            sourceInfo = this->getFileInfo(sourceFileInfo_->path + filename);
+            sourceInfo = Resource::getInfo(sourceFileInfo_->path + filename, sourceFileInfo_->group);
             if (sourceInfo == NULL)
             {
                 // Maybe find something in the same group but in the root path
-                sourceInfo = this->getFileInfo(filename);
+                sourceInfo = Resource::getInfo(filename, sourceFileInfo_->group);
             }
         }
@@ -104,34 +107,12 @@
     }
 
-    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename)
-    {
-        boost::filesystem::path filepath = Core::getDataPath() / "lua" / filename;
-        if (boost::filesystem::exists(filepath))
-        {
-            shared_ptr<ResourceInfo> info(new ResourceInfo());
-            info->filename = filepath.string();
-            info->path = filepath.branch_path().string();
-            info->basename = filepath.leaf();
-            return info;
-        }
-        else
-            return shared_ptr<ResourceInfo>();
-    }
-
-    std::string LuaState::loadFile(const std::string& filename)
-    {
-        std::ifstream file(filename.c_str());
-        std::ostringstream oss;
-        oss << file.rdbuf();
-        return oss.str();
-    }
-
-    void LuaState::includeFile(const std::string& filename, bool bSearchOtherPaths)
-    {
-        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, bSearchOtherPaths);
+    void LuaState::includeFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
         if (sourceInfo != NULL)
-            this->includeString(this->loadFile(sourceInfo->filename), sourceInfo);
-        else
-            COUT(2) << "LuaState: Cannot include file '" << filename << std::endl;
+            this->includeString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
+        else
+            COUT(2) << "LuaState: Cannot include file '" << filename << "' in resource group '"
+                    << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
     }
 
@@ -148,11 +129,12 @@
     }
 
-    void LuaState::doFile(const std::string& filename, bool bSearchOtherPaths)
-    {
-        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, bSearchOtherPaths);
+    void LuaState::doFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
         if (sourceInfo != NULL)
-            this->doString(this->loadFile(sourceInfo->filename), sourceInfo);
-        else
-            COUT(2) << "LuaState: Cannot do file '" << filename << std::endl;
+            this->doString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
+        else
+            COUT(2) << "LuaState: Cannot do file '" << filename << "' in resource group '"
+                << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
     }
 
@@ -204,7 +186,7 @@
     }
 
-    bool LuaState::fileExists(const std::string& filename, bool bSearchOtherPaths)
-    {
-        shared_ptr<ResourceInfo> info =  this->getFileInfo(filename, bSearchOtherPaths);
+    bool LuaState::fileExists(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> info =  this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
         if (info == NULL)
             return false;
Index: code/trunk/src/libraries/core/LuaState.h
===================================================================
--- code/trunk/src/libraries/core/LuaState.h	(revision 5774)
+++ code/trunk/src/libraries/core/LuaState.h	(revision 5781)
@@ -45,15 +45,4 @@
 namespace orxonox
 {
-    //! Stores basic information about a File
-    struct ResourceInfo
-    {
-        //! The file's fully qualified name
-        std::string filename;
-        //! Path name; separated by '/' and ending with '/'
-        std::string path;
-        //! Base filename
-        std::string basename;
-    };
-
     /**
     @brief
@@ -67,13 +56,13 @@
         ~LuaState();
 
-        void doFile(const std::string& filename, bool bSearchOtherPaths = true); // tolua_export
+        void doFile(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
         void doString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo = shared_ptr<ResourceInfo>());
 
-        void includeFile(const std::string& filename, bool bSearchOtherPaths = true); // tolua_export
+        void includeFile(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
         void includeString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo = shared_ptr<ResourceInfo>());
 
         void luaPrint(const std::string& str); // tolua_export
         void luaLog(unsigned int level, const std::string& message); // tolua_export
-        bool fileExists(const std::string& filename, bool bSearchOtherPaths = true); // tolua_export
+        bool fileExists(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
 
         const std::stringstream& getOutput() const { return output_; }
@@ -89,7 +78,5 @@
 
     private:
-        shared_ptr<ResourceInfo> getFileInfo(const std::string& filename, bool bSearchOtherPaths);
-        shared_ptr<ResourceInfo> getFileInfo(const std::string& filename);
-        std::string loadFile(const std::string& filename);
+        shared_ptr<ResourceInfo> getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths);
 
 #if LUA_VERSION_NUM != 501
Index: code/trunk/src/libraries/core/MemoryArchive.cc
===================================================================
--- code/trunk/src/libraries/core/MemoryArchive.cc	(revision 5781)
+++ code/trunk/src/libraries/core/MemoryArchive.cc	(revision 5781)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MemoryArchive.h"
+
+#if OGRE_VERSION < 0x010600
+
+#include <OgreException.h>
+#include <boost/filesystem.hpp>
+
+namespace orxonox
+{
+    using namespace Ogre;
+
+    MemoryArchive::ArchiveMap MemoryArchive::archives_s;
+
+    void MemoryArchive::load()
+    {
+        if (archives_s.find(this->getName()) == archives_s.end())
+            OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, this->getName() + " - MemoryArchive not found.", "MemoryArchive");
+    }
+
+    DataStreamPtr MemoryArchive::open(const String& filename) const
+    {
+        const FileMap& files = archives_s[this->getName()];
+        FileMap::const_iterator itFile = files.find(filename);
+        if (itFile == files.end())
+            return DataStreamPtr();
+        else
+            return MemoryDataStreamPtr(new MemoryDataStream(itFile->second.first.get(), itFile->second.second));
+    }
+
+    void MemoryArchive::findFiles(const String& pattern, bool bRecursive, 
+        bool bDirs, StringVector* simpleList, FileInfoList* detailList)
+    {
+        const FileMap& files = archives_s[this->getName()];
+
+        for (FileMap::const_iterator it = files.begin(); it != files.end(); ++it)
+        {
+            boost::filesystem::path file = it->first;
+            // Check pattern
+            if (!StringUtil::match(file.string(), pattern, true))
+                continue;
+            if (bDirs)
+                file = file.parent_path();
+            if (file.empty())
+                continue;
+            if (file.has_parent_path() && !bRecursive)
+                continue;
+            if (simpleList)
+                simpleList->push_back(file.string());
+            if (detailList)
+            {
+                FileInfo fi;
+                fi.archive = this;
+                fi.filename = file.string();
+                fi.basename = file.filename();
+                fi.path = file.parent_path().string();
+                fi.compressedSize = it->second.second;
+                fi.uncompressedSize = it->second.second;
+                detailList->push_back(fi);
+            }
+        }
+    }
+    StringVectorPtr MemoryArchive::list(bool recursive, bool dirs)
+    {
+        StringVectorPtr ret(new StringVector());
+        findFiles("*", recursive, dirs, ret.getPointer(), 0);
+        return ret;
+    }
+
+    FileInfoListPtr MemoryArchive::listFileInfo(bool recursive, bool dirs)
+    {
+        FileInfoListPtr ret(new FileInfoList());
+        findFiles("*", recursive, dirs, 0, ret.getPointer());
+        return ret;
+    }
+
+    StringVectorPtr MemoryArchive::find(const String& pattern,
+                                            bool recursive, bool dirs)
+    {
+        StringVectorPtr ret(new StringVector());
+        findFiles(pattern, recursive, dirs, ret.getPointer(), 0);
+        return ret;
+    }
+
+    FileInfoListPtr MemoryArchive::findFileInfo(const String& pattern, 
+        bool recursive, bool dirs)
+    {
+        FileInfoListPtr ret(new FileInfoList());
+        findFiles(pattern, recursive, dirs, 0, ret.getPointer());
+        return ret;
+    }
+
+    bool MemoryArchive::exists(const String& filename)
+	{
+        const FileMap& files = archives_s[this->getName()];
+        return files.find(filename) != files.end();
+	}
+
+    const Ogre::String& MemoryArchiveFactory::getType(void) const
+    {
+        static std::string result("Memory");
+        return result;
+    }
+}
+
+#endif /* OGRE_VERSION < 0x010600 */
Index: code/trunk/src/libraries/core/MemoryArchive.h
===================================================================
--- code/trunk/src/libraries/core/MemoryArchive.h	(revision 5781)
+++ code/trunk/src/libraries/core/MemoryArchive.h	(revision 5781)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MemoryArchive_H__
+#define _MemoryArchive_H__
+
+#include "CorePrereqs.h"
+#include <OgrePrerequisites.h>
+
+#if OGRE_VERSION < 0x010600
+
+#include <map>
+#include <OgreArchive.h>
+#include <OgreArchiveFactory.h>
+#include <boost/shared_array.hpp>
+
+namespace orxonox
+{
+    /**
+    @brief
+        Provides a simple mechanism of 'memory mapped IO', but compatible for Ogre 1.4
+
+        Files are stored as shared_array<char> in a static map with the archive names
+        (imaging the different archives as resource locations). This map then contains
+        yet another map with the actual files.
+        If you want to know why we make such a fuss, contact GraphicsManager::upgradeToGraphics()
+        for more information.
+    */
+    class MemoryArchive : public Ogre::Archive
+    {
+    public:
+        MemoryArchive(const Ogre::String& name, const Ogre::String& archiveType) : Ogre::Archive(name, archiveType) { }
+        ~MemoryArchive() { }
+
+        bool isCaseSensitive(void) const { return true; }
+
+        void load();
+        void unload() { }
+
+        Ogre::DataStreamPtr open(const Ogre::String& filename) const;
+
+        Ogre::StringVectorPtr list(bool recursive = true, bool dirs = false);
+        Ogre::FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false);
+
+        Ogre::StringVectorPtr find(const Ogre::String& pattern, bool recursive = true,
+            bool dirs = false);
+        Ogre::FileInfoListPtr findFileInfo(const Ogre::String& pattern, bool recursive = true,
+            bool dirs = false);
+
+        bool exists(const Ogre::String& filename);
+
+        static void addFile(const std::string& archiveName, const std::string& filename, shared_array<char> content, size_t size)
+            { archives_s[archiveName][filename] = std::make_pair(content, size); }
+
+    private:
+        void findFiles(const Ogre::String& pattern, bool bRecursive, 
+            bool bDirs, Ogre::StringVector* simpleList, Ogre::FileInfoList* detailList);
+
+        typedef std::map<std::string, std::pair<shared_array<char>, size_t> > FileMap;
+        typedef std::map<std::string, FileMap> ArchiveMap;
+        static ArchiveMap archives_s;
+    };
+
+    //! Specialisation of ArchiveFactory for MemoryArchive.
+    class _CoreExport MemoryArchiveFactory : public Ogre::ArchiveFactory
+    {
+    public:
+        const Ogre::String& getType(void) const;
+        Ogre::Archive* createInstance(const Ogre::String& name) { return new MemoryArchive(name, "Memory"); }
+        void destroyInstance(Ogre::Archive* arch)               { delete arch; }
+    };
+}
+
+#endif /* OGRE_VERSION < 0x010600 */
+
+#endif /* _MemoryArchive_H__ */
Index: code/trunk/src/libraries/core/Namespace.cc
===================================================================
--- code/trunk/src/libraries/core/Namespace.cc	(revision 5781)
+++ code/trunk/src/libraries/core/Namespace.cc	(revision 5781)
@@ -0,0 +1,182 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Namespace.h"
+
+#include <set>
+
+#include "NamespaceNode.h"
+#include "CoreIncludes.h"
+#include "XMLPort.h"
+#include "util/SubString.h"
+
+namespace orxonox
+{
+    CreateFactory(Namespace);
+
+    Namespace::Namespace(BaseObject* creator) : BaseObject(creator),
+      bAutogeneratedFileRootNamespace_(false),
+      bRoot_(false),
+      operator_("or")
+    {
+        RegisterObject(Namespace);
+    }
+
+    Namespace::~Namespace()
+    {
+        if (this->bRoot_)
+            for (std::set<NamespaceNode*>::iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); ++it)
+                delete (*it);
+    }
+
+    /**
+        @brief XML loading and saving.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+        @return The XML-element
+    */
+    void Namespace::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Namespace, XMLPort, xmlelement, mode);
+
+        std::string name = this->getName();
+        size_t pos = 0;
+        while ((pos = name.find(',')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        while ((pos = name.find(';')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        while ((pos = name.find('\n')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        while ((pos = name.find('\t')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        SubString tokens(name, " ", "", false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (this->bRoot_)
+        {
+            this->representingNamespaces_.insert(new NamespaceNode(this->getName()));
+        }
+        else
+        {
+            for (unsigned int i = 0; i < tokens.size(); i++)
+            {
+                for (std::set<NamespaceNode*>::iterator it = this->getNamespace()->representingNamespaces_.begin(); it != this->getNamespace()->representingNamespaces_.end(); ++it)
+                {
+                    std::set<NamespaceNode*> temp = (*it)->getNodeRelative(tokens[i]);
+                    this->representingNamespaces_.insert(temp.begin(), temp.end());
+                }
+            }
+        }
+
+        XMLPortParam(Namespace, "operator", setOperator, getOperator, xmlelement, mode);
+        XMLPortParam(Namespace, "bAutogenerated", setAutogenerated, isAutogenerated, xmlelement, mode);
+
+        if (this->bAutogeneratedFileRootNamespace_)
+        {
+            for (std::set<NamespaceNode*>::iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); ++it)
+            {
+                (*it)->setRoot(true);
+                (*it)->setHidden(true);
+            }
+        }
+
+        XMLPortObjectExtended(Namespace, BaseObject, "", loadObjects, saveObjects, xmlelement, mode, true, false);
+    }
+
+    void Namespace::loadObjects(BaseObject* object)
+    {
+        object->setNamespace(this);
+    }
+
+    const BaseObject* Namespace::saveObjects(unsigned int index) const
+    {
+        return 0; // todo
+    }
+
+    bool Namespace::includes(const Namespace* ns) const
+    {
+        for (std::set<NamespaceNode*>::const_iterator it1 = this->representingNamespaces_.begin(); it1 != this->representingNamespaces_.end(); ++it1)
+        {
+            for (std::set<NamespaceNode*>::const_iterator it2 = ns->representingNamespaces_.begin(); it2 != ns->representingNamespaces_.end(); ++it2)
+            {
+                if ((*it1)->includes(*it2))
+                {
+                    if (this->operator_ == "or")
+                        return true;
+
+                    if (this->operator_ == "not")
+                        return false;
+                }
+                else
+                {
+                    if (this->operator_ == "and")
+                        return false;
+                }
+            }
+        }
+
+        if (this->operator_ == "or")
+            return false;
+        else if (this->operator_ == "and")
+            return true;
+        else if (this->operator_ == "not")
+            return true;
+
+        return false;
+    }
+
+    std::string Namespace::toString() const
+    {
+        std::string output;
+
+        int i = 0;
+        for (std::set<NamespaceNode*>::const_iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); i++, ++it)
+        {
+            if (i > 0)
+                output += " / ";
+
+            output += (*it)->toString();
+        }
+
+        return output;
+    }
+
+    std::string Namespace::toString(const std::string& indentation) const
+    {
+        std::string output;
+
+        int i = 0;
+        for (std::set<NamespaceNode*>::const_iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); i++, ++it)
+        {
+            if (i > 0)
+                output += "\n";
+
+            output += (*it)->toString(indentation);
+        }
+
+        return output;
+    }
+}
Index: code/trunk/src/libraries/core/Namespace.h
===================================================================
--- code/trunk/src/libraries/core/Namespace.h	(revision 5781)
+++ code/trunk/src/libraries/core/Namespace.h	(revision 5781)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Namespace_H__
+#define _Namespace_H__
+
+#include "CorePrereqs.h"
+
+#include <set>
+#include <string>
+#include "BaseObject.h"
+
+namespace orxonox
+{
+    class Namespace : public BaseObject
+    {
+        public:
+            Namespace(BaseObject* creator);
+            virtual ~Namespace();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void loadObjects(BaseObject* object);
+            const BaseObject* saveObjects(unsigned int index) const;
+
+            void setAutogenerated(bool bAutogenerated)
+                { this->bAutogeneratedFileRootNamespace_ = bAutogenerated; }
+            bool isAutogenerated() const
+                { return this->bAutogeneratedFileRootNamespace_; }
+
+            void setOperator(const std::string& op)
+                { this->operator_ = op; }
+            const std::string& getOperator() const
+                { return this->operator_; }
+
+            void setRoot(bool bRoot)
+                { this->bRoot_ = bRoot; }
+
+            bool includes(const Namespace* ns) const;
+            bool isIncludedIn(const Namespace* ns) const { return ns->includes(this); }
+
+            std::string toString() const;
+            std::string toString(const std::string& indentation) const;
+
+        private:
+            std::set<NamespaceNode*> representingNamespaces_;
+            bool bAutogeneratedFileRootNamespace_;
+            bool bRoot_;
+            std::string operator_;
+    };
+}
+
+#endif /* _Namespace_H__ */
Index: code/trunk/src/libraries/core/NamespaceNode.cc
===================================================================
--- code/trunk/src/libraries/core/NamespaceNode.cc	(revision 5781)
+++ code/trunk/src/libraries/core/NamespaceNode.cc	(revision 5781)
@@ -0,0 +1,174 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NamespaceNode.h"
+#include "util/Debug.h"
+
+namespace orxonox
+{
+    NamespaceNode::NamespaceNode(const std::string& name, NamespaceNode* parent)
+    {
+        this->name_ = name;
+        this->parent_ = parent;
+        this->bRoot_ = false;
+        this->bHidden_ = false;
+    }
+
+    NamespaceNode::~NamespaceNode()
+    {
+        for (std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); )
+            delete ((*(it++)).second);
+    }
+
+    std::set<NamespaceNode*> NamespaceNode::getNodeRelative(const std::string& name)
+    {
+        std::set<NamespaceNode*> nodes;
+
+        if ((name.size() == 0) || (name == ""))
+        {
+            nodes.insert(this);
+        }
+        else
+        {
+            size_t pos = name.find("::");
+            std::string firstPart = name;
+            std::string secondPart;
+
+            if (pos != std::string::npos)
+            {
+                firstPart = name.substr(0, pos);
+                secondPart = name.substr(pos + 2, std::string::npos);
+            }
+
+            if (firstPart == "..")
+            {
+                if (this->bRoot_)
+                {
+                    COUT(2) << "Warning: Can't go to enclosing namespace with '..' operator in namespace " << this->name_ << ", namespace is root." << std::endl;
+                    nodes = this->getNodeRelative(secondPart);
+                }
+                else if (!this->parent_)
+                {
+                    COUT(2) << "Warning: Can't go to enclosing namespace with '..' operator in namespace " << this->name_ << ", no parent namespace set." << std::endl;
+                    nodes = this->getNodeRelative(secondPart);
+                }
+                else
+                {
+                    nodes = this->parent_->getNodeRelative(secondPart);
+                }
+            }
+            else if (name.find('@') != 0)
+            {
+                std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.find(firstPart);
+                if (it == this->subnodes_.end())
+                    it = this->subnodes_.insert(this->subnodes_.begin(), std::pair<std::string, NamespaceNode*>(firstPart, new NamespaceNode(firstPart, this)));
+
+                if ((*it).second->isHidden())
+                {
+                    COUT(2) << "Warning: Subnamespace '" << firstPart << "' in namespace '" << this->name_ << "' is hidden and can't be accessed." << std::endl;
+                    nodes.insert(this);
+                }
+                else
+                {
+                    nodes = (*it).second->getNodeRelative(secondPart);
+                }
+            }
+            else
+            {
+                bool bFoundMatchingNamespace = false;
+
+                for (std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
+                {
+                    if ((*it).first.find(firstPart) == ((*it).first.size() - firstPart.size()))
+                    {
+                        std::set<NamespaceNode*> temp2 = (*it).second->getNodeRelative(secondPart);
+                        nodes.insert(temp2.begin(), temp2.end());
+                        bFoundMatchingNamespace = true;
+                    }
+                }
+
+                if (!bFoundMatchingNamespace)
+                {
+                    COUT(2) << "Warning: No file included with name '" << firstPart.substr(1, std::string::npos) << "' at this part of the level file, using parent namespace instead." << std::endl;
+                    nodes = this->getNodeRelative(secondPart);
+                }
+            }
+        }
+
+        return nodes;
+    }
+
+    bool NamespaceNode::includes(const NamespaceNode* ns) const
+    {
+        if (ns == this)
+        {
+            return true;
+        }
+        else
+        {
+            for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
+                if ((*it).second->includes(ns))
+                    return true;
+        }
+
+        return false;
+    }
+
+    std::string NamespaceNode::toString() const
+    {
+        std::string output = this->name_;
+
+        if (this->subnodes_.size() > 0)
+        {
+            output += " (";
+
+            int i = 0;
+            for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); i++, ++it)
+            {
+                if (i > 0)
+                    output += ", ";
+
+                output += (*it).second->toString();
+            }
+
+            output += ")";
+        }
+
+        return output;
+    }
+
+    std::string NamespaceNode::toString(const std::string& indentation) const
+    {
+        std::string output = (indentation + this->name_ + "\n");
+
+        for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
+            output += (*it).second->toString(indentation + "  ");
+
+        return output;
+    }
+}
Index: code/trunk/src/libraries/core/NamespaceNode.h
===================================================================
--- code/trunk/src/libraries/core/NamespaceNode.h	(revision 5781)
+++ code/trunk/src/libraries/core/NamespaceNode.h	(revision 5781)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NamespaceNode_H__
+#define _NamespaceNode_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+namespace orxonox
+{
+    class NamespaceNode
+    {
+        public:
+            NamespaceNode(const std::string& name, NamespaceNode* parent = 0);
+            ~NamespaceNode();
+
+            std::set<NamespaceNode*> getNodeRelative(const std::string& name);
+
+            void setRoot(bool bRoot) { this->bRoot_ = bRoot; }
+            void setHidden(bool bHidden) { this->bHidden_ = bHidden; }
+
+            bool isRoot() const { return this->bRoot_; }
+            bool isHidden() const { return this->bHidden_; }
+
+            bool includes(const NamespaceNode*) const;
+
+            std::string toString() const;
+            std::string toString(const std::string& indentation) const;
+
+        private:
+            std::string name_;
+            NamespaceNode* parent_;
+            std::map<std::string, NamespaceNode*> subnodes_;
+            bool bHidden_;
+            bool bRoot_;
+    };
+}
+
+#endif /* _NamespaceNode_H__ */
Index: code/trunk/src/libraries/core/Resource.cc
===================================================================
--- code/trunk/src/libraries/core/Resource.cc	(revision 5781)
+++ code/trunk/src/libraries/core/Resource.cc	(revision 5781)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Resource.h"
+#include <OgreResourceGroupManager.h>
+
+namespace orxonox
+{
+    std::string Resource::DEFAULT_GROUP(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+
+    DataStreamPtr Resource::open(const std::string& name, const std::string& group, bool bSearchGroupsIfNotFound)
+    {
+        return Ogre::ResourceGroupManager::getSingleton().openResource(name, group, bSearchGroupsIfNotFound);
+    }
+
+    DataStreamListPtr Resource::openMulti(const std::string& pattern, const std::string& group)
+    {
+        return Ogre::ResourceGroupManager::getSingleton().openResources(pattern, group);
+    }
+
+    bool Resource::exists(const std::string& name, const std::string& group)
+    {
+        return Ogre::ResourceGroupManager::getSingleton().resourceExists(group, name);
+    }
+
+    shared_ptr<ResourceInfo> Resource::getInfo(const std::string& name, const std::string& group)
+    {
+        Ogre::FileInfoListPtr infos = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(group, name);
+        for (std::vector<Ogre::FileInfo>::const_iterator it = infos->begin(); it != infos->end(); ++it)
+        {
+            if (it->filename == name)
+            {
+                shared_ptr<ResourceInfo> ptr(new ResourceInfo());
+                ptr->filename = name;
+                ptr->path = it->path;
+                ptr->basename = it->basename;
+                ptr->group = group;
+                ptr->size = it->uncompressedSize;
+                return ptr;
+            }
+        }
+        return shared_ptr<ResourceInfo>();
+    }
+}
Index: code/trunk/src/libraries/core/Resource.h
===================================================================
--- code/trunk/src/libraries/core/Resource.h	(revision 5781)
+++ code/trunk/src/libraries/core/Resource.h	(revision 5781)
@@ -0,0 +1,134 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Resource_H__
+#define _Core_Resource_H__
+
+#include "CorePrereqs.h"
+
+#include <boost/shared_ptr.hpp>
+#include <OgreDataStream.h>
+
+namespace orxonox
+{
+    // Import the Ogre::DataStreamList
+    using Ogre::DataStreamList;
+    using Ogre::DataStreamListPtr;
+
+    //! Stores basic information about a Resource from Ogre
+    struct ResourceInfo
+    {
+        //! The file's fully qualified name
+        std::string filename;
+        //! Path name; separated by '/' and ending with '/'
+        std::string path;
+        //! Base filename
+        std::string basename;
+        //! Resource group the file is in
+        std::string group;
+        //! Uncompressed size
+        size_t size;
+    };
+
+    /**
+    @brief
+        Provides simple functions to easily access the Ogre::ResourceGroupManager
+    */
+    class _CoreExport Resource
+    {
+        // Docs by Ogre::ResourceGroupManager.h
+    public:
+		/**
+        @brief
+            Open a single resource by name and return a DataStream
+            pointing at the source of the data.
+        @param name
+            The name of the resource to locate.
+            Even if resource locations are added recursively, you
+            must provide a fully qualified name to this method.
+        @param groupName
+            The name of the resource group; this determines which 
+            locations are searched. 
+        @param searchGroupsIfNotFound
+            If true, if the resource is not found in 
+            the group specified, other groups will be searched.
+        @return
+            Shared pointer to data stream containing the data. Will be
+            destroyed automatically when no longer referenced.
+		*/
+        static DataStreamPtr open(const std::string& name,
+            const std::string& group = Resource::DEFAULT_GROUP,
+            bool bSearchGroupsIfNotFound = false);
+
+		/**
+        @brief
+            Open all resources matching a given pattern (which can contain
+            the character '*' as a wildcard), and return a collection of 
+            DataStream objects on them.
+        @param pattern
+            The pattern to look for. If resource locations have been
+            added recursively, subdirectories will be searched too so this
+            does not need to be fully qualified.
+        @param groupName
+            The resource group; this determines which locations
+            are searched.
+        @return
+            Shared pointer to a data stream list , will be
+            destroyed automatically when no longer referenced
+		*/
+        static DataStreamListPtr openMulti(const std::string& pattern, const std::string& group = Resource::DEFAULT_GROUP);
+
+        /**
+            Find out if the named file exists in a group. 
+        @param filename
+            Fully qualified name of the file to test for
+        @param group
+            The name of the resource group
+        */
+        static bool exists(const std::string& name, const std::string& group = Resource::DEFAULT_GROUP);
+
+        /**
+            Get struct with information about group, path and size.
+        @param filename
+            Fully qualified name of the file to test for
+        @param group
+            The name of the resource group
+        */
+        static shared_ptr<ResourceInfo> getInfo(const std::string& name, const std::string& group = Resource::DEFAULT_GROUP);
+
+        //! Name of the default resource group (usually "General")
+        static std::string DEFAULT_GROUP;
+
+    private:
+        Resource();
+        ~Resource();
+        Resource(const Resource& instance);
+    };
+}
+
+#endif /* _Core_Resource_H__ */
Index: code/trunk/src/libraries/core/Shell.cc
===================================================================
--- code/trunk/src/libraries/core/Shell.cc	(revision 5781)
+++ code/trunk/src/libraries/core/Shell.cc	(revision 5781)
@@ -0,0 +1,397 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Shell.h"
+
+#include "util/OutputHandler.h"
+#include "CommandExecutor.h"
+#include "CoreIncludes.h"
+#include "ConfigValueIncludes.h"
+#include "Core.h"
+#include "ConsoleCommand.h"
+
+#define SHELL_UPDATE_LISTENERS(function) \
+    for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ) \
+        (*(it++))->function()
+
+namespace orxonox
+{
+    SetConsoleCommand(Shell, clearShell, true);
+    SetConsoleCommand(Shell, history, true);
+
+    SetConsoleCommandShortcut(OutputHandler, log);
+    SetConsoleCommandShortcut(OutputHandler, error);
+    SetConsoleCommandShortcut(OutputHandler, warning);
+    SetConsoleCommandShortcut(OutputHandler, info);
+    SetConsoleCommandShortcut(OutputHandler, debug);
+
+    Shell* Shell::singletonPtr_s = 0;
+
+    Shell::Shell()
+    {
+        int level = Core::getSoftDebugLevel(OutputHandler::LD_Shell);
+        Core::setSoftDebugLevel(OutputHandler::LD_Shell, -1);
+
+        RegisterRootObject(Shell);
+
+        this->scrollPosition_ = 0;
+        this->maxHistoryLength_ = 100;
+        this->historyPosition_ = 0;
+        this->historyOffset_ = 0;
+        this->finishedLastLine_ = true;
+        this->bAddOutputLevel_ = false;
+
+        this->clearLines();
+
+        this->inputBuffer_ = new InputBuffer();
+        this->configureInputBuffer();
+
+        this->outputBuffer_.registerListener(this);
+        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();
+
+        Core::setSoftDebugLevel(OutputHandler::LD_Shell, level);
+    }
+
+    Shell::~Shell()
+    {
+        OutputHandler::getOutStream().setOutputBuffer(0);
+        if (this->inputBuffer_)
+            delete this->inputBuffer_;
+    }
+
+    void Shell::setConfigValues()
+    {
+        SetConfigValueGeneric(commandHistoryConfigFileType_, maxHistoryLength_, 100)
+            .callback(this, &Shell::commandHistoryLengthChanged);
+        SetConfigValueGeneric(commandHistoryConfigFileType_, historyOffset_, 0)
+            .callback(this, &Shell::commandHistoryOffsetChanged);
+        SetConfigValueVectorGeneric(commandHistoryConfigFileType_, commandHistory_, std::vector<std::string>());
+    }
+
+    void Shell::commandHistoryOffsetChanged()
+    {
+        if (this->historyOffset_ >= this->maxHistoryLength_)
+            this->historyOffset_ = 0;
+    }
+
+    void Shell::commandHistoryLengthChanged()
+    {
+        this->commandHistoryOffsetChanged();
+
+        while (this->commandHistory_.size() > this->maxHistoryLength_)
+        {
+            unsigned int index = this->commandHistory_.size() - 1;
+            this->commandHistory_.erase(this->commandHistory_.begin() + index);
+            ModifyConfigValue(commandHistory_, remove, index);
+        }
+    }
+
+    void Shell::configureInputBuffer()
+    {
+        this->inputBuffer_->registerListener(this, &Shell::inputChanged, true);
+        this->inputBuffer_->registerListener(this, &Shell::execute, '\r', false);
+        this->inputBuffer_->registerListener(this, &Shell::hintandcomplete, '\t', true);
+        this->inputBuffer_->registerListener(this, &Shell::backspace, '\b', true);
+        this->inputBuffer_->registerListener(this, &Shell::deletechar, KeyCode::Delete);
+        this->inputBuffer_->registerListener(this, &Shell::exit, static_cast<char>(27), true);
+        this->inputBuffer_->registerListener(this, &Shell::cursor_right, KeyCode::Right);
+        this->inputBuffer_->registerListener(this, &Shell::cursor_left, KeyCode::Left);
+        this->inputBuffer_->registerListener(this, &Shell::cursor_end, KeyCode::End);
+        this->inputBuffer_->registerListener(this, &Shell::cursor_home, KeyCode::Home);
+        this->inputBuffer_->registerListener(this, &Shell::history_up, KeyCode::Up);
+        this->inputBuffer_->registerListener(this, &Shell::history_down, KeyCode::Down);
+        this->inputBuffer_->registerListener(this, &Shell::scroll_up, KeyCode::PageUp);
+        this->inputBuffer_->registerListener(this, &Shell::scroll_down, KeyCode::PageDown);
+    }
+
+    void Shell::clearShell()
+    {
+        Shell::getInstance().clearLines();
+    }
+
+    void Shell::history()
+    {
+        Shell& instance = Shell::getInstance();
+
+        for (unsigned int i = instance.historyOffset_; i < instance.commandHistory_.size(); ++i)
+            instance.addLine(instance.commandHistory_[i], -1);
+        for (unsigned int i =  0; i < instance.historyOffset_; ++i)
+            instance.addLine(instance.commandHistory_[i], -1);
+    }
+
+    void Shell::registerListener(ShellListener* listener)
+    {
+        this->listeners_.insert(this->listeners_.end(), listener);
+    }
+
+    void Shell::unregisterListener(ShellListener* listener)
+    {
+        for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+        {
+            if ((*it) == listener)
+                this->listeners_.erase(it++);
+            else
+                ++it;
+        }
+    }
+
+    void Shell::setCursorPosition(unsigned int cursor)
+    {
+        this->inputBuffer_->setCursorPosition(cursor);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::setInput(const std::string& input)
+    {
+        this->inputBuffer_->set(input);
+        this->inputChanged();
+    }
+
+    void Shell::addLine(const std::string& line, int level)
+    {
+        int original_level = OutputHandler::getOutStream().getOutputLevel();
+        OutputHandler::getOutStream().setOutputLevel(level);
+
+        if (!this->finishedLastLine_)
+            this->outputBuffer_ << std::endl;
+
+        this->outputBuffer_ << line << std::endl;
+        OutputHandler::getOutStream().setOutputLevel(original_level);
+    }
+
+    void Shell::clearLines()
+    {
+        this->lines_.clear();
+        this->scrollIterator_ = this->lines_.begin();
+
+        this->scrollPosition_ = 0;
+        this->finishedLastLine_ = true;
+
+        SHELL_UPDATE_LISTENERS(linesChanged);
+    }
+
+    std::list<std::string>::const_iterator Shell::getNewestLineIterator() const
+    {
+        if (this->scrollPosition_)
+            return this->scrollIterator_;
+        else
+            return this->lines_.begin();
+    }
+
+    std::list<std::string>::const_iterator Shell::getEndIterator() const
+    {
+        return this->lines_.end();
+    }
+
+    void Shell::addToHistory(const std::string& command)
+    {
+        ModifyConfigValue(commandHistory_, set, this->historyOffset_, command);
+        this->historyPosition_ = 0;
+        ModifyConfigValue(historyOffset_, set, (this->historyOffset_ + 1) % this->maxHistoryLength_);
+    }
+
+    std::string Shell::getFromHistory() const
+    {
+        unsigned int index = mod(static_cast<int>(this->historyOffset_) - static_cast<int>(this->historyPosition_), this->maxHistoryLength_);
+        if (index < this->commandHistory_.size() && this->historyPosition_ != 0)
+            return this->commandHistory_[index];
+        else
+            return "";
+    }
+
+    void Shell::outputChanged()
+    {
+        std::string output;
+        bool newline;
+        do
+        {
+            newline = this->outputBuffer_.getLine(&output);
+
+            if (!newline && output == "")
+                break;
+
+            if (this->finishedLastLine_)
+            {
+                if (this->bAddOutputLevel_)
+                    output.insert(0, 1, static_cast<char>(OutputHandler::getOutStream().getOutputLevel()));
+
+                this->lines_.insert(this->lines_.begin(), output);
+
+                if (this->scrollPosition_)
+                    this->scrollPosition_++;
+                else
+                    this->scrollIterator_ = this->lines_.begin();
+
+                this->finishedLastLine_ = newline;
+
+                if (!this->scrollPosition_)
+                {
+                    SHELL_UPDATE_LISTENERS(lineAdded);
+                }
+            }
+            else
+            {
+                (*this->lines_.begin()) += output;
+                this->finishedLastLine_ = newline;
+                SHELL_UPDATE_LISTENERS(onlyLastLineChanged);
+            }
+
+        } while (newline);
+    }
+
+    void Shell::inputChanged()
+    {
+        SHELL_UPDATE_LISTENERS(inputChanged);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::execute()
+    {
+        this->addToHistory(this->inputBuffer_->get());
+        this->addLine(this->inputBuffer_->get(), 0);
+
+        if (!CommandExecutor::execute(this->inputBuffer_->get()))
+            this->addLine("Error: Can't execute \"" + this->inputBuffer_->get() + "\".", 1);
+
+        this->clear();
+    }
+
+    void Shell::hintandcomplete()
+    {
+        this->inputBuffer_->set(CommandExecutor::complete(this->inputBuffer_->get()));
+        this->addLine(CommandExecutor::hint(this->inputBuffer_->get()), -1);
+
+        this->inputChanged();
+    }
+
+    void Shell::backspace()
+    {
+        this->inputBuffer_->removeBehindCursor();
+        SHELL_UPDATE_LISTENERS(inputChanged);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::deletechar()
+    {
+        this->inputBuffer_->removeAtCursor();
+        SHELL_UPDATE_LISTENERS(inputChanged);
+    }
+
+    void Shell::clear()
+    {
+        this->inputBuffer_->clear();
+        this->historyPosition_ = 0;
+        SHELL_UPDATE_LISTENERS(inputChanged);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::cursor_right()
+    {
+        this->inputBuffer_->increaseCursor();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::cursor_left()
+    {
+        this->inputBuffer_->decreaseCursor();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::cursor_end()
+    {
+        this->inputBuffer_->setCursorToEnd();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::cursor_home()
+    {
+        this->inputBuffer_->setCursorToBegin();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::history_up()
+    {
+        if (this->historyPosition_ < this->commandHistory_.size())
+        {
+            this->historyPosition_++;
+            this->inputBuffer_->set(this->getFromHistory());
+        }
+    }
+
+    void Shell::history_down()
+    {
+        if (this->historyPosition_ > 0)
+        {
+            this->historyPosition_--;
+            this->inputBuffer_->set(this->getFromHistory());
+        }
+    }
+
+    void Shell::scroll_up()
+    {
+        if (this->scrollIterator_ != this->lines_.end())
+        {
+            ++this->scrollIterator_;
+            ++this->scrollPosition_;
+
+            SHELL_UPDATE_LISTENERS(linesChanged);
+        }
+    }
+
+    void Shell::scroll_down()
+    {
+        if (this->scrollIterator_ != this->lines_.begin())
+        {
+            --this->scrollIterator_;
+            --this->scrollPosition_;
+
+            SHELL_UPDATE_LISTENERS(linesChanged);
+        }
+    }
+
+    void Shell::exit()
+    {
+        if (this->inputBuffer_->getSize() > 0)
+        {
+            this->clear();
+            return;
+        }
+
+        this->clear();
+        this->scrollPosition_ = 0;
+        this->scrollIterator_ = this->lines_.begin();
+
+        SHELL_UPDATE_LISTENERS(exit);
+    }
+}
Index: code/trunk/src/libraries/core/Shell.h
===================================================================
--- code/trunk/src/libraries/core/Shell.h	(revision 5781)
+++ code/trunk/src/libraries/core/Shell.h	(revision 5781)
@@ -0,0 +1,153 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Shell_H__
+#define _Shell_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "util/OutputBuffer.h"
+#include "input/InputBuffer.h"
+#include "OrxonoxClass.h"
+#include "ConfigFileManager.h"
+
+namespace orxonox
+{
+    class _CoreExport ShellListener
+    {
+        friend class Shell;
+
+        public:
+            virtual ~ShellListener() {}
+
+        private:
+            virtual void linesChanged() {}
+            virtual void onlyLastLineChanged() {}
+            virtual void lineAdded() {}
+            virtual void inputChanged() {}
+            virtual void cursorChanged() {}
+            virtual void exit() {}
+    };
+
+    class _CoreExport Shell : public Singleton<Shell>, virtual public OrxonoxClass, public OutputBufferListener
+    {
+        friend class Singleton<Shell>;
+        public:
+            Shell();
+            virtual ~Shell();
+
+            static void clearShell();
+            static void history();
+
+            virtual void setConfigValues();
+            void commandHistoryOffsetChanged();
+            void commandHistoryLengthChanged();
+
+            void registerListener(ShellListener* listener);
+            void unregisterListener(ShellListener* listener);
+
+            inline InputBuffer* getInputBuffer()
+                { return this->inputBuffer_; }
+            inline OutputBuffer& getOutputBuffer()
+                { return this->outputBuffer_; }
+
+            void setCursorPosition(unsigned int cursor);
+            inline unsigned int getCursorPosition() const
+                { return this->inputBuffer_->getCursorPosition(); }
+
+            void setInput(const std::string& input);
+
+            inline void clearInput()
+                { this->setInput(""); }
+            inline std::string getInput() const
+                { return this->inputBuffer_->get(); }
+
+            std::list<std::string>::const_iterator getNewestLineIterator() const;
+            std::list<std::string>::const_iterator getEndIterator() const;
+
+            void addLine(const std::string& line, int level = 0);
+            void clearLines();
+
+            inline unsigned int getNumLines() const
+                { return this->lines_.size(); }
+            inline unsigned int getScrollPosition() const
+                { return this->scrollPosition_; }
+
+            inline void addOutputLevel(bool bAddOutputLevel)
+                { this->bAddOutputLevel_ = bAddOutputLevel; }
+
+        private:
+            Shell(const Shell& other);
+
+            void configureInputBuffer();
+
+            void addToHistory(const std::string& command);
+            std::string getFromHistory() const;
+
+            virtual void outputChanged();
+            void inputChanged();
+            void execute();
+            void hintandcomplete();
+            void backspace();
+            void deletechar();
+            void clear();
+            void cursor_right();
+            void cursor_left();
+            void cursor_end();
+            void cursor_home();
+            void history_up();
+            void history_down();
+            void scroll_up();
+            void scroll_down();
+            void exit();
+
+            std::list<ShellListener*> listeners_;
+            InputBuffer* inputBuffer_;
+            OutputBuffer outputBuffer_;
+            bool finishedLastLine_;
+            std::list<std::string> lines_;
+            std::list<std::string>::const_iterator scrollIterator_;
+            unsigned int scrollPosition_;
+            std::vector<std::string> commandHistory_;
+            unsigned int maxHistoryLength_;
+            unsigned int historyPosition_;
+            unsigned int historyOffset_;
+            bool bAddOutputLevel_;
+
+            ConfigFileType commandHistoryConfigFileType_;
+
+            static Shell* singletonPtr_s;
+    };
+}
+
+#endif /* _Shell_H__ */
Index: code/trunk/src/libraries/core/Super.h
===================================================================
--- code/trunk/src/libraries/core/Super.h	(revision 5781)
+++ code/trunk/src/libraries/core/Super.h	(revision 5781)
@@ -0,0 +1,585 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of all super-function related macros.
+
+    This file defines all macros needed to add a new "super-function".
+    If you add a super-function, you can call SUPER(myclass, functionname) inside your
+    code and the function of the parentclass gets called. This is comparable with
+    super.functionname() in Java or other languages.
+
+    This works only with virtual functions that return nothing (void) and belong to
+    classes that have an Identifier. Arguments however are supported.
+
+    To add a new super-function, you have process 4 steps:
+
+    1) Add a new SUPER macro
+       This allows you to call the super-function in your code.
+       Location: This file (Super.h), marked with --> HERE <-- comments (1/3)
+
+    2) Call the SUPER_FUNCTION_GLOBAL_DECLARATION_PART1/2 macros.
+       This defines some global classes and templates, needed to create and call the super-functions.
+       Location: This file (Super.h), marked with --> HERE <-- comments (2/3)
+
+    3) Call the SUPER_INTRUSIVE_DECLARATION macro.
+       This will be included into the declaration of ClassIdentifier<T>.
+       Location: This file (Super.h), marked with --> HERE <-- comments (3/3)
+
+    4) Call the SUPER_FUNCTION macro.
+       This defines a partially specialized template that will decide if a class is "super" to another class.
+       If the check returns true, a SuperFunctionCaller gets created, which will be used by the SUPER macro.
+       You have to add this into the header-file of the baseclass of the super-function (the class that first
+       implements the function), below the class declaration. You can't call it directly in this file, because
+       otherwise you had to include the headerfile right here, which would cause some ugly backdependencies,
+       include loops and slower compilation.
+       Dont forget to include Super.h in the header-file.
+       Location: The header-file of the baseclass (Baseclass.h), below the class declaration
+*/
+
+#ifndef _Super_H__
+#define _Super_H__
+
+#include "CorePrereqs.h"
+
+#include "util/Debug.h"
+#include "Event.h"
+
+///////////////////////
+// Macro definitions //
+///////////////////////
+
+//// Common macros ////
+
+    /**
+        @brief Declares a new super-function by creating a specialized template. Add this below the class declaration of the baseclass.
+        @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
+        @param baseclass The baseclass of the super-function (~the root)
+        @param functionname The name of the super-function
+        @param purevirtualbase "true" if the function is pure virtual in the baseclass, "false" if the function is implemented (without "")
+    */
+    #define SUPER_FUNCTION(functionnumber, baseclass, functionname, purevirtualbase) \
+        template <class T, int templatehack2> \
+        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2> \
+        { \
+            static void check() \
+            { \
+                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0)); \
+                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check(); \
+            } \
+            \
+            static void apply(void* temp) {} \
+            \
+            static void apply(baseclass* temp) \
+            { \
+                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier(); \
+                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it) \
+                { \
+                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
+                    { \
+                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_; \
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0; \
+                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false; \
+                    } \
+                    \
+                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
+                    { \
+                        COUT(5) << "Added SuperFunctionCaller for " << #functionname << ": " << ClassIdentifier<T>::getIdentifier()->getName() << " <- " << ((ClassIdentifier<T>*)(*it))->getName() << std::endl; \
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>; \
+                    } \
+                } \
+            } \
+        }; \
+        \
+        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase(functionnumber, baseclass)
+
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND0(functionnumber, baseclass) SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDfalse(functionnumber, baseclass)
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND1(functionnumber, baseclass) SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDtrue(functionnumber, baseclass)
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDfalse(functionnumber, baseclass)
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDtrue(functionnumber, baseclass) \
+        template <int templatehack2> \
+        struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
+        { \
+            static void check() \
+            { \
+                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
+            } \
+        };
+
+
+    /*
+    //// Comments about the macro ////
+
+        // Partially specialized template (templatehack is now specialized too).
+        //
+        // This ensures the compiler takes THIS template if the header-file of the super-function
+        // is included. In any other case, the compiler just uses the fallback template which is
+        // defined in this file.
+        template <class T, templatehack2>
+        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2>
+        {
+            static void check()
+            {
+                // This call to the apply-function is the whole check. By calling the function with
+                // a T* pointer, the right function get's called.
+                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0));
+
+                // Go go the check for of next super-function (functionnumber + 1)
+                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check();
+            }
+
+            // This function gets called if T is not a child of the baseclass.
+            // The function does nothing.
+            static void apply(void* temp) {}
+
+            // This function gets called if T is a child of the baseclass and can therefore be converted.
+            // The function adds a SuperFunctionCaller to the Identifier of all subclasses of T.
+            static void apply(baseclass* temp)
+            {
+                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
+
+                // Iterate through all children
+                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it)
+                {
+                    // Check if the caller is a fallback-caller
+                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
+                    {
+                        // Delete the fallback caller an prepare to get a real caller
+                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_;
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0;
+                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false;
+                    }
+
+                    // Check if there's not already a caller
+                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
+                    {
+                        // Add the SuperFunctionCaller
+                        COUT(5) << "adding functionpointer to " << ((ClassIdentifier<T>*)(*it))->getName() << std::endl;
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>;
+                    }
+                }
+            }
+        };
+        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase
+
+
+        // The following piece of code is only added if purevirtualbase = true
+
+        // Explicit specialization of the Condition template for the baseclass to avoid
+        // errors if the function is pure virtual in the baseclass.
+        template <int templatehack2> \
+        struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
+        { \
+            // The check function acts like the fallback - it advances to the check for the next super-function (functionnumber + 1)
+            static void check() \
+            { \
+                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
+            } \
+        };
+    */
+
+    // SUPER-macro: Calls Parent::functionname() where Parent is the direct parent of classname
+    #ifdef ORXONOX_COMPILER_MSVC
+        #define SUPER(classname, functionname, ...) \
+            __super::functionname(__VA_ARGS__)
+    #else
+        #define SUPER(classname, functionname, ...) \
+            SUPER_##functionname(classname, functionname, __VA_ARGS__)
+    #endif
+
+    // helper macro: for functions without arguments
+    #define SUPER_NOARGS(classname, functionname) \
+        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this)
+
+    // helper macro: for functions with arguments
+    #define SUPER_ARGS(classname, functionname, ...) \
+        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this, __VA_ARGS__)
+
+
+//// Function-specific macros ////
+
+    /*
+        Add a macro for each super-function
+
+        Example (no arguments):
+        #define SUPER_myfunction(classname, functionname, ...) \
+            SUPER_NOARGS(classname, functionname)
+
+        Example (with arguments):
+        #define SUPER_myfunction(classname, functionname, ...) \
+            SUPER_ARGS(classname, functionname, __VA_ARGS__)
+    */
+
+    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+    #define SUPER_XMLPort(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+
+    #define SUPER_tick(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+
+    #define SUPER_changedActivity(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedVisibility(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_processEvent(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+
+    #define SUPER_changedScale(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedMainState(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedOwner(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedOverlayGroup(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedName(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedGametype(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+
+
+namespace orxonox
+{
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+    // This code gets included by Identifier.h and every other header file that needs a super-function //
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    //// Common code ////
+
+        // Base templates
+        /**
+            @brief Creates the SuperFunctionCaller if T is a child of the super-functions baseclass.
+        */
+        template <int functionnumber, class T, int templatehack1, int templatehack2>
+        struct SuperFunctionCondition
+        {
+            static void check() {}
+        };
+
+        /**
+            @brief Initializes the SuperFunctionCaller-pointer with zero.
+        */
+        template <int functionnumber, class T>
+        struct SuperFunctionInitialization
+        {
+            static void initialize(ClassIdentifier<T>* identifier) {}
+        };
+
+        /**
+            @brief Deletes the SuperFunctionCaller.
+        */
+        template <int functionnumber, class T>
+        struct SuperFunctionDestruction
+        {
+            static void destroy(ClassIdentifier<T>* identifier) {}
+        };
+
+
+    //// Function-specific code ////
+
+        /**
+            @brief Creates the needed objects and templates to call a super-function.
+            @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
+            @param functionname The name of the super-function
+            @param hasarguments "false" if the function doesn't take any arguments, "true" if it does (without "")
+            @param ... Variadic: If the function takes arguments, add them here with type and name. Example: int myvalue, float myothervalue
+        */
+        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(functionnumber, functionname, hasarguments, ...) \
+            template <class T, int templatehack1, int templatehack2> \
+            struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2> \
+            { \
+                static void check() \
+                { \
+                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check(); \
+                } \
+            }; \
+            \
+            class _CoreExport SuperFunctionCaller_##functionname \
+            { \
+                public: \
+                    virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0; \
+                    virtual ~SuperFunctionCaller_##functionname () {} \
+            }; \
+            \
+            template <class T> \
+            class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname \
+            { \
+                public: \
+                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
+                    { \
+                    } \
+            }; \
+            \
+            template <class T> \
+            struct SuperFunctionInitialization<functionnumber, T> \
+            { \
+                static void initialize(ClassIdentifier<T>* identifier) \
+                { \
+                    identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>; \
+                    identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true; \
+                    SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier); \
+                } \
+            }; \
+            \
+            template <class T> \
+            struct SuperFunctionDestruction<functionnumber, T> \
+            { \
+                static void destroy(ClassIdentifier<T>* identifier) \
+                { \
+                    if (identifier->superFunctionCaller_##functionname##_) \
+                        delete identifier->superFunctionCaller_##functionname##_; \
+                    SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier); \
+                } \
+            }; \
+            \
+            template <class T> \
+            class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname \
+            { \
+                public: \
+                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
+                    { \
+                        (dynamic_cast<T*>(object))->T:: functionname
+
+        /*
+            JUST ADD THE FUNCTION ARGUMENTS BETWEEN BOTH MACROS, ENCLOSED BY BRACKETS
+            EXAMPLE:
+
+              SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, myfunction, true, int myvalue, float myothervalue) <-- !!! DONT ADD A SEMICOLON HERE !!!
+                (myvalue, myothervalue)
+              SUPER_FUNCTION_GLOBAL_DECLARATION_PART2
+        */
+
+        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART2 \
+                                                        ; \
+                    } \
+            };
+
+        #define SUPER_CALL_ARGUMENTSfalse(...) OrxonoxClass* object
+        #define SUPER_CALL_ARGUMENTS0(...)     OrxonoxClass* object
+        #define SUPER_CALL_ARGUMENTStrue(...) OrxonoxClass* object, __VA_ARGS__
+        #define SUPER_CALL_ARGUMENTS1(...)    OrxonoxClass* object, __VA_ARGS__
+
+
+    /*
+    //// COMMENTS ABOUT THE MACRO ////
+
+        // Partially specialized template (templatehack not yet specialized, this
+        // will be done by the real condition in the header-file of the super-function)
+        // Only used as fallback
+        template <class T, int templatehack1, int templatehack2>
+        struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2>
+        {
+            // If this function gets called, the header-file of the super function is not
+            // included, so this fallback template (templatehack not specialized) is used
+            static void check()
+            {
+                // Calls the condition-check of the next super-function (functionnumber + 1)
+                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check();
+            }
+        };
+
+        // Baseclass of the super-function caller. The real call will be done by a
+        // templatized subclass through the virtual () operator.
+        class _CoreExport SuperFunctionCaller_##functionname
+        {
+            public:
+                virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0;
+                virtual ~SuperFunctionCaller_##functionname () {}
+        };
+
+        // Fallback if the base is pure virtual
+        template <class T>
+        class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname
+        {
+            public:
+                // Fallback does nothing
+                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
+                {
+                }
+        };
+
+        // Initializes the SuperFunctionCaller-pointer with a fallback caller in case the base function is pure virtual
+        template <class T>
+        struct SuperFunctionInitialization<functionnumber, T>
+        {
+            static void initialize(ClassIdentifier<T>* identifier)
+            {
+                identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>;
+                identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true;
+
+                // Calls the initialization of the next super-function (functionnumber + 1)
+                SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier);
+            }
+        };
+
+        // Deletes the SuperFunctionCaller.
+        template <class T>
+        struct SuperFunctionDestruction<functionnumber, T>
+        {
+            static void destroy(ClassIdentifier<T>* identifier)
+            {
+                if (identifier->superFunctionCaller_##functionname##_)
+                    delete identifier->superFunctionCaller_##functionname##_;
+
+                // Calls the destruction of the next super-function (functionnumber + 1)
+                SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier);
+            }
+        };
+
+        // The real super-function caller: Calls T::functionname()
+        // T should be the parent, but this will be done by the spezialized condition template
+        template <class T>
+        class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname
+        {
+            public:
+                // @brief Calls the function.
+                // @param object The object to call the function on
+                // @param ... The arguments of the function
+                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
+                {
+                    (dynamic_cast<T*>(object))->T:: functionname ( Call the function with it's arguments );
+                }
+        }
+    */
+
+
+    //// Execute the code for each super-function ////
+
+        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, XMLPort, true, Element& xmlelement, XMLPort::Mode mode)
+            (xmlelement, mode)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(1, tick, true, float dt)
+            (dt)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(2, changedActivity, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(3, changedVisibility, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, processEvent, true, Event& event)
+            (event)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(5, changedScale, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedMainState, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOwner, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedOverlayGroup, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedName, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedGametype, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+
+}
+
+#else /* _Super_H__ */
+  #ifdef SUPER_INTRUSIVE_DECLARATION_INCLUDE
+
+//////////////////////////////////////////////////////////////////////////
+// This code gets included within the declaration of ClassIdentifier<T> //
+//////////////////////////////////////////////////////////////////////////
+
+//// Common code ////
+
+    private:
+
+        template <int functionnumber, class TT, int templatehack1, int templatehack2>
+        friend struct SuperFunctionCondition;
+
+        // Creates the super-function-callers by calling the first SuperFunctionCondition check
+        // This get's called within the initialization of an Identifier
+        virtual void createSuperFunctionCaller() const
+        {
+            SuperFunctionCondition<0, T, 0, 0>::check();
+        }
+
+
+//// Function-specific code ////
+
+    public:
+        /**
+            @brief Adds a pointer to the SuperFunctionCaller as a member of ClassIdentifier.
+            @param functionname The name of the super-function
+        */
+        #ifndef SUPER_INTRUSIVE_DECLARATION
+          #define SUPER_INTRUSIVE_DECLARATION(functionname) \
+            SuperFunctionCaller_##functionname * superFunctionCaller_##functionname##_; \
+            bool bSuperFunctionCaller_##functionname##_isFallback_
+        #endif
+
+
+//// Execute the code for each super-function ////
+
+    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+    SUPER_INTRUSIVE_DECLARATION(XMLPort);
+    SUPER_INTRUSIVE_DECLARATION(tick);
+    SUPER_INTRUSIVE_DECLARATION(changedActivity);
+    SUPER_INTRUSIVE_DECLARATION(changedVisibility);
+    SUPER_INTRUSIVE_DECLARATION(processEvent);
+    SUPER_INTRUSIVE_DECLARATION(changedScale);
+    SUPER_INTRUSIVE_DECLARATION(changedMainState);
+    SUPER_INTRUSIVE_DECLARATION(changedOwner);
+    SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup);
+    SUPER_INTRUSIVE_DECLARATION(changedName);
+    SUPER_INTRUSIVE_DECLARATION(changedGametype);
+    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+
+
+    #undef SUPER_INTRUSIVE_DECLARATION_INCLUDE
+  #endif /* SUPER_INTRUSIVE_DECLARATION_INCLUDE */
+#endif /* _Super_H__ */
Index: code/trunk/src/libraries/core/TclBind.cc
===================================================================
--- code/trunk/src/libraries/core/TclBind.cc	(revision 5781)
+++ code/trunk/src/libraries/core/TclBind.cc	(revision 5781)
@@ -0,0 +1,203 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TclBind.h"
+
+#include <exception>
+#include <string>
+#include <cpptcl/cpptcl.h>
+
+#include "SpecialConfig.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "CommandExecutor.h"
+#include "ConsoleCommand.h"
+#include "Core.h"
+#include "TclThreadManager.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcut(TclBind, tcl);
+    SetConsoleCommandShortcut(TclBind, bgerror);
+
+    TclBind* TclBind::singletonPtr_s = 0;
+
+    TclBind::TclBind(const std::string& datapath)
+    {
+        this->interpreter_ = 0;
+        this->bSetTclDataPath_ = false;
+        this->setDataPath(datapath);
+    }
+
+    TclBind::~TclBind()
+    {
+        if (this->interpreter_)
+            delete this->interpreter_;
+    }
+
+    void TclBind::setDataPath(const std::string& datapath)
+    {
+        // String has POSIX slashes
+        this->tclDataPath_ = datapath + "tcl" + '/';
+        this->bSetTclDataPath_ = true;
+
+        this->initializeTclInterpreter();
+    }
+
+    void TclBind::initializeTclInterpreter()
+    {
+        if (this->bSetTclDataPath_ && !this->interpreter_)
+        {
+            this->interpreter_ = this->createTclInterpreter();
+
+            this->interpreter_->def("::orxonox::query", TclBind::tcl_query, Tcl::variadic());
+            this->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
+            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
+            this->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+
+            try
+            {
+                this->interpreter_->eval("proc query        {args}    { ::orxonox::query $args }");
+                this->interpreter_->eval("proc crossquery   {id args} { ::orxonox::crossquery 0 $id $args }");
+                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossquery 0 $id $args }");
+                this->interpreter_->eval("proc running      {}        { return 1 }");
+                this->interpreter_->eval("set id 0");
+                this->interpreter_->eval("rename exit ::tcl::exit; proc exit {} { execute exit }");
+            }
+            catch (Tcl::tcl_error const &e)
+            {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl;   }
+            catch (...)
+            {   COUT(1) << "Error while creating Tcl-interpreter: " << Exception::handleMessage() << std::endl;   }
+        }
+    }
+
+    Tcl::interpreter* TclBind::createTclInterpreter()
+    {
+        Tcl::interpreter* interpreter = new Tcl::interpreter();
+        std::string libpath = TclBind::getTclLibraryPath();
+
+        try
+        {
+            if (libpath != "")
+                interpreter->eval("set tcl_library \"" + libpath + "\"");
+
+            Tcl_Init(interpreter->get());
+
+            interpreter->eval("source \"" + TclBind::getInstance().tclDataPath_ + "/init.tcl\"");
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
+        catch (...)
+        {   COUT(1) << "Error while creating Tcl-interpreter: " << Exception::handleMessage() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
+
+        return interpreter;
+    }
+
+    std::string TclBind::getTclLibraryPath()
+    {
+#ifdef DEPENDENCY_PACKAGE_ENABLE
+        if (Core::isDevelopmentRun())
+            return (std::string(specialConfig::dependencyLibraryDirectory) + "/tcl");
+        else
+            return (Core::getRootPathString() + "lib/tcl");
+#else
+        return "";
+#endif
+    }
+
+    std::string TclBind::tcl_query(Tcl::object const &args)
+    {
+        COUT(4) << "Tcl_query: " << args.get() << std::endl;
+
+        std::string command = stripEnclosingBraces(args.get());
+
+        if (!CommandExecutor::execute(command, false))
+        {
+            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
+        }
+
+        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
+            return CommandExecutor::getLastEvaluation().getReturnvalue().getString();
+
+        return "";
+    }
+
+    void TclBind::tcl_execute(Tcl::object const &args)
+    {
+        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
+        std::string command = stripEnclosingBraces(args.get());
+
+        if (!CommandExecutor::execute(command, false))
+        {
+            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
+        }
+    }
+
+    std::string TclBind::tcl(const std::string& tclcode)
+    {
+        if (TclBind::getInstance().interpreter_)
+        {
+            try
+            {
+                std::string output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
+                if (output != "")
+                {
+                    COUT(0) << "tcl> " << output << std::endl;
+                }
+                return output;
+            }
+            catch (Tcl::tcl_error const &e)
+            {   COUT(1) << "tcl> Error: " << e.what() << std::endl;   }
+            catch (...)
+            {   COUT(1) << "Error while executing Tcl: " << Exception::handleMessage() << std::endl;   }
+        }
+
+        return "";
+    }
+
+    void TclBind::bgerror(std::string error)
+    {
+        COUT(1) << "Tcl background error: " << stripEnclosingBraces(error) << std::endl;
+    }
+
+    bool TclBind::eval(const std::string& tclcode)
+    {
+        try
+        {
+            TclBind::getInstance().interpreter_->eval(tclcode);
+            return true;
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
+        catch (...)
+        {   COUT(1) << "Error while executing Tcl: " << Exception::handleMessage() << std::endl;   }
+
+        return false;
+    }
+}
Index: code/trunk/src/libraries/core/TclBind.h
===================================================================
--- code/trunk/src/libraries/core/TclBind.h	(revision 5781)
+++ code/trunk/src/libraries/core/TclBind.h	(revision 5781)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TclBind_H__
+#define _TclBind_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include "util/Singleton.h"
+
+namespace orxonox
+{
+    class _CoreExport TclBind : public Singleton<TclBind>
+    {
+        friend class Singleton<TclBind>;
+        public:
+            TclBind(const std::string& datapath);
+            ~TclBind();
+
+            static std::string tcl(const std::string& tclcode);
+            static void bgerror(std::string error);
+
+            void setDataPath(const std::string& datapath);
+            const std::string& getTclDataPath() const { return this->tclDataPath_; }
+            static std::string getTclLibraryPath();
+
+            void initializeTclInterpreter();
+            static Tcl::interpreter* createTclInterpreter();
+            Tcl::interpreter* getTclInterpreter() const { return this->interpreter_; }
+
+            static std::string tcl_query(Tcl::object const &args);
+            static void tcl_execute(Tcl::object const &args);
+
+            static bool eval(const std::string& tclcode);
+
+        private:
+            TclBind(const TclBind& other);
+
+            Tcl::interpreter* interpreter_;
+            std::string tclDataPath_;
+            bool bSetTclDataPath_;
+
+            static TclBind* singletonPtr_s;
+    };
+}
+
+#endif /* _TclBind_H__ */
Index: code/trunk/src/libraries/core/TclThreadList.h
===================================================================
--- code/trunk/src/libraries/core/TclThreadList.h	(revision 5781)
+++ code/trunk/src/libraries/core/TclThreadList.h	(revision 5781)
@@ -0,0 +1,263 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TclThreadList_H__
+#define _TclThreadList_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace orxonox
+{
+    template <class T>
+    class TclThreadList
+    {
+        public:
+            void push_front(const T& value);
+            void push_back(const T& value);
+            template <class InputIterator> void insert(typename std::list<T>::iterator position, InputIterator begin, InputIterator end);
+
+            void wait_and_pop_front(T* value);
+            void wait_and_pop_back(T* value);
+            bool try_pop_front(T* value);
+            bool try_pop_back(T* value);
+            void clear();
+
+            size_t size() const;
+            bool empty() const;
+            bool is_in(const T& value) const;
+
+            /**
+                @brief Returns a reference to the list. Don't forget to lock the mutex (see @ref getMutex).
+            */
+            inline std::list<T>& getList()
+                { return this->list_; }
+
+            /**
+                @brief Returns a reference to the list. Don't forget to lock the mutex (see @ref getMutex).
+            */
+            inline const std::list<T>& getList() const
+                { return this->list_; }
+
+            /**
+                @brief Returns a reference to the mutex which might be useful if you want to iterate through the list (see @ref begin and @ref end).
+            */
+            inline boost::shared_mutex& getMutex() const
+                { return this->mutex_; }
+
+        private:
+            std::list<T>                  list_;        ///< A standard list for type T
+            mutable boost::shared_mutex   mutex_;       ///< A mutex to grant exclusive access to the list
+            boost::condition_variable_any condition_;   ///< A condition variable to wake threads waiting for the mutex to become ready
+    };
+
+    /**
+        @brief Pushes a new element to the front of the list. A unique_lock is needed.
+    */
+    template <class T>
+    void TclThreadList<T>::push_front(const T& value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.push_front(value);
+        lock.unlock();                  // unlock the mutex...
+        this->condition_.notify_all();  // ...then call notify_all to wake threads waiting in wait_and_pop_front/back
+    }
+
+    /**
+        @brief Pushes a new element to the back of the list. A unique_lock is needed.
+    */
+    template <class T>
+    void TclThreadList<T>::push_back(const T& value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.push_back(value);
+        lock.unlock();                  // unlock the mutex...
+        this->condition_.notify_all();  // ...then call notify_all to wake threads waiting in wait_and_pop_front/back
+    }
+
+    /**
+        @brief Inserts new elements into the list. A unique_lock is needed.
+    */
+    template <class T>
+    template <class InputIterator> void TclThreadList<T>::insert(typename std::list<T>::iterator position, InputIterator begin, InputIterator end)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.insert(position, begin, end);
+        lock.unlock();                  // unlock the mutex...
+        this->condition_.notify_all();  // ...then call notify_all to wake threads waiting in wait_and_pop_front/back
+    }
+
+    /**
+        @brief Waits until the list contains at least one element and then pops and returns the front element.
+        @param value The front value will be stored in the variable referenced by this pointer.
+    */
+    template <class T>
+    void TclThreadList<T>::wait_and_pop_front(T* value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+
+        while (this->list_.empty())       // check if there's an element in the list
+            this->condition_.wait(lock);  // wait until the condition becomes true (a notification comes from push_front, push_back or insert
+
+        *value = this->list_.front();
+        this->list_.pop_front();
+    }
+
+    /**
+        @brief Waits until the list contains at least one element and then pops and returns the back element.
+        @param value The back value will be stored in the variable referenced by this pointer.
+    */
+    template <class T>
+    void TclThreadList<T>::wait_and_pop_back(T* value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+
+        while (this->list_.empty())       // check if there's an element in the list
+            this->condition_.wait(lock);  // wait until the condition becomes true (a notification comes from push_front, push_back or insert
+
+        *value = this->list_.back();
+        this->list_.pop_back();
+    }
+
+    /**
+        @brief Pops and returns the front element if there's at least one element in the list.
+        @param value The front value will be stored in the variable referenced by this pointer.
+        @return Returns true if there was at least one element in the list (which got poped). If the list was empty, false is returned immediately.
+
+        Needs a unique_lock if there's an element to pop. If not, shared_lock is sufficient.
+    */
+    template <class T>
+    bool TclThreadList<T>::try_pop_front(T* value)
+    {
+        boost::upgrade_lock<boost::shared_mutex> lock(this->mutex_); // gain shared lock
+
+        if (this->list_.empty())
+        {
+            // No elements - return immediately
+            return false;
+        }
+        else
+        {
+            // At least one element - write it into the passed variable and pop it from the list
+            boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); // upgrade to unique lock to modify the list
+            *value = this->list_.front();
+            this->list_.pop_front();
+        }
+        return true;
+    }
+
+    /**
+        @brief Pops and returns the back element if there's at least one element in the list.
+        @param value The back value will be stored in the variable referenced by this pointer.
+        @return Returns true if there was at least one element in the list (which got poped). If the list was empty, false is returned immediately.
+
+        Needs a unique_lock if there's an element to pop. If not, shared_lock is sufficient.
+    */
+    template <class T>
+    bool TclThreadList<T>::try_pop_back(T* value)
+    {
+        boost::upgrade_lock<boost::shared_mutex> lock(this->mutex_); // gain shared lock
+
+        if (this->list_.empty())
+        {
+            // No elements - return immediately
+            return false;
+        }
+        else
+        {
+            // At least one element - write it into the passed variable and pop it from the list
+            boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); // upgrade to unique lock to modify the list
+            *value = this->list_.back();
+            this->list_.pop_back();
+        }
+        return true;
+    }
+
+    /**
+        @brief Clears the list. A unique_lock is needed.
+    */
+    template <class T>
+    void TclThreadList<T>::clear()
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.clear();
+    }
+
+    /**
+        @brief Returns the size of the list. A shared_lock is needed.
+
+        Warning: Don't change the list based on the result of size(). Use an atomic function instead. Other threads may change the list
+        beween your call to size() and your further actions, so be careful and use this function only if you really want nothing else than
+        just the size of the list.
+    */
+    template <class T>
+    size_t TclThreadList<T>::size() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(this->mutex_);
+        return this->list_.size();
+    }
+
+    /**
+        @brief Returns true if the list is empty, false otherwise. A shared_lock is needed.
+
+        Warning: Don't change the list based on the result of empty(). Use an atomic function instead. Other threads may change the list
+        beween your call to empty() and your further actions, so be careful and use this function only if you really want nothing else than
+        just if the list is empty or not.
+    */
+    template <class T>
+    bool TclThreadList<T>::empty() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(this->mutex_);
+        return this->list_.empty();
+    }
+
+    /**
+        @brief Returns true if a given element is in the list, false otherwise. A shared_lock is needed.
+
+        Warning: The result of this function might be wrong just one instruction after the call. Use this function just to get information
+        about a temporary snapshot and don't change the list based on the result of this function.
+    */
+    template <class T>
+    bool TclThreadList<T>::is_in(const T& value) const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(this->mutex_);
+
+        for (typename std::list<T>::const_iterator it = this->list_.begin(); it != this->list_.end(); ++it)
+            if (*it == value)
+                return true;
+
+        return false;
+    }
+}
+
+#endif /* _TclThreadList_H__ */
Index: code/trunk/src/libraries/core/TclThreadManager.cc
===================================================================
--- code/trunk/src/libraries/core/TclThreadManager.cc	(revision 5781)
+++ code/trunk/src/libraries/core/TclThreadManager.cc	(revision 5781)
@@ -0,0 +1,671 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TclThreadManager.h"
+
+#include <boost/bind.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <OgreTimer.h>
+#include <cpptcl/cpptcl.h>
+
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "Clock.h"
+#include "CommandExecutor.h"
+#include "ConsoleCommand.h"
+#include "CoreIncludes.h"
+#include "TclBind.h"
+#include "TclThreadList.h"
+
+namespace orxonox
+{
+    const float TCLTHREADMANAGER_MAX_CPU_USAGE = 0.50f;
+
+    SetConsoleCommandShortcutAlias(TclThreadManager, execute, "tclexecute").argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommandShortcutAlias(TclThreadManager, query,   "tclquery"  ).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, create,  false);
+    SetConsoleCommand(TclThreadManager, destroy, false).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, execute, false).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, query,   false).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, source,  false).argumentCompleter(0, autocompletion::tclthreads());
+
+    /**
+        @brief A struct containing all information about a Tcl-interpreter
+    */
+    struct TclInterpreterBundle
+    {
+        TclInterpreterBundle()
+        {
+            this->lock_ = new boost::unique_lock<boost::mutex>(this->mutex_, boost::defer_lock);
+            this->bRunning_ = true;
+        }
+
+        ~TclInterpreterBundle()
+        {
+            delete this->lock_;
+        }
+
+        unsigned int                      id_;             ///< The id of the interpreter
+        Tcl::interpreter*                 interpreter_;    ///< The Tcl-interpreter
+        boost::mutex                      mutex_;          ///< A mutex to lock the interpreter while it's being used
+        boost::unique_lock<boost::mutex>* lock_;           ///< The corresponding lock for the mutex
+        TclThreadList<std::string>        queue_;          ///< The command queue for commands passed by execute(command)
+        TclThreadList<unsigned int>       queriers_;       ///< A list containing the id's of all other threads sending a query to this interpreter (to avoid circular queries and deadlocks)
+        bool                              bRunning_;       ///< This variable stays true until destroy() gets called
+    };
+
+    TclThreadManager* TclThreadManager::singletonPtr_s = 0;
+
+    /**
+        @brief Constructor
+        @param interpreter A pointer to the standard Tcl-interpreter (see @ref TclBind)
+    */
+    TclThreadManager::TclThreadManager(Tcl::interpreter* interpreter)
+    {
+        RegisterRootObject(TclThreadManager);
+
+        this->numInterpreterBundles_ = 0;
+
+        this->interpreterBundlesMutex_ = new boost::shared_mutex();
+        this->mainInterpreterMutex_ = new boost::mutex();
+        this->messageQueue_ = new TclThreadList<std::string>();
+
+        TclInterpreterBundle* newbundle = new TclInterpreterBundle();
+        newbundle->id_ = 0;
+        newbundle->interpreter_ = interpreter;
+        newbundle->lock_->lock();
+
+        {
+            boost::unique_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+            this->interpreterBundles_[0] = newbundle;
+        }
+    }
+
+    /**
+        @brief Destructor
+    */
+    TclThreadManager::~TclThreadManager()
+    {
+        delete this->interpreterBundlesMutex_;
+//        delete this->mainInterpreterMutex_; // <-- temporary disabled to avoid crash if a thread is still actively queriyng
+        delete this->messageQueue_;
+    }
+
+    /**
+        @brief The "main loop" of the TclThreadManager. Creates new threads if needed and handles queries and queued commands for the main interpreter.
+    */
+    void TclThreadManager::update(const Clock& time)
+    {
+        // Get the bundle of the main interpreter (0)
+        TclInterpreterBundle* bundle = this->getInterpreterBundle(0);
+        if (bundle)
+        {
+            // Unlock the mutex to allow other threads accessing the main interpreter
+            bundle->lock_->unlock();
+
+            // Lock the main interpreter mutex once to synchronize with threads that want to query the main interpreter
+            {
+                boost::unique_lock<boost::mutex> lock(*this->mainInterpreterMutex_);
+            }
+
+            // Lock the mutex again to gain exclusive access to the interpreter for the rest of the mainloop
+            bundle->lock_->lock();
+
+            // Execute commands in the queues of the threaded interpreters
+            {
+                boost::shared_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+                for (std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = this->interpreterBundles_.begin(); it != this->interpreterBundles_.end(); ++it)
+                {
+                    if (it->first == 0)
+                        continue; // We'll handle the default interpreter later (and without threads of course)
+
+                    TclInterpreterBundle* bundle = it->second;
+                    if (!bundle->queue_.empty())
+                    {
+                        // There are commands in the queue
+                        try
+                        {
+                            if (!bundle->lock_->owns_lock() && bundle->lock_->try_lock())
+                            {
+                                // We sucessfully obtained a lock for the interpreter
+                                std::string command;
+                                if (bundle->queue_.try_pop_front(&command))
+                                {
+                                    // Start a thread to execute the command
+                                    boost::thread(boost::bind(&tclThread, bundle, command));
+                                }
+                                else
+                                {
+                                    // Somehow the queue become empty (maybe multiple consumers) - unlock the mutex
+                                    bundle->lock_->unlock();
+                                }
+                            }
+                        }
+                        catch (...)
+                        {
+                            // A lock error occurred - this is possible if the lock gets locked between !bundle->lock_->owns_lock() and bundle->lock_->try_lock()
+                            // This isn't too bad, just continue
+                        }
+                    }
+                }
+            }
+
+            // Execute commands in the message queue
+            if (!this->messageQueue_->empty())
+            {
+                std::string command;
+                while (true)
+                {
+                    // Pop the front value from the list (break the loop if there are no elements in the list)
+                    if (!this->messageQueue_->try_pop_front(&command))
+                        break;
+
+                    // Execute the command
+                    CommandExecutor::execute(command, false);
+                }
+            }
+
+            // Execute commands in the queue of the main interpreter
+            if (!bundle->queue_.empty())
+            {
+                // Calculate the time we have until we reach the maximal cpu usage
+                unsigned long maxtime = (unsigned long)(time.getDeltaTime() * 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE);
+
+                Ogre::Timer timer;
+                std::string command;
+
+                while (timer.getMicroseconds() < maxtime)
+                {
+                    // Pop the front value from the list (break the loop if there are no elements in the list)
+                    if (!bundle->queue_.try_pop_front(&command))
+                        break;
+
+                    // Execute the command
+                    CommandExecutor::execute(command, false);
+                }
+            }
+        }
+    }
+
+    /**
+        @brief Creates a new Tcl-interpreter.
+    */
+    unsigned int TclThreadManager::create()
+    {
+        TclThreadManager::getInstance().numInterpreterBundles_++;
+        TclThreadManager::createWithId(TclThreadManager::getInstance().numInterpreterBundles_);
+        COUT(0) << "Created new Tcl-interpreter with ID " << TclThreadManager::getInstance().numInterpreterBundles_ << std::endl;
+        return TclThreadManager::getInstance().numInterpreterBundles_;
+    }
+
+    /**
+        @brief Creates a new Tcl-interpreter with a given id.
+
+        Use with caution - if the id collides with an already existing interpreter, this call will fail.
+        This will also be a problem, if the auto-numbered interpreters (by using create()) reach an id
+        which was previously used in this function. Use high numbers to be safe.
+    */
+    Tcl::interpreter* TclThreadManager::createWithId(unsigned int id)
+    {
+        TclInterpreterBundle* newbundle = new TclInterpreterBundle();
+        newbundle->id_ = id;
+        newbundle->interpreter_ = TclBind::createTclInterpreter();
+
+        TclThreadManager::initialize(newbundle);
+
+        {
+            // Add the new bundle to the map
+            boost::unique_lock<boost::shared_mutex> lock(*TclThreadManager::getInstance().interpreterBundlesMutex_);
+            TclThreadManager::getInstance().interpreterBundles_[id] = newbundle;
+        }
+
+        return newbundle->interpreter_;
+    }
+
+    void TclThreadManager::initialize(TclInterpreterBundle* bundle)
+    {
+        std::string id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
+
+        // Initialize the new interpreter
+        try
+        {
+            // Define the functions which are implemented in C++
+            bundle->interpreter_->def("::orxonox::execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::query",        TclThreadManager::tcl_query,        Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::crossquery",   TclThreadManager::tcl_crossquery,   Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::running",      TclThreadManager::tcl_running);
+
+            // Create threadspecific shortcuts for the functions above
+            bundle->interpreter_->def("execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
+            bundle->interpreter_->def("crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+            bundle->interpreter_->eval("proc query      {args}    { ::orxonox::query " + id_string + " $args }");
+            bundle->interpreter_->eval("proc crossquery {id args} { ::orxonox::crossquery " + id_string + " $id $args }");
+            bundle->interpreter_->eval("proc running    {}        { return [::orxonox::running " + id_string + "] }");
+
+            // Define a variable containing the thread id
+            bundle->interpreter_->eval("set id " + id_string);
+
+            // Use our own exit function to avoid shutting down the whole program instead of just the interpreter
+            bundle->interpreter_->eval("rename exit ::tcl::exit");
+            bundle->interpreter_->eval("proc exit {} { execute TclThreadManager destroy " + id_string + " }");
+
+            // Redefine some native functions
+            bundle->interpreter_->eval("rename while ::tcl::while");
+            bundle->interpreter_->eval("rename ::orxonox::while while");
+            bundle->interpreter_->eval("rename for ::tcl::for");
+            bundle->interpreter_->eval("rename ::orxonox::for for");
+        }
+        catch (const Tcl::tcl_error& e)
+        {   bundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl;   }
+        catch (...)
+        {   bundle->interpreter_ = 0; COUT(1) << "Error while creating Tcl-interpreter (" << id_string << "): " << Exception::handleMessage() << std::endl;   }
+    }
+
+    /**
+        @brief Stops and destroys a given Tcl-interpreter
+    */
+    void TclThreadManager::destroy(unsigned int id)
+    {
+        // TODO
+        // Not yet implemented
+        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
+        if (bundle)
+        {
+            bundle->bRunning_ = false;
+        }
+    }
+
+    /**
+        @brief Sends a command to the queue of a given Tcl-interpreter
+        @param id The id of the target interpreter
+        @param command The command to be sent
+    */
+    void TclThreadManager::execute(unsigned int target_id, const std::string& command)
+    {
+        TclThreadManager::getInstance()._execute(target_id, command);
+    }
+
+    /**
+        @brief This function can be called from Tcl to execute a console command.
+
+        Commands which shall be executed are put into a queue and processed as soon as the
+        main thread feels ready to do so. The queue may also be full which results in a temporary
+        suspension of the calling thread until the queue gets ready again.
+    */
+    void TclThreadManager::tcl_execute(const Tcl::object& args)
+    {
+        TclThreadManager::getInstance()._execute(0, stripEnclosingBraces(args.get()));
+    }
+
+    /**
+        @brief This function can be called from Tcl to send a command to the queue of any interpreter.
+        @param target_id The id of the target thread
+    */
+    void TclThreadManager::tcl_crossexecute(int target_id, const Tcl::object& args)
+    {
+        TclThreadManager::getInstance()._execute(static_cast<unsigned int>(target_id), stripEnclosingBraces(args.get()));
+    }
+
+    /**
+        @brief Sends a command to the queue of a given Tcl-interpreter
+        @param id The id of the target interpreter
+        @param command The command to be sent
+    */
+    void TclThreadManager::_execute(unsigned int target_id, const std::string& command)
+    {
+        TclInterpreterBundle* bundle = this->getInterpreterBundle(target_id);
+        if (bundle)
+            bundle->queue_.push_back(command);
+    }
+
+
+    /**
+        @brief Sends a query to a given Tcl-interpreter and waits for the result
+        @param id The id of the target interpreter
+        @param command The command to be sent
+        @return The result of the command
+    */
+    std::string TclThreadManager::query(unsigned int target_id, const std::string& command)
+    {
+        return TclThreadManager::getInstance()._query(0, target_id, command);
+    }
+
+    /**
+        @brief This function can be called from Tcl to send a query to the main thread.
+        @param source_id The id of the calling thread
+
+        A query waits for the result of the command. This means, the calling thread will be blocked until
+        the main thread answers the query. In return, the main thread sends the result of the console
+        command back to Tcl.
+    */
+    std::string TclThreadManager::tcl_query(int source_id, const Tcl::object& args)
+    {
+        return TclThreadManager::getInstance()._query(static_cast<unsigned int>(source_id), 0, stripEnclosingBraces(args.get()), true);
+    }
+
+    /**
+        @brief This function can be called from Tcl to send a query to another thread.
+        @param source_id The id of the calling thread
+        @param target_id The id of the target thread
+    */
+    std::string TclThreadManager::tcl_crossquery(int source_id, int target_id, const Tcl::object& args)
+    {
+        return TclThreadManager::getInstance()._query(static_cast<unsigned int>(source_id), static_cast<unsigned int>(target_id), stripEnclosingBraces(args.get()));
+    }
+
+    /**
+        @brief This function performs a query to any Tcl interpreter
+        @param source_id The id of the calling thread
+        @param target_id The id of the target thread
+        @param command The command to send as a query
+        @param bUseCommandExecutor Only used if the target_id is 0 (which references the main interpreter). In this case it means if the command should be passed to the CommandExecutor (true) or to the main Tcl interpreter (false). This is true when called by tcl_query and false when called by tcl_crossquery.
+    */
+    std::string TclThreadManager::_query(unsigned int source_id, unsigned int target_id, const std::string& command, bool bUseCommandExecutor)
+    {
+        TclInterpreterBundle* source_bundle = this->getInterpreterBundle(source_id);
+        TclInterpreterBundle* target_bundle = this->getInterpreterBundle(target_id);
+        std::string output;
+
+        if (source_bundle && target_bundle)
+        {
+            // At this point we assume the mutex of source_bundle to be locked (because it's executing this query right now an waits for the return value)
+            // We can safely use it's querier list (because there's no other place in the code using the list except this query - and the interpreter can't start more than one query)
+
+            if ((source_bundle->id_ == target_bundle->id_) || source_bundle->queriers_.is_in(target_bundle->id_))
+            {
+                // This query would lead to a deadlock - return with an error
+                TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + " " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
+                            + " -> " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
+                            + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
+                            + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) + ".");
+            }
+            else
+            {
+                boost::unique_lock<boost::mutex> lock(target_bundle->mutex_, boost::try_to_lock);
+                boost::unique_lock<boost::mutex> mainlock(*this->mainInterpreterMutex_, boost::defer_lock);
+
+                if (!lock.owns_lock() && source_bundle->id_ != 0)
+                {
+                    // We couldn't obtain the try_lock immediately and we're not the main interpreter - wait until the lock becomes possible (note: the main interpreter won't wait and instead returns an error - see below)
+                    if (target_bundle->id_ == 0)
+                    {
+                        // We're querying the main interpreter - use the main interpreter mutex to synchronize
+                        mainlock.lock();
+                        lock.lock();
+                    }
+                    else
+                    {
+                        // We're querying a threaded interpreter - no synchronization needed
+                        lock.lock();
+                    }
+                }
+
+                if (lock.owns_lock())
+                {
+                    // Now the mutex of target_bundle is also locked an we can update the querier list
+                    target_bundle->queriers_.insert(target_bundle->queriers_.getList().begin(), source_bundle->queriers_.getList().begin(), source_bundle->queriers_.getList().end());
+                    target_bundle->queriers_.push_back(source_bundle->id_);
+
+                    // Perform the query (note: this happens in the main thread because we need the returnvalue)
+                    if (target_bundle->id_ == 0 && bUseCommandExecutor)
+                    {
+                        // It's a query to the CommandExecutor
+                        TclThreadManager::debug("TclThread_query -> CE: " + command);
+                        if (!CommandExecutor::execute(command, false))
+                            TclThreadManager::error("Error: Can't execute command \"" + command + "\"!");
+
+                        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
+                            output = CommandExecutor::getLastEvaluation().getReturnvalue().getString();
+                    }
+                    else
+                    {
+                        // It's a query to a Tcl interpreter
+                        TclThreadManager::debug("TclThread_query: " + command);
+
+                        output = TclThreadManager::eval(target_bundle, command, "query");
+                    }
+
+                    // Clear the queriers list of the target
+                    target_bundle->queriers_.clear();
+
+                    // Unlock the mutex of the target_bundle
+                    lock.unlock();
+
+                    // Finally unlock the main interpreter lock if necessary
+                    if (mainlock.owns_lock())
+                        mainlock.unlock();
+                }
+                else
+                {
+                    // This happens if the main thread tries to query a busy interpreter
+                    // To avoid a lock of the main thread, we simply don't proceed with the query in this case
+                    TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
+                }
+            }
+
+        }
+
+        return output;
+    }
+
+    /**
+        @brief Creates a non-interactive Tcl-interpreter which executes a file.
+    */
+    void TclThreadManager::source(const std::string& file)
+    {
+        boost::thread(boost::bind(&sourceThread, file));
+    }
+
+    /**
+        @brief This function can be called from Tcl to ask if the thread is still suposed to be running.
+        @param id The id of the thread in question
+    */
+    bool TclThreadManager::tcl_running(int id)
+    {
+        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(static_cast<unsigned int>(id));
+        if (bundle)
+            return bundle->bRunning_;
+        else
+            return false;
+    }
+
+    /**
+        @brief Returns the interpreter bundle with the given id.
+        @param id The id of the interpreter
+        @return The interpreter or 0 if the id doesn't exist
+    */
+    TclInterpreterBundle* TclThreadManager::getInterpreterBundle(unsigned int id)
+    {
+        boost::shared_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+
+        std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = this->interpreterBundles_.find(id);
+        if (it != this->interpreterBundles_.end())
+        {
+            return it->second;
+        }
+        else
+        {
+            TclThreadManager::error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
+            return 0;
+        }
+    }
+
+    /**
+        @brief Returns a string containing all elements of a unsigned-integer-list separated by spaces.
+    */
+    std::string TclThreadManager::dumpList(const std::list<unsigned int>& list)
+    {
+        std::string output = "";
+        for (std::list<unsigned int>::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                output += " ";
+
+            output += getConvertedValue<unsigned int, std::string>(*it);
+        }
+        return output;
+    }
+
+    /**
+        @brief Returns a list with the numbers of all existing Tcl-interpreters.
+
+        This function is used by the auto completion function.
+    */
+    std::list<unsigned int> TclThreadManager::getThreadList() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+
+        std::list<unsigned int> threads;
+        for (std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = this->interpreterBundles_.begin(); it != this->interpreterBundles_.end(); ++it)
+            if (it->first > 0 && it->first <= this->numInterpreterBundles_) // only list autonumbered interpreters (created with create()) - exclude the default interpreter 0 and all manually numbered interpreters)
+                threads.push_back(it->first);
+        return threads;
+    }
+
+    /**
+        @brief A helper function to print errors in a thread safe manner.
+    */
+    void TclThreadManager::error(const std::string& error)
+    {
+        TclThreadManager::getInstance().messageQueue_->push_back("error " + error);
+    }
+
+    /**
+        @brief A helper function to print debug information in a thread safe manner.
+    */
+    void TclThreadManager::debug(const std::string& error)
+    {
+        TclThreadManager::getInstance().messageQueue_->push_back("debug " + error);
+    }
+
+    /**
+        @brief Evaluates a Tcl command without throwing exceptions (which may rise problems on certain machines).
+        @return The Tcl return value
+
+        Errors are reported through the @ref error function.
+    */
+    std::string TclThreadManager::eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action)
+    {
+        Tcl_Interp* interpreter = bundle->interpreter_->get();
+        int cc = Tcl_Eval(interpreter, command.c_str());
+
+        Tcl::details::result result(interpreter);
+
+        if (cc != TCL_OK)
+        {
+            TclThreadManager::error("Tcl error (" + action + ", ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
+            return "";
+        }
+        else
+        {
+            return result;
+        }
+    }
+
+    ////////////////
+    // The Thread //
+    ////////////////
+
+    /**
+        @brief The main function of the thread. Executes a Tcl command.
+        @param bundle The interpreter bundle containing all necessary variables
+        @param command the Command to execute
+    */
+    void tclThread(TclInterpreterBundle* bundle, std::string command)
+    {
+        TclThreadManager::debug("TclThread_execute: " + command);
+
+        TclThreadManager::eval(bundle, command, "execute");
+
+        bundle->lock_->unlock();
+    }
+
+    /**
+        @brief The main function of a non-interactive source thread. Executes the file.
+        @param file The name of the file that should be executed by the non-interactive interpreter.
+    */
+    void sourceThread(std::string file)
+    {
+        TclThreadManager::debug("TclThread_source: " + file);
+
+        // Prepare the command-line arguments
+        const int argc = 2;
+        char* argv[argc];
+        argv[0] = "tclthread";
+        argv[1] = const_cast<char*>(file.c_str());
+
+        // Start the Tcl-command Tcl_Main with the Tcl_OrxonoxAppInit hook
+        Tcl_Main(argc, argv, Tcl_OrxonoxAppInit);
+
+//        Tcl::object object(file);
+//        int cc = Tcl_FSEvalFile(bundle->interpreter_->get(), object.get_object());
+//        Tcl::details::result result(bundle->interpreter_->get());
+//        if (cc != TCL_OK)
+//            TclThreadManager::error("Tcl error (source, ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
+//
+//        // Unlock the mutex
+//        bundle->lock_->unlock();
+    }
+
+    /**
+        @brief A tcl-init hook to inject the non-interactive Tcl-interpreter into the TclThreadManager.
+    */
+    int Tcl_OrxonoxAppInit(Tcl_Interp* interp)
+    {
+        // Create a new interpreter bundle
+        unsigned int id = TclThreadManager::create();
+        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
+
+        // Replace the default interpreter in the bundle with the non-interactive one (passed as an argument to this function)
+        if (bundle->interpreter_)
+            delete bundle->interpreter_;
+        bundle->interpreter_ = new Tcl::interpreter(interp, true);
+
+        // Initialize the non-interactive interpreter (like in @ref TclBind::createTclInterpreter but exception safe)
+        std::string libpath = TclBind::getTclLibraryPath();
+        if (libpath != "")
+            TclThreadManager::eval(bundle, "set tcl_library \"" + libpath + "\"", "source");
+        int cc = Tcl_Init(interp);
+        TclThreadManager::eval(bundle, "source \"" + TclBind::getInstance().getTclDataPath() + "/init.tcl\"", "source");
+
+        // Initialize the non-interactive interpreter also with the thread-specific stuff
+        TclThreadManager::initialize(bundle);
+
+        // Lock the mutex (this will be locked until the thread finishes - no chance to interact with the interpreter)
+        bundle->lock_->lock();
+
+        // Return to Tcl_Main
+        if (!bundle->interpreter_)
+            return TCL_ERROR;
+        else
+            return cc;
+    }
+}
Index: code/trunk/src/libraries/core/TclThreadManager.h
===================================================================
--- code/trunk/src/libraries/core/TclThreadManager.h	(revision 5781)
+++ code/trunk/src/libraries/core/TclThreadManager.h	(revision 5781)
@@ -0,0 +1,102 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TclThreadManager_H__
+#define _TclThreadManager_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <map>
+#include <string>
+
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+struct Tcl_Interp;
+
+namespace orxonox
+{
+    class _CoreExport TclThreadManager : public Singleton<TclThreadManager>, public OrxonoxClass
+    {
+        friend class Singleton<TclThreadManager>;
+        friend class TclBind;
+        friend _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
+        friend _CoreExport void sourceThread(std::string file);
+        friend _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
+
+        public:
+            TclThreadManager(Tcl::interpreter* interpreter);
+            virtual ~TclThreadManager();
+
+            static unsigned int      create();
+            static Tcl::interpreter* createWithId(unsigned int id);
+            static void              destroy(unsigned int id);
+            static void              execute(unsigned int target_id, const std::string& command);
+            static std::string       query(unsigned int target_id, const std::string& command);
+            static void              source(const std::string& file);
+
+            static void error(const std::string& error);
+            static void debug(const std::string& error);
+
+            void update(const Clock& time);
+
+            std::list<unsigned int> getThreadList() const;
+
+        private:
+            static void tcl_execute(const Tcl::object& args);
+            static void tcl_crossexecute(int target_id, const Tcl::object& args);
+            static std::string tcl_query(int source_id, const Tcl::object& args);
+            static std::string tcl_crossquery(int source_id, int target_id, const Tcl::object& args);
+            static bool tcl_running(int id);
+
+            void _execute(unsigned int target_id, const std::string& command);
+            std::string _query(unsigned int source_id, unsigned int target_id, const std::string& command, bool bUseCommandExecutor = false);
+
+            TclInterpreterBundle* getInterpreterBundle(unsigned int id);
+            std::string dumpList(const std::list<unsigned int>& list);
+
+            static void initialize(TclInterpreterBundle* bundle);
+            static std::string eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action);
+
+            static TclThreadManager* singletonPtr_s;                            ///< Singleton pointer
+
+            unsigned int numInterpreterBundles_;                                ///< Number of created Tcl-interpreters (only used for auto-numbered interpreters, not affected by @ref createWithId)
+            std::map<unsigned int, TclInterpreterBundle*> interpreterBundles_;  ///< A map containing all Tcl-interpreters
+            boost::shared_mutex* interpreterBundlesMutex_;                      ///< A mutex used to synchronize threads when accessing @ref interpreterBundles_
+            TclThreadList<std::string>* messageQueue_;                          ///< A queue to pass messages from Tcl-threads to the main thread
+            boost::mutex* mainInterpreterMutex_;                                ///< A mutex to synchronize queries to the main interpreter
+    };
+
+    _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
+    _CoreExport void sourceThread(std::string file);
+    _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
+}
+
+#endif /* _TclThreadManager_H__ */
Index: code/trunk/src/libraries/core/Template.cc
===================================================================
--- code/trunk/src/libraries/core/Template.cc	(revision 5781)
+++ code/trunk/src/libraries/core/Template.cc	(revision 5781)
@@ -0,0 +1,181 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Template.h"
+
+#include <tinyxml/tinyxml.h>
+#include <tinyxml/ticpp.h>
+
+#include "util/Debug.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(Template);
+
+    Template::Template(BaseObject* creator) : BaseObject(creator)
+    {
+        this->xmlelement_ = new TiXmlElement("");
+
+        RegisterObject(Template);
+
+        this->bIsLink_ = false;
+        this->bLoadDefaults_ = true;
+        this->bIsReturningXMLElement_ = false;
+        this->baseclassIdentifier_ = 0;
+    }
+
+    Template::~Template()
+    {
+        Template::getTemplateMap().erase(this->getName());
+        delete this->xmlelement_;
+    }
+
+    void Template::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Template, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Template, "link",      setLink,         getLink,         xmlelement, mode);
+        XMLPortParam(Template, "baseclass", setBaseclass,    getBaseclass,    xmlelement, mode);
+        XMLPortParam(Template, "defaults",  setLoadDefaults, getLoadDefaults, xmlelement, mode).defaultValues(true);
+
+        Element* element = xmlelement.FirstChildElement(false);
+        if (element)
+        {
+            TiXmlElement* tixmlelement = static_cast<TiXmlElement*>(element->GetTiXmlPointer());
+            if (tixmlelement)
+                this->setXMLElement(*tixmlelement);
+        }
+    }
+
+    void Template::changedName()
+    {
+        SUPER(Template, changedName);
+
+        if (this->getName() != "")
+        {
+            std::map<std::string, Template*>::iterator it;
+            it = Template::getTemplateMap().find(this->getOldName());
+            if (it != Template::getTemplateMap().end())
+                Template::getTemplateMap().erase(it);
+
+            it = Template::getTemplateMap().find(this->getName());
+            if (it != Template::getTemplateMap().end())
+                COUT(2) << "Warning: Template with name \"" << this->getName() << "\" already exists." << std::endl;
+            else
+                Template::getTemplateMap()[this->getName()] = this;
+        }
+    }
+
+    void Template::setXMLElement(const TiXmlElement& xmlelement)
+    {
+        *this->xmlelement_ = xmlelement;
+    }
+
+    const TiXmlElement& Template::getXMLElement() const
+    {
+        if (this->bIsLink_)
+        {
+            Template* temp = Template::getTemplate(this->link_);
+            if (temp)
+            {
+                if (!temp->bIsReturningXMLElement_)
+                {
+                    this->bIsReturningXMLElement_ = true;
+                    const TiXmlElement& element = temp->getXMLElement();
+                    this->bIsReturningXMLElement_ = false;
+                    return element;
+                }
+                else
+                {
+                    COUT(2) << "Warning: Linking from " << this->getName() << " to " << this->link_ << " leads to an infinite loop. Returning own element." << std::endl;
+                }
+            }
+            else
+            {
+                COUT(2) << "Warning: " << this->link_ << " is not an existing Template name. Returning own element." << std::endl;
+            }
+        }
+
+        return *this->xmlelement_;
+    }
+
+    void Template::setBaseclass(const std::string& baseclass)
+    {
+        this->baseclassIdentifier_ = ClassByString(baseclass);
+        if (this->baseclassIdentifier_)
+            this->baseclass_ = baseclass;
+    }
+
+    void Template::applyOn(BaseObject* object)
+    {
+        if (this->baseclassIdentifier_)
+        {
+            if (!object->isA(this->baseclassIdentifier_))
+            {
+                COUT(1) << "Error: Can't apply template (name: " << this->getName() << "), object (name: " << object->getName() << ", class: " << object->getIdentifier()->getName() << ") is not a " << this->baseclassIdentifier_->getName() << std::endl;
+                return;
+            }
+        }
+
+        COUT(4) << object->getLoaderIndentation() << " aplying Template \"" << this->getName() << "\"..." << std::endl;
+
+        Element temp = &const_cast<TiXmlElement&>(this->getXMLElement());
+
+        if (this->bLoadDefaults_)
+            object->XMLPort(temp, XMLPort::LoadObject);
+        else
+            object->XMLPort(temp, XMLPort::ExpandObject);
+    }
+
+    std::map<std::string, Template*>& Template::getTemplateMap()
+    {
+        static std::map<std::string, Template*> templateMap;
+        return templateMap;
+    }
+
+    Template* Template::getTemplate(const std::string& name)
+    {
+        std::map<std::string, Template*>::iterator it = Template::getTemplateMap().find(name);
+        if (it != Template::getTemplateMap().end())
+            return it->second;
+        else
+        {
+            COUT(2) << "Warning: Template with name " << name << " doesn't exist." << std::endl;
+            return 0;
+        }
+    }
+
+    void Template::apply(const std::string& name, BaseObject* object)
+    {
+        std::map<std::string, Template*>::iterator it = Template::getTemplateMap().find(name);
+        if (it != Template::getTemplateMap().end())
+            it->second->applyOn(object);
+    }
+}
Index: code/trunk/src/libraries/core/Template.h
===================================================================
--- code/trunk/src/libraries/core/Template.h	(revision 5781)
+++ code/trunk/src/libraries/core/Template.h	(revision 5781)
@@ -0,0 +1,85 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Template_H__
+#define _Template_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include "BaseObject.h"
+
+namespace orxonox
+{
+    class _CoreExport Template : public BaseObject
+    {
+        public:
+            Template(BaseObject* creator);
+            virtual ~Template();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void changedName();
+
+            inline void setLink(const std::string& link)
+                { this->link_ = link; this->bIsLink_ = (link != ""); }
+            inline const std::string& getLink() const
+                { return this->link_; }
+
+            inline void setLoadDefaults(bool bLoadDefaults)
+                { this->bLoadDefaults_ = bLoadDefaults; }
+            inline bool getLoadDefaults() const
+                { return this->bLoadDefaults_; }
+
+            void setXMLElement(const TiXmlElement& xmlelement);
+            const TiXmlElement& getXMLElement() const;
+
+            void setBaseclass(const std::string& baseclass);
+            inline const std::string& getBaseclass() const
+                { return this->baseclass_; }
+            inline Identifier* getBaseclassIdentifier() const
+                { return this->baseclassIdentifier_; }
+
+            void applyOn(BaseObject* object);
+
+            static std::map<std::string, Template*>& getTemplateMap();
+            static Template* getTemplate(const std::string& name);
+            static void apply(const std::string& name, BaseObject* object);
+
+        private:
+            TiXmlElement* xmlelement_;
+            std::string link_;
+            std::string baseclass_;
+            Identifier* baseclassIdentifier_;
+            bool bIsLink_;
+            bool bLoadDefaults_;
+            mutable bool bIsReturningXMLElement_;
+    };
+}
+
+#endif /* _Template_H__ */
Index: code/trunk/src/libraries/core/WindowEventListener.cc
===================================================================
--- code/trunk/src/libraries/core/WindowEventListener.cc	(revision 5781)
+++ code/trunk/src/libraries/core/WindowEventListener.cc	(revision 5781)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WindowEventListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    unsigned int WindowEventListener::windowWidth_s  = 0;
+    unsigned int WindowEventListener::windowHeight_s = 0;
+
+    WindowEventListener::WindowEventListener()
+    {
+        RegisterRootObject(WindowEventListener);
+    }
+
+    //! Calls all registered objects
+    /*static*/ void WindowEventListener::moveWindow()
+    {
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowMoved();
+    }
+
+    //! Calls all registered objects and sets the static variables
+    /*static*/ void WindowEventListener::resizeWindow(unsigned int newWidth, unsigned int newHeight)
+    {
+        windowWidth_s = newWidth;
+        windowHeight_s = newHeight;
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowResized(newWidth, newHeight);
+    }
+
+    //! Calls all registered objects
+    /*static*/ void WindowEventListener::changeWindowFocus()
+    {
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowFocusChanged();
+    }
+}
Index: code/trunk/src/libraries/core/WindowEventListener.h
===================================================================
--- code/trunk/src/libraries/core/WindowEventListener.h	(revision 5781)
+++ code/trunk/src/libraries/core/WindowEventListener.h	(revision 5781)
@@ -0,0 +1,71 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WindowEventListener_H__
+#define _WindowEventListener_H__
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    //! Interface for receiving window events like resize, moved and focusChanged
+    class _CoreExport WindowEventListener : virtual public OrxonoxClass
+    {
+        friend class OgreWindowEventListener;
+
+        protected:
+            WindowEventListener();
+            virtual ~WindowEventListener() { }
+
+            //! Returns the current render window width
+            unsigned int getWindowWidth() const { return windowWidth_s; }
+            //! Returns the current render window height
+            unsigned int getWindowHeight() const { return windowHeight_s; }
+
+        private:
+            //! Window has been moved
+            virtual void windowMoved() { }
+
+            //! Window has resized
+            virtual void windowResized(unsigned int newWidth, unsigned int newHeight) { }
+
+            //! Window has lost/gained focus
+            virtual void windowFocusChanged() { }
+
+            static void moveWindow();
+            static void resizeWindow(unsigned int newWidth, unsigned int newHeight);
+            static void changeWindowFocus();
+
+            //! Static variable that holds the latest distributed information
+            static unsigned int windowWidth_s;
+            static unsigned int windowHeight_s;
+    };
+}
+
+#endif /* _WindowEventListener_H__ */
Index: code/trunk/src/libraries/core/XMLFile.h
===================================================================
--- code/trunk/src/libraries/core/XMLFile.h	(revision 5781)
+++ code/trunk/src/libraries/core/XMLFile.h	(revision 5781)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _XMLFile_H__
+#define _XMLFile_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include "ClassTreeMask.h"
+
+namespace orxonox
+{
+    class _CoreExport XMLFile
+    {
+        public:
+            XMLFile(const std::string& filename, const std::string& resourceGroup = "General")
+                : filename_(filename)
+                , group_(resourceGroup)
+                , bLuaSupport_(true)
+            { }
+            XMLFile(const ClassTreeMask& mask, const std::string& filename, const std::string& resourceGroup = "General")
+                : filename_(filename)
+                , group_(resourceGroup)
+                , mask_(mask)
+                , bLuaSupport_(true)
+            { }
+
+            void setLuaSupport(bool val) { bLuaSupport_ = val; }
+
+            const std::string& getFilename() const { return this->filename_; }
+            const std::string& getResourceGroup() const { return this->group_; }
+            const ClassTreeMask& getMask() const { return this->mask_; }
+            bool getLuaSupport() const { return this->bLuaSupport_; }
+
+        private:
+            std::string filename_;
+            std::string group_;
+            ClassTreeMask mask_;
+            bool bLuaSupport_; // Default is true
+    };
+}
+
+#endif /* _XMLFile_H__ */
Index: code/trunk/src/libraries/core/XMLNameListener.cc
===================================================================
--- code/trunk/src/libraries/core/XMLNameListener.cc	(revision 5781)
+++ code/trunk/src/libraries/core/XMLNameListener.cc	(revision 5781)
@@ -0,0 +1,38 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "XMLNameListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    XMLNameListener::XMLNameListener()
+    {
+        RegisterRootObject(XMLNameListener);
+    }
+}
Index: code/trunk/src/libraries/core/XMLNameListener.h
===================================================================
--- code/trunk/src/libraries/core/XMLNameListener.h	(revision 5781)
+++ code/trunk/src/libraries/core/XMLNameListener.h	(revision 5781)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _XMLNameListener_H__
+#define _XMLNameListener_H__
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport XMLNameListener : virtual public OrxonoxClass
+    {
+        public:
+            XMLNameListener();
+            virtual ~XMLNameListener() {}
+
+            virtual void loadedNewXMLName(BaseObject* object) = 0;
+    };
+}
+
+#endif /* _XMLNameListener_H__ */
Index: code/trunk/src/libraries/core/XMLPort.cc
===================================================================
--- code/trunk/src/libraries/core/XMLPort.cc	(revision 5781)
+++ code/trunk/src/libraries/core/XMLPort.cc	(revision 5781)
@@ -0,0 +1,43 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "XMLPort.h"
+
+#include "Loader.h"
+#include "Namespace.h"
+
+namespace orxonox
+{
+    // ################################
+    // ###  XMLPortObjectContainer  ###
+    // ################################
+    bool XMLPortObjectContainer::identifierIsIncludedInLoaderMask(const Identifier* identifier)
+    {
+        return ((!this->bApplyLoaderMask_) || identifier->isA(ClassIdentifier<Namespace>::getIdentifier()) || Loader::currentMask_s.isIncluded(identifier));
+    }
+}
Index: code/trunk/src/libraries/core/XMLPort.h
===================================================================
--- code/trunk/src/libraries/core/XMLPort.h	(revision 5781)
+++ code/trunk/src/libraries/core/XMLPort.h	(revision 5781)
@@ -0,0 +1,688 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the XMLPort helper classes and macros.
+
+    XMLPort is a virtual function of every BaseObject. Every object can change this function.
+    The XMLPort function gets called with an XMLElement, containing all attributes and
+    subclasses the object gets from the levelfile.
+
+    This file declares classes and macros to simplify XML-parsing.
+*/
+
+#ifndef _XMLPort_H__
+#define _XMLPort_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <tinyxml/ticpp.h>
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/MultiType.h"
+#include "util/OrxAssert.h"
+#include "Factory.h"
+#include "Identifier.h"
+#include "Executor.h"
+#include "BaseObject.h"
+
+// ------------
+// XMLPortParam
+
+/**
+    @brief Declares an XML attribute with a name, which will be set through load- and savefunctions.
+    @param classname The name of the class owning this param
+    @param paramname The name of the attribute
+    @param loadfunction A function to set the param in the object with a given value (~a set-function)
+    @param savefunction A function to get the value of the param from the object (~a get-function)
+    @param xmlelement The XMLElement, you get this from the XMLPort function
+    @param mode The mode (load or save), you get this from the XMLPort function
+
+    In the XML file, a param or attribute will be set like this:
+    <classname paramname="value" />
+
+    The macro will then call loadfunction(value) to set the given value (or call savefunction() to
+    write an existing value to an XML file).
+*/
+#define XMLPortParam(classname, paramname, loadfunction, savefunction, xmlelement, mode) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode)
+
+/**
+    @brief Declares an XML attribute with a name, which will be set through a variable.
+    @param classname The name of the class owning this param
+    @param paramname The name of the attribute
+    @param variable Name of the variable used to save and load the value
+    @param xmlelement The XMLElement, you get this from the XMLPort function
+    @param mode The mode (load or save), you get this from the XMLPort function
+
+    In the XML file, a param or attribute will be set like this:
+    <classname paramname="value" />
+
+    The macro will then store "value" in the variable or read it when saving.
+*/
+#define XMLPortParamVariable(classname, paramname, variable, xmlelement, mode) \
+    XMLPortVariableHelperClass xmlcontainer##variable##dummy(static_cast<void*>(&variable)); \
+    static ExecutorMember<orxonox::XMLPortVariableHelperClass>* xmlcontainer##variable##loadexecutor = static_cast<ExecutorMember<orxonox::XMLPortVariableHelperClass>*>(orxonox::createExecutor(orxonox::createFunctor(orxonox::XMLPortVariableHelperClass::getLoader(variable)), std::string( #classname ) + "::" + #variable + "loader")); \
+    static ExecutorMember<orxonox::XMLPortVariableHelperClass>* xmlcontainer##variable##saveexecutor = static_cast<ExecutorMember<orxonox::XMLPortVariableHelperClass>*>(orxonox::createExecutor(orxonox::createFunctor(orxonox::XMLPortVariableHelperClass::getSaver (variable)), std::string( #classname ) + "::" + #variable + "saver" )); \
+    XMLPortParamGeneric(xmlcontainer##variable, classname, orxonox::XMLPortVariableHelperClass, &xmlcontainer##variable##dummy, paramname, xmlcontainer##variable##loadexecutor, xmlcontainer##variable##saveexecutor, xmlelement, mode)
+
+/**
+    @brief This is the same as XMLPortParam, but you can set the template arguments needed to store the loadfunction.
+
+    Sometimes the name of the loadfunction is ambiguous (example: setPosition(Vector3) or
+    setPosition(float, float, float)). In this case, you can choose the right function by
+    telling the types of the functionparams. In our example, this would be either
+    > XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, Vector3);
+    or
+    > XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, float, float, float);
+    You don't have to use this, if there exist only one function with the given name.
+*/
+#define XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode)
+
+// --------------------
+// XMLPortParamLoadOnly
+
+/**
+    @brief Declares an XML attribute with a name, which can be set through a loadfunction.
+
+    This is the same as XMLPortParam, but you don't need a savefunction (get-function). Therefore,
+    this param won't be saved in an XML file, but you can add the attribute manually an it will be
+    loaded.
+
+    This might be helpful in cases, when you have several options to set a value, for example the
+    rotation. You can set the rotation with a quaternion, but you could also use three angles.
+    When saving the object, only one of both options has to be saved; this is, where this macro helps.
+*/
+#define XMLPortParamLoadOnly(classname, paramname, loadfunction, xmlelement, mode) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##0##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, xmlcontainer##loadfunction##0##loadexecutor, 0, xmlelement, mode)
+/**
+    @brief This is the same as XMLPortParamTemplate, but for load-only attributes (see XMLPortParamLoadOnly).
+*/
+#define XMLPortParamLoadOnlyTemplate(classname, paramname, loadfunction, xmlelement, mode, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##0##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, xmlcontainer##loadfunction##0##loadexecutor, 0, xmlelement, mode)
+
+// ------------------
+// XMLPortParamExtern
+
+/**
+    @brief This is the same as XMLPortParam, but for attributes in an extern class.
+    @param classname The name of the class owning the object owning the attribute
+    @param externclass The name of the extern class (the objects class)
+    @param object The name of the object of the extern class (a member of the main class)
+    @param paramname The name of the attribute
+    @param loadfunction The function to set the attribute inside of the member object.
+    @param loadfunction The function to get the attribute from the member object
+
+    Sometimes you'll have a member object in your class, which has it's own load- and savefunctions.
+    With this macro, you can simply use them instead of writing your own functions.
+
+    @example
+    Your class is called SpaceShip and this class has an object (myPilot_) of class Pilot. Pilot has a name
+    and two functions, setName(name) and getName(). Now you want an attribute "pilotname" in your
+    SpaceShip class. Instead of writing wrapper functions, you can simply use the XMLPortParamExtern
+    macro:
+    > XMLPortParamExtern(SpaceShip, Pilot, myPilot_, "pilotname", setName, getName, xmlelement, mode);
+*/
+#define XMLPortParamExtern(classname, externclass, object, paramname, loadfunction, savefunction, xmlelement, mode) \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction); \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode);
+/**
+    @brief This is the same as XMLPortParamTemplate, but for extern attributes (see XMLPortParamExtern).
+*/
+#define XMLPortParamExternTemplate(classname, externclass, object, paramname, loadfunction, savefunction, xmlelement, mode, ...) \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<externclass, __VA_ARGS__ >(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction); \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode);
+
+// -------------------
+// XMLPortParamGeneric
+
+/**
+    @brief This is the generic XMLPort param macro, which is used by all six specialized macros above.
+*/
+#define XMLPortParamGeneric(containername, classname, objectclass, object, paramname, loadexecutor, saveexecutor, xmlelement, mode) \
+    orxonox::XMLPortClassParamContainer<objectclass>* containername = static_cast<orxonox::XMLPortClassParamContainer<objectclass>*>(ClassIdentifier<classname>::getIdentifier()->getXMLPortParamContainer(paramname)); \
+    if (!containername) \
+    { \
+        containername = new orxonox::XMLPortClassParamContainer<objectclass>(std::string(paramname), ClassIdentifier<classname>::getIdentifier(), loadexecutor, saveexecutor); \
+        ClassIdentifier<classname>::getIdentifier()->addXMLPortParamContainer(paramname, containername); \
+    } \
+    containername->port(static_cast<BaseObject*>(this), object, xmlelement, mode)
+
+// --------------------
+// XMLPortObjectExtended
+
+/**
+    @brief Declares a possible sub-object that can be added in the XML file.
+    @param classname The name of the class that uses this macro
+    @param objectclass The baseclass of objects that can be added
+    @param sectionname The name of the subsection in the XML file that encloses the sub-objects ("" means no subsection)
+    @param loadfunction The function to add a new object to the class
+    @param loadfunction The function to get all added objects from the class
+    @param xmlelement The XMLElement (recieved through the XMLPort function)
+    @param mode The mode (load/save) (received through the XMLPort function)
+    @param bApplyLoaderMask If this is true, an added sub-object gets loaded only if it's class is included in the Loaders ClassTreeMask (this is usually false)
+    @param bLoadBefore If this is true, the sub-object gets loaded (through XMLPort) BEFORE it gets added to the main class (this is usually true)
+
+    bApplyLoaderMask is usually false for the following reason:
+    If the loaders mask says, for example, "load only SpaceShips" and you added weapons to the
+    SpaceShips, then the Weapons will still be loaded (which is most probably what you want).
+    Of course, if there are "standalone" weapons in the level, they wont be loaded.
+
+    If bLoadBefore is true, an added object already has all attributes set (like it's name). This is most
+    likely the best option, so this is usually true.
+
+    @note
+    The load- and savefunctions have to follow an exactly defined protocol.
+    Loadfunction:
+      The loadfunction gets a pointer to the object.
+      > void loadfunction(objectclass* pointer);
+
+    Savefunction:
+      The savefunction gets an index, starting with 0. For every returnvalue != 0, the savefunction
+      gets called again, but with index + 1. It's the functions responsibility to do something smart
+      with the index and to return 0 if all objects were returned.
+      > objectclass* savefunction(unsigned int index) const;
+
+      Possible implementation:
+        objectclass* savefunction(unsigned int index) const
+        {
+          if (index < number_of_added_objects_)
+            return my_added_objects[index];
+          else
+            return 0;
+        }
+
+    @example
+    Possible usage of the macro:
+    > XMLPortObject(SpaceShip, Weapon, "weapons", addWeapon, getWeapon, xmlelement, mode, false, true);
+
+    Now you can add weapons through the XML file:
+    <SpaceShip someattribute="..." ...>
+      <weapons>
+        <Weapon someattribute="..." ... />
+        <Weapon someattribute="..." ... />
+        <Weapon someattribute="..." ... />
+      </weapons>
+    </SpaceShip>
+
+    Note that "weapons" is the subsection. This allows you to add more types of sub-objects. In our example,
+    you could add pilots, blinking lights or other stuff. If you don't want a subsection, just use "" (an
+    empty string). Then you can add sub-objects directly into the mainclass.
+*/
+#define XMLPortObjectExtended(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore)
+/**
+    @brief This is the same as XMLPortObjectExtended, but you can specify the loadfunction by adding the param types. See XMLPortParamTemplate for more details about the types.
+*/
+#define XMLPortObjectExtendedTemplate(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore)
+
+// -------------
+// XMLPortObject
+
+/**
+    @brief This is the same as XMLPortObjectExtended, but bApplyLoaderMask is false and bLoadBefore is true by default.
+*/
+#define XMLPortObject(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, false, true)
+/**
+    @brief This is the same as XMLPortObject, but you can specify the loadfunction by adding the param types. See XMLPortParamTemplate for more details about the types.
+*/
+#define XMLPortObjectTemplate(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, false, true)
+
+// --------------------
+// XMLPortObjectGeneric
+
+/**
+    @brief Generic XMLPortObject macro, that gets called by all other XMLPortObject macros above.
+*/
+#define XMLPortObjectGeneric(containername, classname, objectclass, sectionname, loadexecutor, saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
+    orxonox::XMLPortClassObjectContainer<classname, objectclass>* containername = (orxonox::XMLPortClassObjectContainer<classname, objectclass>*)(ClassIdentifier<classname>::getIdentifier()->getXMLPortObjectContainer(sectionname)); \
+    if (!containername) \
+    { \
+        containername = new orxonox::XMLPortClassObjectContainer<classname, objectclass>(std::string(sectionname), ClassIdentifier<classname>::getIdentifier(), loadexecutor, saveexecutor, bApplyLoaderMask, bLoadBefore); \
+        ClassIdentifier<classname>::getIdentifier()->addXMLPortObjectContainer(sectionname, containername); \
+    } \
+    containername->port(this, xmlelement, mode)
+
+
+namespace orxonox
+{
+    // ###############################
+    // ###  XMLPortParamContainer  ###
+    // ###############################
+    class _CoreExport XMLPortParamContainer
+    {
+    public:
+        enum ParseResult
+        {
+            PR_not_started,
+            PR_finished,
+            PR_waiting_for_default_values
+        };
+
+        public:
+            XMLPortParamContainer()
+                { this->parseResult_ = PR_not_started; }
+            virtual ~XMLPortParamContainer() {}
+
+            inline const std::string& getName() const
+                { return this->paramname_; }
+
+            virtual XMLPortParamContainer& description(const std::string description) = 0;
+            virtual const std::string& getDescription() = 0;
+
+            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiType& param) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) = 0;
+
+        protected:
+            std::string paramname_;
+            ParseResult parseResult_;
+            Identifier* identifier_;
+            BaseObject* owner_;
+    };
+
+    template <class T>
+    class XMLPortClassParamContainer : public XMLPortParamContainer
+    {
+        struct ParseParams
+        {
+            T* object;
+            Element* xmlelement;
+            XMLPort::Mode mode;
+        };
+
+        public:
+            XMLPortClassParamContainer(const std::string paramname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor)
+            {
+                this->paramname_ = paramname;
+                this->identifier_ = identifier;
+                this->loadexecutor_ = loadexecutor;
+                this->saveexecutor_ = saveexecutor;
+            }
+
+            ~XMLPortClassParamContainer()
+            {
+                assert(this->loadexecutor_);
+                delete this->loadexecutor_;
+                if (this->saveexecutor_)
+                    delete this->saveexecutor_;
+            }
+
+            XMLPortParamContainer& port(BaseObject* owner, T* object, Element& xmlelement, XMLPort::Mode mode)
+            {
+                OrxAssert(owner, "XMLPortParamContainer must have a BaseObject as owner.");
+                this->owner_ = owner;
+                this->parseParams_.object = object;
+                this->parseParams_.xmlelement = &xmlelement;
+                this->parseParams_.mode = mode;
+
+                if ((mode == XMLPort::LoadObject) || (mode == XMLPort::ExpandObject))
+                {
+                    try
+                    {
+                        if (this->owner_->lastLoadedXMLElement_ != &xmlelement)
+                        {
+                            this->owner_->xmlAttributes_.clear();
+                            // Iterate through the attributes manually in order to make them case insensitive
+                            Attribute* attribute = xmlelement.FirstAttribute(false);
+                            while (attribute != 0)
+                            {
+                                this->owner_->xmlAttributes_[getLowercase(attribute->Name())] = attribute->Value();
+                                attribute = attribute->Next(false);
+                            }
+                            this->owner_->lastLoadedXMLElement_ = &xmlelement;
+                        }
+                        std::map<std::string, std::string>::const_iterator it = this->owner_->xmlAttributes_.find(getLowercase(this->paramname_));
+                        std::string attributeValue("");
+                        if (it != this->owner_->xmlAttributes_.end())
+                            attributeValue = it->second;
+
+                        // TODO: Checking the iterator would be better since then we can have strings with value "" as well.
+                        //       Unfortunately this does not seem to work with the Executor parser yet.
+                        if ((!attributeValue.empty()) || ((mode != XMLPort::ExpandObject) && this->loadexecutor_->allDefaultValuesSet()))
+                        {
+                            COUT(5) << this->owner_->getLoaderIndentation() << "Loading parameter " << this->paramname_ << " in " << this->identifier_->getName() << " (objectname " << this->owner_->getName() << ")." << std::endl << this->owner_->getLoaderIndentation();
+                            if (this->loadexecutor_->parse(object, attributeValue, ",") || (mode  == XMLPort::ExpandObject))
+                                this->parseResult_ = PR_finished;
+                            else
+                                this->parseResult_ = PR_waiting_for_default_values;
+                        }
+                        else if (mode == XMLPort::ExpandObject)
+                            this->parseResult_ = PR_finished;
+                        else
+                            this->parseResult_ = PR_waiting_for_default_values;
+                    }
+                    catch (ticpp::Exception& ex)
+                    {
+                        COUT(1) << std::endl;
+                        COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << this->owner_->getName() << ") in " << this->owner_->getFilename() << ":" << std::endl;
+                        COUT(1) << ex.what() << std::endl;
+                    }
+                }
+                else
+                {
+                    if (this->saveexecutor_)
+                    {
+//                        xmlelement.SetAttribute(this->paramname_, "...");
+                    }
+                }
+
+                return (*this);
+            }
+
+            XMLPortParamContainer& port(BaseObject* owner, const ParseParams& parseParams)
+            {
+                return this->port(owner, parseParams.object, *parseParams.xmlelement, parseParams.mode);
+            }
+
+            XMLPortParamContainer& portIfWaitingForDefaultValues(const ParseResult& result, const ParseParams& params)
+            {
+                if (result == PR_waiting_for_default_values)
+                    return this->port(this->owner_, params);
+                else
+                    return (*this);
+            }
+
+            virtual XMLPortParamContainer& description(const std::string description)
+                { this->loadexecutor_->setDescription(description); return (*this); }
+            virtual const std::string& getDescription()
+                { return this->loadexecutor_->getDescription(); }
+
+            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiType& param)
+            {
+                if (!this->loadexecutor_->defaultValueSet(index))
+                    this->loadexecutor_->setDefaultValue(index, param);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1)
+            {
+                if (!this->loadexecutor_->defaultValueSet(0))
+                    this->loadexecutor_->setDefaultValues(param1);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)))
+                    this->loadexecutor_->setDefaultValues(param1, param2);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)))
+                    this->loadexecutor_->setDefaultValues(param1, param2, param3);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)))
+                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)) || (!this->loadexecutor_->defaultValueSet(4)))
+                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4, param5);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+
+        private:
+            ExecutorMember<T>* loadexecutor_;
+            ExecutorMember<T>* saveexecutor_;
+            ParseParams parseParams_;
+    };
+
+
+    // ################################
+    // ###  XMLPortObjectContainer  ###
+    // ################################
+    class _CoreExport XMLPortObjectContainer
+    {
+        public:
+            XMLPortObjectContainer()
+                { this->bApplyLoaderMask_ = false; }
+            virtual ~XMLPortObjectContainer() {}
+
+            inline const std::string& getName() const
+                { return this->sectionname_; }
+
+            virtual XMLPortObjectContainer& description(const std::string description) = 0;
+            virtual const std::string& getDescription() = 0;
+
+            bool identifierIsIncludedInLoaderMask(const Identifier* identifier);
+
+        protected:
+            std::string sectionname_;
+            bool bApplyLoaderMask_;
+            bool bLoadBefore_;
+            Identifier* identifier_;
+    };
+
+    template <class T, class O>
+    class XMLPortClassObjectContainer : public XMLPortObjectContainer
+    {
+        public:
+            XMLPortClassObjectContainer(const std::string sectionname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore)
+            {
+                this->sectionname_ = sectionname;
+                this->identifier_ = identifier;
+                this->loadexecutor_ = loadexecutor;
+                this->saveexecutor_ = saveexecutor;
+                this->bApplyLoaderMask_ = bApplyLoaderMask;
+                this->bLoadBefore_ = bLoadBefore;
+            }
+
+            ~XMLPortClassObjectContainer()
+            {
+                assert(this->loadexecutor_);
+                delete this->loadexecutor_;
+                if (this->saveexecutor_)
+                    delete this->saveexecutor_;
+            }
+
+            XMLPortObjectContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode)
+            {
+                if ((mode == XMLPort::LoadObject) || (mode == XMLPort::ExpandObject))
+                {
+                    try
+                    {
+                        Element* xmlsubelement;
+                        if ((this->sectionname_ != "") && (this->sectionname_.size() > 0))
+                            xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
+                        else
+                            xmlsubelement = &xmlelement;
+
+                        if (xmlsubelement)
+                        {
+                            for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
+                            {
+                                Identifier* identifier = Factory::getIdentifier(child->Value());
+                                if (identifier)
+                                {
+                                    if (identifier->isA(ClassIdentifier<O>::getIdentifier()))
+                                    {
+                                        if (identifier->isLoadable())
+                                        {
+                                            if (this->identifierIsIncludedInLoaderMask(identifier))
+                                            {
+                                                try
+                                                {
+                                                    COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
+
+                                                    BaseObject* newObject = identifier->fabricate(static_cast<BaseObject*>(object));
+                                                    assert(newObject);
+                                                    newObject->setLoaderIndentation(object->getLoaderIndentation() + "  ");
+
+                                                    O* castedObject = orxonox_cast<O*>(newObject);
+                                                    assert(castedObject);
+
+                                                    if (this->bLoadBefore_)
+                                                    {
+                                                        newObject->XMLPort(*child, XMLPort::LoadObject);
+                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ")" << std::endl;
+                                                    }
+                                                    else
+                                                    {
+                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ")" << std::endl;
+                                                    }
+
+                                                    COUT(5) << object->getLoaderIndentation();
+                                                    (*this->loadexecutor_)(object, castedObject);
+
+                                                    if (!this->bLoadBefore_)
+                                                        newObject->XMLPort(*child, XMLPort::LoadObject);
+
+                                                    COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
+                                                }
+                                                catch (AbortLoadingException& ex)
+                                                {
+                                                    COUT(1) << "An error occurred while loading object, abort loading..." << std::endl;
+                                                    throw ex;
+                                                }
+                                                catch (...)
+                                                {
+                                                    COUT(1) << "An error occurred while loading object:" << std::endl;
+                                                    COUT(1) << Exception::handleMessage() << std::endl;
+                                                }
+                                            }
+                                        }
+                                        else
+                                        {
+                                            COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << ClassIdentifier<O>::getIdentifier()->getName() << "'." << std::endl;
+                                    }
+                                }
+                                else
+                                {
+                                    if (this->sectionname_ != "")
+                                    {
+                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
+                                    }
+                                    else
+                                    {
+                                        // It's probably just another subsection
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    catch (ticpp::Exception& ex)
+                    {
+                        COUT(1) << std::endl;
+                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << ClassIdentifier<O>::getIdentifier()->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ":" << std::endl;
+                        COUT(1) << ex.what() << std::endl;
+                    }
+                }
+                else
+                {
+                }
+
+                return (*this);
+            }
+
+            virtual XMLPortObjectContainer& description(const std::string description)
+                { this->loadexecutor_->setDescription(description); return (*this); }
+            virtual const std::string& getDescription()
+                { return this->loadexecutor_->getDescription(); }
+
+        private:
+            ExecutorMember<T>* loadexecutor_;
+            ExecutorMember<T>* saveexecutor_;
+    };
+
+
+    // ####################################
+    // ###  XMLPortVariableHelperClass  ###
+    // ####################################
+    /**
+    @brief
+        Helper class to load and save simple variables with XMLPort.
+
+        getLoader and getSaver were necessary to get the type T with
+        the help of template function type deduction (const T& is unused).
+        These functions return the adress of save<T> or load<T>.
+    */
+    class XMLPortVariableHelperClass
+    {
+        public:
+            XMLPortVariableHelperClass(void* var)
+                : variable_(var)
+                { }
+
+            template <class T>
+            void load(const T& value)
+                { *static_cast<T*>(this->variable_) = value; }
+
+            template <class T>
+            const T& save()
+                { return *static_cast<T*>(this->variable_); }
+
+            template <class T>
+            static void (XMLPortVariableHelperClass::*getLoader(const T& var))(const T& value)
+                { return &XMLPortVariableHelperClass::load<T>; }
+
+            template <class T>
+            static const T& (XMLPortVariableHelperClass::*getSaver(const T& var))()
+                { return &XMLPortVariableHelperClass::save<T>; }
+
+        private:
+            void* variable_;
+    };
+}
+
+#endif /* _XMLPort_H__ */
Index: code/trunk/src/libraries/core/input/Button.cc
===================================================================
--- code/trunk/src/libraries/core/input/Button.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/Button.cc	(revision 5781)
@@ -0,0 +1,257 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the different input handlers.
+*/
+
+#include "Button.h"
+
+#include "util/Convert.h"
+#include "util/SubString.h"
+#include "util/StringUtils.h"
+#include "util/Debug.h"
+#include "core/ConsoleCommand.h"
+#include "core/CommandEvaluation.h"
+#include "core/CommandExecutor.h"
+#include "core/ConfigValueContainer.h"
+
+namespace orxonox
+{
+    /**
+    @note
+        bButtonThresholdUser_: We set it to true so that setConfigValues in KeyBinder sets the value
+        correctly the first time. It is then set to false first and changed later in Button::parse().
+    */
+    Button::Button()
+        : configContainer_(0)
+        , bButtonThresholdUser_(false)
+        , paramCommandBuffer_(0)
+    {
+        nCommands_[0]=0;
+        nCommands_[1]=0;
+        nCommands_[2]=0;
+    }
+
+    Button::~Button()
+    {
+        this->clear();
+
+        if (this->configContainer_)
+            delete this->configContainer_;
+    }
+
+    void Button::clear()
+    {
+        for (unsigned int j = 0; j < 3; j++)
+        {
+            if (nCommands_[j])
+            {
+                // delete all commands and the command pointer array
+                for (unsigned int i = 0; i < nCommands_[j]; i++)
+                    delete commands_[j][i];
+                delete[] commands_[j];
+                commands_[j] = 0;
+                nCommands_[j] = 0;
+            }
+        }
+    }
+
+    void Button::readConfigValue(ConfigFileType configFile)
+    {
+        // create/get ConfigValueContainer
+        if (!configContainer_)
+        {
+            configContainer_ = new ConfigValueContainer(configFile, 0, groupName_, name_, "", name_);
+            configContainer_->callback(this, &Button::parse);
+        }
+        configContainer_->getValue(&bindingString_, this);
+    }
+
+    void Button::parse()
+    {
+        // delete all commands
+        clear();
+
+        if (isEmpty(bindingString_))
+            return;
+
+        // reset this to false first when parsing (was true before when parsing for the first time)
+        bButtonThresholdUser_ = false;
+
+        // use std::vector for a temporary dynamic array
+        std::vector<BaseCommand*> commands[3];
+
+        // separate the commands
+        SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
+            '\\', false, '"', false, '(', ')', false, '\0');
+
+        for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
+        {
+            if (commandStrings[iCommand] != "")
+            {
+                SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
+                    '\\', false, '"', false, '(', ')', false, '\0');
+
+                KeybindMode::Value mode = KeybindMode::None;
+                float paramModifier = 1.0f;
+                std::string commandStr = "";
+
+                for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken)
+                {
+                    std::string token = getLowercase(tokens[iToken]);
+
+                    if (token == "onpress")
+                        mode = KeybindMode::OnPress;
+                    else if (token == "onrelease")
+                        mode = KeybindMode::OnRelease;
+                    else if (token == "onhold")
+                        mode = KeybindMode::OnHold;
+                    else if (token == "buttonthreshold")
+                    {
+                        // for real axes, we can feed a ButtonThreshold argument
+                        ++iToken;
+                        if (iToken == tokens.size())
+                            continue;
+                        // may fail, but doesn't matter (default value already set)
+                        if (!convertValue(&buttonThreshold_, tokens[iToken + 1]))
+                            parseError("Could not parse 'ButtonThreshold' argument. \
+                                Switching to default value.", true);
+                        else
+                            this->bButtonThresholdUser_ = true;
+                    }
+                    else if (token == "scale")
+                    {
+                        ++iToken;
+                        if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
+                            parseError("Could not parse 'scale' argument. Switching to default value.", true);
+                    }
+                    else
+                    {
+                        // no input related argument
+                        // we interpret everything from here as a command string
+                        while (iToken != tokens.size())
+                            commandStr += tokens[iToken++] + " ";
+                    }
+                }
+
+                if (commandStr == "")
+                {
+                    parseError("No command string given.", false);
+                    continue;
+                }
+
+                // evaluate the command
+                CommandEvaluation eval = CommandExecutor::evaluate(commandStr);
+                if (!eval.isValid())
+                {
+                    parseError("Command evaluation failed.", true);
+                    continue;
+                }
+
+                // check for param command
+                int paramIndex = eval.getConsoleCommand()->getInputConfiguredParam_();
+                if (paramIndex >= 0)
+                {
+                    // parameter supported command
+                    ParamCommand* cmd = new ParamCommand();
+                    cmd->scale_ = paramModifier;
+
+                    // add command to the buffer if not yet existing
+                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer_->size(); iParamCmd++)
+                    {
+                        if ((*paramCommandBuffer_)[iParamCmd]->evaluation_.getConsoleCommand()
+                            == eval.getConsoleCommand())
+                        {
+                            // already in list
+                            cmd->paramCommand_ = (*paramCommandBuffer_)[iParamCmd];
+                            break;
+                        }
+                    }
+                    if (cmd->paramCommand_ == 0)
+                    {
+                        cmd->paramCommand_ = new BufferedParamCommand();
+                        paramCommandBuffer_->push_back(cmd->paramCommand_);
+                        cmd->paramCommand_->evaluation_ = eval;
+                        cmd->paramCommand_->paramIndex_ = paramIndex;
+                    }
+
+
+                    // we don't know whether this is an actual axis or just a button
+                    if (mode == KeybindMode::None)
+                    {
+                        if (!addParamCommand(cmd))
+                        {
+                            mode = eval.getConsoleCommand()->getKeybindMode();
+                            commands[mode].push_back(cmd);
+                        }
+                    }
+                }
+                else
+                {
+                    SimpleCommand* cmd = new SimpleCommand();
+                    cmd->evaluation_ = eval;
+
+                    if (mode == KeybindMode::None)
+                        mode = eval.getConsoleCommand()->getKeybindMode();
+
+                    commands[mode].push_back(cmd);
+                }
+            }
+        }
+
+        for (unsigned int j = 0; j < 3; j++)
+        {
+            nCommands_[j] = commands[j].size();
+            if (nCommands_[j])
+            {
+                commands_[j] = new BaseCommand*[nCommands_[j]];
+                for (unsigned int i = 0; i < commands[j].size(); i++)
+                    commands_[j][i] = commands[j][i];
+            }
+            else
+                commands_[j] = 0;
+        }
+    }
+
+    inline void Button::parseError(std::string message, bool serious)
+    {
+        if (serious)
+        {
+            COUT(2) << "Error while parsing binding for button/axis " << this->name_ << ". "
+                << message << std::endl;
+        }
+        else
+        {
+            COUT(3) << "Warning while parsing binding for button/axis " << this->name_ << ". "
+                << message << std::endl;
+        }
+    }
+}
Index: code/trunk/src/libraries/core/input/Button.h
===================================================================
--- code/trunk/src/libraries/core/input/Button.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/Button.h	(revision 5781)
@@ -0,0 +1,91 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _Button_H__
+#define _Button_H__
+
+#include "InputPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "InputCommands.h"
+#include "core/ConfigFileManager.h"
+
+namespace orxonox
+{
+    class _CoreExport Button
+    {
+    public:
+        Button();
+        virtual ~Button();
+        virtual void clear();
+        virtual bool addParamCommand(ParamCommand* command) { return false; }
+        void parse();
+        void readConfigValue(ConfigFileType configFile);
+        bool execute(KeybindMode::Value mode, float abs = 1.0f, float rel = 1.0f);
+
+        //! Container to allow for better configValue support
+        ConfigValueContainer* configContainer_;
+        //! The configured string value
+        std::string bindingString_;
+        //! Name of the trigger as strings
+        std::string name_;
+        //! Name of the group of input triggers
+        std::string groupName_;
+        //! Basic commands for OnPress, OnHold and OnRelease
+        BaseCommand** commands_[3];
+        //! Number of basic commands
+        unsigned int nCommands_[3];
+        //! Says how much it takes for an analog axis to trigger a button
+        //! Note: This variable is here to have only one parse() function.
+        float buttonThreshold_;
+        bool bButtonThresholdUser_;
+        //! Pointer to the list of parametrised commands
+        std::vector<BufferedParamCommand*>* paramCommandBuffer_;
+
+    private:
+        void parseError(std::string message, bool serious);
+    };
+
+    inline bool Button::execute(KeybindMode::Value mode, float abs, float rel)
+    {
+        // execute all the parsed commands in the string
+        for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
+            commands_[mode][iCommand]->execute(abs, rel);
+        return true;
+    }
+
+}
+
+#endif /* _Button_H__ */
Index: code/trunk/src/libraries/core/input/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/core/input/CMakeLists.txt	(revision 5781)
+++ code/trunk/src/libraries/core/input/CMakeLists.txt	(revision 5781)
@@ -0,0 +1,14 @@
+ADD_SOURCE_FILES(CORE_SRC_FILES
+  Button.cc
+  HalfAxis.cc
+  InputBuffer.cc
+  InputCommands.cc
+  InputManager.cc
+  InputState.cc
+  JoyStick.cc
+  JoyStickQuantityListener.cc
+  KeyBinder.cc
+  Keyboard.cc
+  KeyDetector.cc
+  Mouse.cc
+)
Index: code/trunk/src/libraries/core/input/HalfAxis.cc
===================================================================
--- code/trunk/src/libraries/core/input/HalfAxis.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/HalfAxis.cc	(revision 5781)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the different input handlers.
+*/
+
+#include "HalfAxis.h"
+#include "core/CommandEvaluation.h"
+
+namespace orxonox
+{
+    void HalfAxis::clear()
+    {
+        Button::clear();
+        if (nParamCommands_)
+        {
+            // delete all commands and the command pointer array
+            for (unsigned int i = 0; i < nParamCommands_; i++)
+                delete paramCommands_[i];
+            delete[] paramCommands_;
+            nParamCommands_ = 0;
+        }
+    }
+
+    bool HalfAxis::addParamCommand(ParamCommand* command)
+    {
+        ParamCommand** cmds = paramCommands_;
+        paramCommands_ = new ParamCommand*[++nParamCommands_];
+        unsigned int i;
+        for (i = 0; i < nParamCommands_ - 1; i++)
+            paramCommands_[i] = cmds[i];
+        paramCommands_[i] = command;
+        if (nParamCommands_ > 1)
+            delete[] cmds;
+        return true;
+    }
+}
Index: code/trunk/src/libraries/core/input/HalfAxis.h
===================================================================
--- code/trunk/src/libraries/core/input/HalfAxis.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/HalfAxis.h	(revision 5781)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _HalfAxis_H__
+#define _HalfAxis_H__
+
+#include "InputPrereqs.h"
+
+#include "Button.h"
+#include "InputCommands.h"
+
+namespace orxonox
+{
+    class _CoreExport HalfAxis : public Button
+    {
+    public:
+        HalfAxis()
+            : relVal_(0.0f)
+            , absVal_(0.0f)
+            , paramCommands_(0)
+            , nParamCommands_(0)
+            , pressed_(false)
+            , hasChanged_(false)
+        { }
+        using Button::execute;
+        bool execute();
+        bool addParamCommand(ParamCommand* command);
+        void clear();
+
+        // axis related
+        float relVal_;
+        float absVal_;
+        ParamCommand** paramCommands_;
+        unsigned int nParamCommands_;
+
+        // button related
+        bool pressed_;
+        bool hasChanged_;
+    };
+
+    inline bool HalfAxis::execute()
+    {
+        bool success = true;
+        for (unsigned int i = 0; i < nParamCommands_; i++)
+            success = paramCommands_[i]->execute(absVal_, relVal_) && success;
+        return success;
+    }
+}
+
+#endif /* _HalfAxis_H__ */
Index: code/trunk/src/libraries/core/input/InputBuffer.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputBuffer.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputBuffer.cc	(revision 5781)
@@ -0,0 +1,262 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "InputBuffer.h"
+
+#include "util/Clipboard.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+
+namespace orxonox
+{
+    InputBuffer::InputBuffer()
+    {
+        RegisterRootObject(InputBuffer);
+
+        this->buffer_ = "";
+        this->cursor_ = 0;
+        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
+                               ABCDEFGHIJKLMNOPQRSTUVWXYZ \
+                               äëïöüÄËÏÖÜáâàéêèíîìóôòúûù \
+                               0123456789 \
+                               \\\"(){}[]<>.:,;_-+*/=!?|$&%^~#";
+
+        this->lastKey_ = KeyCode::Unassigned;
+        this->timeSinceKeyPressed_ = 0.0f;
+        this->timeSinceKeyRepeated_ = 0.0f;
+        this->keysToRepeat_ = 0;
+
+        setConfigValues();
+    }
+
+    InputBuffer::InputBuffer(const std::string& allowedChars)
+    {
+        RegisterRootObject(InputBuffer);
+
+        this->allowedChars_ = allowedChars;
+        this->buffer_ = "";
+        this->cursor_ = 0;
+
+        this->lastKey_ = KeyCode::Unassigned;
+        this->timeSinceKeyPressed_ = 0.0f;
+        this->timeSinceKeyRepeated_ = 0.0f;
+        this->keysToRepeat_ = 0;
+
+        setConfigValues();
+    }
+
+    InputBuffer::~InputBuffer()
+    {
+        for (std::list<BaseInputBufferListenerTuple*>::const_iterator it = this->listeners_.begin();
+            it != this->listeners_.end(); ++it)
+            delete *it;
+    }
+
+    void InputBuffer::setConfigValues()
+    {
+        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat deleay of the input buffer");
+        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
+
+        if (keyRepeatDeleay_ < 0.0)
+        {
+            ResetConfigValue(keyRepeatDeleay_);
+        }
+        if (keyRepeatTime_ < 0.0)
+        {
+            ResetConfigValue(keyRepeatTime_);
+        }
+    }
+
+    void InputBuffer::set(const std::string& input, bool update)
+    {
+        this->clear(false);
+        this->insert(input, update);
+    }
+
+    void InputBuffer::insert(const std::string& input, bool update)
+    {
+        for (unsigned int i = 0; i < input.size(); ++i)
+        {
+            this->insert(input[i], false);
+
+            if (update)
+                this->updated(input[i], false);
+        }
+
+        if (update)
+            this->updated();
+    }
+
+    void InputBuffer::insert(const char& input, bool update)
+    {
+        if (this->charIsAllowed(input))
+        {
+            this->buffer_.insert(this->cursor_, 1, input);
+            ++this->cursor_;
+        }
+
+        if (update)
+            this->updated(input, true);
+    }
+
+    void InputBuffer::clear(bool update)
+    {
+        this->buffer_ = "";
+        this->cursor_ = 0;
+
+        if (update)
+            this->updated();
+    }
+
+    void InputBuffer::removeBehindCursor(bool update)
+    {
+        if (this->cursor_ > 0)
+        {
+            --this->cursor_;
+            this->buffer_.erase(this->cursor_, 1);
+
+            if (update)
+                this->updated();
+        }
+    }
+
+    void InputBuffer::removeAtCursor(bool update)
+    {
+        if (this->cursor_ < this->buffer_.size())
+        {
+            this->buffer_.erase(this->cursor_, 1);
+
+            if (update)
+                this->updated();
+        }
+    }
+
+    void InputBuffer::updated()
+    {
+        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->bListenToAllChanges_)
+                (*it)->callFunction();
+        }
+    }
+
+    void InputBuffer::updated(const char& update, bool bSingleInput)
+    {
+        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((!(*it)->trueKeyFalseChar_) && ((*it)->bListenToAllChanges_ || ((*it)->char_ == update)) && (!(*it)->bOnlySingleInput_ || bSingleInput))
+                (*it)->callFunction();
+        }
+    }
+
+    bool InputBuffer::charIsAllowed(const char& input)
+    {
+        if (this->allowedChars_ == "")
+            return true;
+        else
+            return (this->allowedChars_.find(input) != std::string::npos);
+    }
+
+
+    void InputBuffer::processKey(const KeyEvent& evt)
+    {
+        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
+            return;
+
+        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
+                (*it)->callFunction();
+        }
+
+        if (evt.isModifierDown(KeyboardModifier::Ctrl))
+        {
+            if (evt.getKeyCode() == KeyCode::V)
+                this->insert(fromClipboard());
+            else if (evt.getKeyCode() == KeyCode::C)
+                toClipboard(this->buffer_);
+            else if (evt.getKeyCode() == KeyCode::X)
+            {
+                toClipboard(this->buffer_);
+                this->clear();
+            }
+        }
+        else if (evt.isModifierDown(KeyboardModifier::Shift))
+        {
+            if (evt.getKeyCode() == KeyCode::Insert)
+                this->insert(fromClipboard());
+            else if (evt.getKeyCode() == KeyCode::Delete)
+            {
+                toClipboard(this->buffer_);
+                this->clear();
+            }
+        }
+
+        this->insert(static_cast<char>(evt.getText()));
+    }
+
+    /**
+        @brief This update() function is called by the InputManager if the InputBuffer is active.
+        @param dt Delta time
+    */
+    void InputBuffer::keyboardUpdated(float dt)
+    {
+        timeSinceKeyPressed_ += dt;
+        if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
+        {
+            // initial time out has gone by, start repeating keys
+            while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
+            {
+                timeSinceKeyRepeated_ += keyRepeatTime_;
+                keysToRepeat_++;
+            }
+        }
+    }
+
+    void InputBuffer::buttonPressed(const KeyEvent& evt)
+    {
+        lastKey_ = evt.getKeyCode();
+        timeSinceKeyPressed_ = 0.0;
+        timeSinceKeyRepeated_ = keyRepeatDeleay_;
+        keysToRepeat_ = 0;
+
+        processKey(evt);
+    }
+
+    void InputBuffer::buttonHeld(const KeyEvent& evt)
+    {
+        if (evt.getKeyCode() == lastKey_)
+        {
+            while (keysToRepeat_)
+            {
+                processKey(evt);
+                keysToRepeat_--;
+            }
+        }
+    }
+}
Index: code/trunk/src/libraries/core/input/InputBuffer.h
===================================================================
--- code/trunk/src/libraries/core/input/InputBuffer.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputBuffer.h	(revision 5781)
@@ -0,0 +1,188 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _InputBuffer_H__
+#define _InputBuffer_H__
+
+#include "InputPrereqs.h"
+
+#include <list>
+#include <string>
+#include "core/OrxonoxClass.h"
+#include "InputHandler.h"
+
+namespace orxonox
+{
+    class BaseInputBufferListenerTuple
+    {
+    public:
+        BaseInputBufferListenerTuple(bool bListenToAllChanges, bool bOnlySingleInput,
+            bool trueKeyFalseChar, char _char, KeyCode::ByEnum key)
+            : bListenToAllChanges_(bListenToAllChanges), bOnlySingleInput_(bOnlySingleInput),
+              trueKeyFalseChar_(trueKeyFalseChar), char_(_char), key_(key)
+        { }
+        virtual ~BaseInputBufferListenerTuple() { }
+        virtual void callFunction() = 0;
+        bool bListenToAllChanges_;
+        bool bOnlySingleInput_;
+        bool trueKeyFalseChar_;
+        char char_;
+        KeyCode::ByEnum key_;
+    };
+
+    template <class T>
+    class InputBufferListenerTuple : public BaseInputBufferListenerTuple
+    {
+    public:
+        InputBufferListenerTuple(T* listener, void (T::*function)(), bool bListenToAllChanges,
+            bool bOnlySingleInput, bool trueKeyFalseChar, char _char, KeyCode::ByEnum key)
+            : BaseInputBufferListenerTuple(bListenToAllChanges, bOnlySingleInput, trueKeyFalseChar, _char, key),
+              listener_(listener), function_(function)
+        { }
+        virtual ~InputBufferListenerTuple() { }
+        void callFunction()
+        {
+            (listener_->*function_)();
+        }
+        T* listener_;
+        void (T::*function_)();
+    };
+
+    class _CoreExport InputBuffer : public InputHandler, public OrxonoxClass
+    {
+        public:
+            InputBuffer();
+            ~InputBuffer();
+            InputBuffer(const std::string& allowedChars);
+
+            void setConfigValues();
+
+            template <class T>
+            void registerListener(T* listener, void (T::*function)(), bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, true, bOnlySingleInput, false, '\0', KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)() const, bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, true, bOnlySingleInput, false, '\0', KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)(), char _char, bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, bOnlySingleInput, false, _char, KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)() const, char _char, bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, bOnlySingleInput, false, _char, KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+
+            template <class T>
+            void registerListener(T* listener, void (T::*function)(), KeyCode::ByEnum key)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)() const, KeyCode::ByEnum key)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+
+            template <class T>
+            void unregisterListener(T* listener)
+            {
+                for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+                {
+                    InputBufferListenerTuple<T>* refListener = static_cast<InputBufferListenerTuple<T>*>(*it);
+                    if (refListener && refListener->listener_ == listener)
+                        this->listeners_.erase(it++);
+                    else
+                        it++;
+                }
+            }
+
+            void set(const std::string& input, bool update = true);
+            void insert(const std::string& input, bool update = true);
+            void insert(const char& input, bool update = true);
+            void clear(bool update = true);
+            void removeAtCursor(bool update = true);
+            void removeBehindCursor(bool update = true);
+
+            void updated();
+            void updated(const char& update, bool bSingleInput);
+
+            inline const std::string& get() const
+                { return this->buffer_; }
+            inline unsigned int getSize() const
+                { return this->buffer_.size(); }
+
+            inline unsigned int getCursorPosition() const
+                { return this->cursor_; }
+            inline void setCursorPosition(unsigned int cursor)
+                { if (cursor <= this->buffer_.size()) { this->cursor_ = cursor; } }
+            inline void setCursorToEnd()
+                { this->cursor_ = this->buffer_.size(); }
+            inline void setCursorToBegin()
+                { this->cursor_ = 0; }
+            inline void increaseCursor()
+                { if (this->cursor_ < this->buffer_.size()) { ++this->cursor_; } }
+            inline void decreaseCursor()
+                { if (this->cursor_ > 0) { --this->cursor_; } }
+
+        private:
+            bool charIsAllowed(const char& input);
+
+            void buttonPressed(const KeyEvent& evt);
+            void buttonHeld   (const KeyEvent& evt);
+            void processKey   (const KeyEvent& evt);
+
+            void keyboardUpdated(float dt);
+
+            std::string buffer_;
+            std::list<BaseInputBufferListenerTuple*> listeners_;
+            std::string allowedChars_;
+            unsigned int cursor_;
+
+            KeyCode::ByEnum lastKey_;
+            float timeSinceKeyPressed_;
+            float timeSinceKeyRepeated_;
+            int keysToRepeat_;
+
+            float keyRepeatDeleay_;
+            float keyRepeatTime_;
+    };
+}
+
+#endif /* _InputBuffer_H__ */
Index: code/trunk/src/libraries/core/input/InputCommands.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputCommands.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputCommands.cc	(revision 5781)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the different input handlers.
+*/
+
+#include "InputCommands.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###  BufferedParamCommand   ###
+    // ###############################
+
+    /**
+    @brief
+        Executes a buffered command. This is used for commands with additional
+        parameters.
+    @return
+        True if command execution was successful or value was zero.
+    */
+    bool BufferedParamCommand::execute()
+    {
+        if (this->abs_ != 0.0f || this->rel_ != 0.0f)
+        {
+            evaluation_.setEvaluatedParameter(paramIndex_, Vector2(abs_, rel_));
+            // reset
+            rel_ = 0.0;
+            abs_ = 0.0;
+            return evaluation_.execute();
+        }
+        else
+            return true;
+    }
+
+    // ###############################
+    // #####    ParamCommand     #####
+    // ###############################
+
+    /**
+    @brief
+        Executes a parameter command. The commmand string is not directly executed,
+        but instead stored in a buffer list so that values can be combined.
+    @return
+        Always true.
+    */
+    bool ParamCommand::execute(float abs, float rel)
+    {
+        BufferedParamCommand& cmd = *paramCommand_;
+        // command has an additional parameter
+        if (rel != 0.0f)
+        {
+            // calculate relative movement.
+            // scale_ says how much one keystroke is
+            cmd.rel_ += scale_ * rel;
+        }
+
+        if (abs != 0.0f)
+        {
+            cmd.abs_ += scale_ * abs;
+            if (cmd.abs_ > 1.0)
+                cmd.abs_ = 1.0;
+            if (cmd.abs_ < -1.0)
+                cmd.abs_ = -1.0;
+        }
+        return true;
+    }
+}
Index: code/trunk/src/libraries/core/input/InputCommands.h
===================================================================
--- code/trunk/src/libraries/core/input/InputCommands.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputCommands.h	(revision 5781)
@@ -0,0 +1,92 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _InputCommands_H__
+#define _InputCommands_H__
+
+#include "InputPrereqs.h"
+#include "core/CommandEvaluation.h"
+
+namespace orxonox
+{
+    class _CoreExport BufferedParamCommand
+    {
+    public:
+        BufferedParamCommand() : abs_(0.0f), rel_(0.0), paramIndex_(-1) { }
+        bool execute();
+
+        float abs_;
+        float rel_;
+        int paramIndex_;
+        CommandEvaluation evaluation_;
+    };
+
+    class _CoreExport BaseCommand
+    {
+    public:
+        virtual ~BaseCommand() { }
+        virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;
+    };
+
+    class _CoreExport SimpleCommand : public BaseCommand
+    {
+    public:
+        bool execute(float abs = 1.0f, float rel = 1.0f);
+
+        CommandEvaluation evaluation_;
+    };
+
+    /**
+    @brief
+        Executes a simple command with no additional paramters.
+    @return 
+        True if command execution was successful, false otherwise.
+    */
+    inline bool SimpleCommand::execute(float abs, float rel)
+    {
+        return evaluation_.execute();
+    }
+
+    class _CoreExport ParamCommand : public BaseCommand
+    {
+    public:
+        ParamCommand() : scale_(1.0f), paramCommand_(0) { }
+        bool execute(float abs = 1.0f, float rel = 1.0f);
+
+        float scale_;
+        BufferedParamCommand* paramCommand_;
+    };
+}
+
+#endif /* _InputCommands_H__ */
Index: code/trunk/src/libraries/core/input/InputDevice.h
===================================================================
--- code/trunk/src/libraries/core/input/InputDevice.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputDevice.h	(revision 5781)
@@ -0,0 +1,235 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of InputDevice and InputDeviceTemplated
+*/
+
+#ifndef _InputDevice_H__
+#define _InputDevice_H__
+
+#include "InputPrereqs.h"
+
+#include <vector>
+#include <ois/OISInputManager.h>
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "core/Clock.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Abstract base class for all input devices (mouse, keyboard and joy sticks).
+
+        It provides common virtual functions to be used by the InputManager.
+    */
+    class InputDevice
+    {
+    public:
+        //! Only resets the members
+        InputDevice(unsigned int id) : bCalibrating_(false), deviceID_(id) { }
+        virtual ~InputDevice() { }
+        //! Returns the device class (derived) name as string
+        virtual std::string getClassName() const = 0;
+        //! Updates the device which should in turn distribute events
+        virtual void update(const Clock& time) = 0;
+        //! Clear all button related buffers
+        virtual void clearBuffers() = 0;
+
+        //! Start calibrating (only useful for joy sticks)
+        void startCalibration()
+        {
+            bCalibrating_ = true;
+            this->calibrationStarted();
+        }
+
+        //! Stop calibrating and evaluate the data (only useful for joy sticks)
+        void stopCalibration()
+        {
+            this->calibrationStopped();
+            bCalibrating_ = false;
+        }
+
+        //! Returns a reference to the internal input state vector. Use with care!
+        std::vector<InputState*>& getStateListRef() { return this->inputStates_; }
+        //! Returns the ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
+        unsigned int getDeviceID() const { return this->deviceID_; }
+        //! Tells whether the device is in calibration mode
+        bool isCalibrating() const { return bCalibrating_; }
+
+    protected:
+        //! To be ovrridden by the subclass
+        virtual void calibrationStarted() { }
+        //! To be ovrridden by the subclass
+        virtual void calibrationStopped() { }
+
+        //! List of all input states that receive events from this device
+        std::vector<InputState*> inputStates_;
+
+    private:
+        InputDevice(const InputDevice& rhs); //!< Don't use!
+
+        bool bCalibrating_;                  //!< Whether the device is in calibration mode
+        const unsigned int deviceID_;        //!< ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
+    };
+
+    /**
+    @brief
+        Heavily templated base class for all three input devices.
+
+        The purpose of this class is not to provide an interface but rather
+        to reduce code redundancy. This concerns device creation and destruction
+        as well as common code for button events (press, release, hold).
+
+        In order to derive from this class you have to supply it with a struct
+        as template parameter that contains the necessary type traits.
+    */
+    template <class Traits>
+    class InputDeviceTemplated : public InputDevice
+    {
+        typedef typename Traits::DeviceClass DeviceClass;
+        typedef typename Traits::OISDeviceClass OISDeviceClass;
+        typedef typename Traits::ButtonType ButtonType;
+        typedef typename Traits::ButtonTypeParam ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = Traits::OISDeviceValue;
+
+    public:
+        //! Creates the OIS device
+        InputDeviceTemplated(unsigned int id, OIS::InputManager* oisInputManager)
+            : InputDevice(id)
+            , oisInputManager_(oisInputManager)
+        {
+            oisDevice_ = static_cast<OISDeviceClass*>(oisInputManager_->createInputObject(OISDeviceValue, true));
+            // Note: after the static_cast here, the casted this pointer becomes
+            //       invalid right until the subclass has been constructed!
+            oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
+            COUT(4) << "Instantiated a " << this->getClassName() << std::endl;
+        }
+
+        //! Destroys the OIS device
+        virtual ~InputDeviceTemplated()
+        {
+            try
+            {
+                oisInputManager_->destroyInputObject(oisDevice_);
+            }
+            catch (...)
+            {
+                COUT(1) << this->getClassName() << " destruction failed: " << Exception::handleMessage() << std::endl
+                        << "    Potential resource leak!" << std::endl;
+            }
+        }
+
+        //! Captures OIS events (which then get distributed to the derived class) and creates the button held events
+        void update(const Clock& time)
+        {
+            oisDevice_->capture();
+
+            // Call all the states with the held button event
+            for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
+                for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
+                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
+                        this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
+
+            // Call states with device update events
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID());
+
+            static_cast<DeviceClass*>(this)->updateImpl(time);
+        }
+
+        //! Clears the list of pressed buttons and calls the derived class's method
+        void clearBuffers()
+        {
+            pressedButtons_.clear();
+            static_cast<DeviceClass*>(this)->clearBuffersImpl();
+        }
+
+        // Returns a pointer to the OIS device
+        OISDeviceClass* getOISDevice()   { return this->oisDevice_; }
+        // Returns the name of the derived class as string
+        std::string getClassName() const { return DeviceClass::getClassNameImpl(); }
+
+    protected:
+        //! Common code for all button pressed events (updates pressed buttons list and calls the input states)
+        FORCEINLINE void buttonPressed(ButtonTypeParam button)
+        {
+            // check whether the button already is in the list (can happen when focus was lost)
+            unsigned int iButton = 0;
+            while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
+                iButton++;
+            if (iButton == pressedButtons_.size())
+                pressedButtons_.push_back(button);
+            else
+                return; // Button already pressed
+
+            // Call states
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->buttonEvent<ButtonEvent::TPress, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
+        }
+
+        //! Common code for all button released events (updates pressed buttons list and calls the input states)
+        FORCEINLINE void buttonReleased(ButtonTypeParam button)
+        {
+            // remove the button from the pressedButtons_ list
+            for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
+            {
+                if (pressedButtons_[iButton] == button)
+                {
+                    pressedButtons_.erase(pressedButtons_.begin() + iButton);
+                    break;
+                }
+            }
+
+            // Call states
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->buttonEvent<ButtonEvent::TRelease, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
+        }
+
+        //! Managed pointer to the OIS device
+        OISDeviceClass* oisDevice_;
+
+    private:
+        //!< Fallback dummy function for static polymorphism
+        void clearBuffersImpl() { }
+        //!< Fallback dummy function for static polymorphism
+        void updateImpl(const Clock& time) { }
+        //!< Fallback dummy function for static polymorphism
+        ButtonType& getButtonEventArg(ButtonType& button) { return button; }
+
+        std::vector<ButtonType> pressedButtons_; //!< List of all buttons that are currently pressed down
+        OIS::InputManager* oisInputManager_;     //!< Pointer to the OIS InputManager that can create and destroy devices
+    };
+}
+
+#endif /* _InputDevice_H__ */
Index: code/trunk/src/libraries/core/input/InputHandler.h
===================================================================
--- code/trunk/src/libraries/core/input/InputHandler.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputHandler.h	(revision 5781)
@@ -0,0 +1,148 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _InputHandler_H__
+#define _InputHandler_H__
+
+#include "InputPrereqs.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    namespace ButtonEvent
+    {
+        //! Helper enum to deploy events with the help of templates
+        enum Value
+        {
+            Press,
+            Release,
+            Hold
+        };
+
+        //! Enables function overloading with integer values
+        template <ButtonEvent::Value Event>
+        struct EnumToType { };
+        typedef EnumToType<Press>   TPress;
+        typedef EnumToType<Release> TRelease;
+        typedef EnumToType<Hold>    THold;
+    }
+
+    namespace KeyboardModifier
+    {
+        //! Keyboard modifiers (shift, ctrl and alt)
+        enum Enum
+        {
+            Shift = 0x0000001,
+            Ctrl  = 0x0000010,
+            Alt   = 0x0000100
+        };
+    }
+
+    //! Event argument for key events
+    class _CoreExport KeyEvent
+    {
+    public:
+        KeyEvent(const OIS::KeyEvent& evt)
+            : key_(static_cast<KeyCode::ByEnum>(evt.key))
+            , text_(evt.text)
+            , modifiers_(0)
+        { }
+        bool operator==(const KeyEvent& rhs) const
+            { return rhs.key_ == key_; }
+        bool operator!=(const KeyEvent& rhs) const
+            { return rhs.key_ != key_; }
+        void setModifiers(int modifiers)
+            { modifiers_ = modifiers; }
+
+        bool isModifierDown(KeyboardModifier::Enum modifier) const
+            { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); }
+        KeyCode::ByEnum getKeyCode() const
+            { return key_; }
+        unsigned int getText() const { return text_; }
+
+    private:
+        KeyCode::ByEnum key_;
+        unsigned int text_;
+        int modifiers_;
+    };
+
+    /**
+    @brief
+        Base class for all input handlers like KeyBinder, InputBuffer, etc.
+
+        Derive from this class if you wish to receive input events.
+        But keep in mind that this is pointless wihtout first having an InputState.
+    @note
+        The definitions for the button events with the weird arguments are simply
+        to avoid redunant code in the input devices.
+    */
+    class _CoreExport InputHandler
+    {
+    public:
+        virtual ~InputHandler() { }
+
+        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TPress)
+            { this->buttonPressed(button); }
+        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TRelease)
+            { this->buttonReleased(button); }
+        template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::THold)
+            { this->buttonHeld(button); }
+        void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)
+            { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }
+        void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)
+            { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }
+        void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)
+            { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }
+
+        virtual void buttonPressed (const KeyEvent& evt) { }
+        virtual void buttonReleased(const KeyEvent& evt) { }
+        virtual void buttonHeld    (const KeyEvent& evt) { }
+
+        virtual void buttonPressed (MouseButtonCode::ByEnum button) { }
+        virtual void buttonReleased(MouseButtonCode::ByEnum button) { }
+        virtual void buttonHeld    (MouseButtonCode::ByEnum button) { }
+        virtual void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
+        virtual void mouseScrolled (int abs, int rel) { }
+
+        virtual void buttonPressed (unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void buttonReleased(unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void buttonHeld    (unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void axisMoved     (unsigned int joyStick, unsigned int axis, float value){ }
+
+        virtual void keyboardUpdated(float dt) { }
+        virtual void mouseUpdated   (float dt) { }
+        virtual void joyStickUpdated(unsigned int joyStick, float dt) { }
+
+        virtual void allDevicesUpdated(float dt) { }
+
+        //! Use this input handler if you want to occupy a device in an input state.
+        static InputHandler EMPTY;
+    };
+}
+
+#endif /* _InputHandler_H__ */
Index: code/trunk/src/libraries/core/input/InputManager.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputManager.cc	(revision 5781)
@@ -0,0 +1,726 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the InputManager and a static variable from the InputHandler.
+*/
+
+#include "InputManager.h"
+
+#include <cassert>
+#include <climits>
+#include <ois/OISException.h>
+#include <ois/OISInputManager.h>
+#include <boost/foreach.hpp>
+
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "util/ScopeGuard.h"
+#include "core/Clock.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/CommandLine.h"
+#include "core/Functor.h"
+#include "core/GraphicsManager.h"
+
+#include "InputBuffer.h"
+#include "KeyDetector.h"
+#include "JoyStick.h"
+#include "JoyStickQuantityListener.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+
+namespace orxonox
+{
+    SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
+
+    // Abuse of this source file for the InputHandler
+    InputHandler InputHandler::EMPTY;
+
+    InputManager* InputManager::singletonPtr_s = 0;
+
+    //! Defines the |= operator for easier use.
+    inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval)
+    {
+        return (lval = (InputManager::State)(lval | rval));
+    }
+
+    //! Defines the &= operator for easier use.
+    inline InputManager::State operator&=(InputManager::State& lval, int rval)
+    {
+        return (lval = (InputManager::State)(lval & rval));
+    }
+
+    // ############################################################
+    // #####                  Initialisation                  #####
+    // ##########                                        ##########
+    // ############################################################
+    InputManager::InputManager()
+        : internalState_(Bad)
+        , oisInputManager_(0)
+        , devices_(2)
+        , bExclusiveMouse_(false)
+        , emptyState_(0)
+        , keyDetector_(0)
+        , calibratorCallbackHandler_(0)
+    {
+        RegisterRootObject(InputManager);
+
+        CCOUT(4) << "Constructing..." << std::endl;
+
+        this->setConfigValues();
+
+        this->loadDevices();
+
+        // Lowest priority empty InputState
+        emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty);
+        emptyState_->setHandler(&InputHandler::EMPTY);
+        activeStates_[emptyState_->getPriority()] = emptyState_;
+
+        // KeyDetector to evaluate a pressed key's name
+        InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector);
+        // Create a callback to avoid buttonHeld events after the key has been detected
+        FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers);
+        bufferFunctor->setObject(this);
+        detector->setLeaveFunctor(bufferFunctor);
+        keyDetector_ = new KeyDetector();
+        detector->setHandler(keyDetector_);
+
+        // Joy stick calibration helper callback
+        InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
+        calibrator->setHandler(&InputHandler::EMPTY);
+        calibratorCallbackHandler_ = new InputBuffer();
+        calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true);
+        calibrator->setKeyHandler(calibratorCallbackHandler_);
+
+        this->updateActiveStates();
+
+        {
+            // calibrate console command
+            FunctorMember<InputManager>* functor = createFunctor(&InputManager::calibrate);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "calibrate"), true);
+        }
+        {
+            // reload console command
+            FunctorMember<InputManager>* functor = createFunctor(&InputManager::reload);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "reload"), false);
+        }
+
+        CCOUT(4) << "Construction complete." << std::endl;
+        internalState_ = Nothing;
+    }
+
+    void InputManager::setConfigValues()
+    {
+    }
+
+    /**
+    @brief
+        Creates the OIS::InputMananger, the keyboard, the mouse and
+        the joys ticks. If either of the first two fail, this method throws an exception.
+    @param windowWidth
+        The width of the render window
+    @param windowHeight
+        The height of the render window
+    */
+    void InputManager::loadDevices()
+    {
+        CCOUT(4) << "Loading input devices..." << std::endl;
+
+        // When loading the devices they should not already be loaded
+        assert(internalState_ & Bad);
+        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
+        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
+        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
+
+        // Fill parameter list
+        OIS::ParamList paramList;
+        size_t windowHnd = GraphicsManager::getInstance().getRenderWindowHandle();
+        paramList.insert(std::make_pair("WINDOW", multi_cast<std::string>(windowHnd)));
+#if defined(ORXONOX_PLATFORM_WINDOWS)
+        paramList.insert(std::make_pair("w32_keyboard", "DISCL_NONEXCLUSIVE"));
+        paramList.insert(std::make_pair("w32_keyboard", "DISCL_FOREGROUND"));
+        paramList.insert(std::make_pair("w32_mouse", "DISCL_FOREGROUND"));
+        if (bExclusiveMouse_ || GraphicsManager::getInstance().isFullScreen())
+        {
+            // Disable Windows key plus special keys (like play, stop, next, etc.)
+            paramList.insert(std::make_pair("w32_keyboard", "DISCL_NOWINKEY"));
+            paramList.insert(std::make_pair("w32_mouse", "DISCL_EXCLUSIVE"));
+        }
+        else
+            paramList.insert(std::make_pair("w32_mouse", "DISCL_NONEXCLUSIVE"));
+#elif defined(ORXONOX_PLATFORM_LINUX)
+        // Enabling this is probably a bad idea, but whenever orxonox crashes, the setting stays on
+        // Trouble might be that the Pressed event occurs a bit too often...
+        paramList.insert(std::make_pair("XAutoRepeatOn", "true"));
+
+        if (bExclusiveMouse_ || GraphicsManager::getInstance().isFullScreen())
+        {
+            if (CommandLine::getValue("keyboard_no_grab").getBool())
+                paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
+            else
+                paramList.insert(std::make_pair("x11_keyboard_grab", "true"));
+            paramList.insert(std::make_pair("x11_mouse_grab",  "true"));
+            paramList.insert(std::make_pair("x11_mouse_hide", "true"));
+        }
+        else
+        {
+            paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
+            paramList.insert(std::make_pair("x11_mouse_grab",  "false"));
+            paramList.insert(std::make_pair("x11_mouse_hide", "false"));
+        }
+#endif
+
+        try
+        {
+            oisInputManager_ = OIS::InputManager::createInputSystem(paramList);
+            // Exception-safety
+            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
+            CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl;
+
+            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
+                devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard, oisInputManager_);
+            else
+                ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
+
+            // Successful initialisation
+            guard.Dismiss();
+        }
+        catch (const std::exception& ex)
+        {
+            oisInputManager_ = NULL;
+            internalState_ |= Bad;
+            ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
+        }
+
+        this->loadMouse();
+        this->loadJoySticks();
+
+        // Reorder states in case some joy sticks were added/removed
+        this->updateActiveStates();
+
+        CCOUT(4) << "Input devices loaded." << std::endl;
+    }
+
+    //! Creates a new orxonox::Mouse
+    void InputManager::loadMouse()
+    {
+        if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0)
+        {
+            try
+            {
+                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, oisInputManager_);
+            }
+            catch (const std::exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.what() << std::endl
+                         << "Proceeding without mouse support." << std::endl;
+            }
+        }
+        else
+            CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
+    }
+
+    //! Creates as many joy sticks as are available.
+    void InputManager::loadJoySticks()
+    {
+        for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++)
+        {
+            try
+            {
+                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i, oisInputManager_));
+            }
+            catch (const std::exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl;
+            }
+        }
+
+        // inform all JoyStick Device Number Listeners
+        std::vector<JoyStick*> joyStickList;
+        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
+            joyStickList.push_back(static_cast<JoyStick*>(devices_[i]));
+        JoyStickQuantityListener::changeJoyStickQuantity(joyStickList);
+    }
+
+    void InputManager::setKeyDetectorCallback(const std::string& command)
+    {
+        this->keyDetector_->setCallbackCommand(command);
+    }
+
+    // ############################################################
+    // #####                    Destruction                   #####
+    // ##########                                        ##########
+    // ############################################################
+
+    InputManager::~InputManager()
+    {
+        CCOUT(3) << "Destroying..." << std::endl;
+
+        // Destroy calibrator helper handler and state
+        delete keyDetector_;
+        this->destroyState("calibrator");
+        // Destroy KeyDetector and state
+        delete calibratorCallbackHandler_;
+        this->destroyState("detector");
+        // destroy the empty InputState
+        this->destroyStateInternal(this->emptyState_);
+
+        // destroy all user InputStates
+        while (statesByName_.size() > 0)
+            this->destroyStateInternal((*statesByName_.rbegin()).second);
+
+        if (!(internalState_ & Bad))
+            this->destroyDevices();
+
+        CCOUT(3) << "Destruction complete." << std::endl;
+    }
+
+    /**
+    @brief
+        Destoys all input devices (joy sticks, mouse, keyboard and OIS::InputManager)
+    @throw
+        Method does not throw
+    */
+    void InputManager::destroyDevices()
+    {
+        CCOUT(4) << "Destroying devices..." << std::endl;
+
+        BOOST_FOREACH(InputDevice*& device, devices_)
+        {
+            if (device == NULL)
+                continue;
+            std::string className = device->getClassName();
+            try
+            {
+                delete device;
+                device = 0;
+                CCOUT(4) << className << " destroyed." << std::endl;
+            }
+            catch (...)
+            {
+                COUT(1) << className << " destruction failed: " << Exception::handleMessage() << std::endl
+                        << "    Potential resource leak!" << std::endl;
+            }
+        }
+        devices_.resize(InputDeviceEnumerator::FirstJoyStick);
+
+        assert(oisInputManager_ != NULL);
+        try
+        {
+            OIS::InputManager::destroyInputSystem(oisInputManager_);
+        }
+        catch (...)
+        {
+            COUT(1) << "OIS::InputManager destruction failed" << Exception::handleMessage() << std::endl
+                    << "    Potential resource leak!" << std::endl;
+        }
+        oisInputManager_ = NULL;
+
+        internalState_ |= Bad;
+        CCOUT(4) << "Destroyed devices." << std::endl;
+    }
+
+    // ############################################################
+    // #####                     Reloading                    #####
+    // ##########                                        ##########
+    // ############################################################
+
+    void InputManager::reload()
+    {
+        if (internalState_ & Ticking)
+        {
+            // We cannot destroy OIS right now, because reload was probably
+            // caused by a user clicking on a GUI item. The stack trace would then
+            // include an OIS method. So it would be a very bad thing to destroy it..
+            internalState_ |= ReloadRequest;
+        }
+        else if (internalState_ & Calibrating)
+            CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
+        else
+            reloadInternal();
+    }
+
+    //! Internal reload method. Destroys the OIS devices and loads them again.
+    void InputManager::reloadInternal()
+    {
+        CCOUT(3) << "Reloading ..." << std::endl;
+
+        this->destroyDevices();
+        this->loadDevices();
+
+        internalState_ &= ~Bad;
+        internalState_ &= ~ReloadRequest;
+        CCOUT(4) << "Reloading complete." << std::endl;
+    }
+
+    // ############################################################
+    // #####                  Runtime Methods                 #####
+    // ##########                                        ##########
+    // ############################################################
+
+    void InputManager::update(const Clock& time)
+    {
+        if (internalState_ & Bad)
+            ThrowException(General, "InputManager was not correctly reloaded.");
+
+        else if (internalState_ & ReloadRequest)
+            reloadInternal();
+
+        // check for states to leave
+        if (!stateLeaveRequests_.empty())
+        {
+            for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin();
+                it != stateLeaveRequests_.end(); ++it)
+            {
+                (*it)->left();
+                // just to be sure that the state actually is registered
+                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
+
+                activeStates_.erase((*it)->getPriority());
+                if ((*it)->getPriority() < InputStatePriority::HighPriority)
+                    (*it)->setPriority(0);
+                updateActiveStates();
+            }
+            stateLeaveRequests_.clear();
+        }
+
+        // check for states to enter
+        if (!stateEnterRequests_.empty())
+        {
+            for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin();
+                it != stateEnterRequests_.end(); ++it)
+            {
+                // just to be sure that the state actually is registered
+                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
+
+                if ((*it)->getPriority() == 0)
+                {
+                    // Get smallest possible priority between 1 and maxStateStackSize_s
+                    for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                        rit != activeStates_.rend(); ++rit)
+                    {
+                        if (rit->first < InputStatePriority::HighPriority)
+                        {
+                            (*it)->setPriority(rit->first + 1);
+                            break;
+                        }
+                    }
+                    // In case no normal handler was on the stack
+                    if ((*it)->getPriority() == 0)
+                        (*it)->setPriority(1);
+                }
+                activeStates_[(*it)->getPriority()] = (*it);
+                updateActiveStates();
+                (*it)->entered();
+            }
+            stateEnterRequests_.clear();
+        }
+
+        // check for states to destroy
+        if (!stateDestroyRequests_.empty())
+        {
+            for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin();
+                it != stateDestroyRequests_.end(); ++it)
+            {
+                destroyStateInternal((*it));
+            }
+            stateDestroyRequests_.clear();
+        }
+
+        // check whether a state has changed its EMPTY situation
+        bool bUpdateRequired = false;
+        for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
+        {
+            if (it->second->hasExpired())
+            {
+                it->second->resetExpiration();
+                bUpdateRequired = true;
+            }
+        }
+        if (bUpdateRequired)
+            updateActiveStates();
+
+        // mark that we now start capturing and distributing input
+        internalState_ |= Ticking;
+
+        // Capture all the input and handle it
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->update(time);
+
+        // Update the states
+        for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
+            activeStatesTicked_[i]->update(time.getDeltaTime());
+
+        internalState_ &= ~Ticking;
+    }
+
+    /**
+    @brief
+        Updates the currently active states (according to activeStates_) for each device.
+        Also, a list of all active states (no duplicates!) is compiled for the general update().
+    */
+    void InputManager::updateActiveStates()
+    {
+        assert((internalState_ & InputManager::Ticking) == 0);
+        // temporary resize
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+        {
+            if (devices_[i] == NULL)
+                continue;
+            std::vector<InputState*>& states = devices_[i]->getStateListRef();
+            bool occupied = false;
+            states.clear();
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
+                {
+                    states.push_back(rit->second);
+                    if (!rit->second->bTransparent_)
+                        occupied = true;
+                }
+            }
+        }
+
+        // update tickables (every state will only appear once)
+        // Using a std::set to avoid duplicates
+        std::set<InputState*> tempSet;
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+            if (devices_[i] != NULL)
+                for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState)
+                    tempSet.insert(devices_[i]->getStateListRef()[iState]);
+
+        // copy the content of the std::set back to the actual vector
+        activeStatesTicked_.clear();
+        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
+            activeStatesTicked_.push_back(*it);
+
+        // Check whether we have to change the mouse mode
+        std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
+        if (mouseStates.empty() && bExclusiveMouse_ ||
+            !mouseStates.empty() && mouseStates.front()->getIsExclusiveMouse() != bExclusiveMouse_)
+        {
+            bExclusiveMouse_ = !bExclusiveMouse_;
+            if (!GraphicsManager::getInstance().isFullScreen())
+                this->reloadInternal();
+        }
+    }
+
+    void InputManager::clearBuffers()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->clearBuffers();
+    }
+
+    void InputManager::calibrate()
+    {
+        COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
+                << "When done, put the axex in the middle position and press enter." << std::endl;
+
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->startCalibration();
+
+        internalState_ |= Calibrating;
+        enterState("calibrator");
+    }
+
+    //! Tells all devices to stop the calibration and evaluate it. Buffers are being cleared as well!
+    void InputManager::stopCalibration()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->stopCalibration();
+
+        // restore old input state
+        leaveState("calibrator");
+        internalState_ &= ~Calibrating;
+        // Clear buffers to prevent button hold events
+        this->clearBuffers();
+
+        COUT(0) << "Calibration has been stored." << std::endl;
+    }
+
+    //! Gets called by WindowEventListener upon focus change --> clear buffers 
+    void InputManager::windowFocusChanged()
+    {
+        this->clearBuffers();
+    }
+
+    std::pair<int, int> InputManager::getMousePosition() const
+    {
+        Mouse* mouse = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse]);
+        if (mouse != NULL)
+        {
+            const OIS::MouseState state = mouse->getOISDevice()->getMouseState();
+            return std::make_pair(state.X.abs, state.Y.abs);
+        }
+        else
+            return std::make_pair(0, 0);
+    }
+
+    // ############################################################
+    // #####                    Input States                  #####
+    // ##########                                        ##########
+    // ############################################################
+
+    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+    {
+        if (name == "")
+            return 0;
+        if (statesByName_.find(name) == statesByName_.end())
+        {
+            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            {
+                // Make sure we don't add two high priority states with the same priority
+                for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin();
+                    it != this->statesByName_.end(); ++it)
+                {
+                    if (it->second->getPriority() == priority)
+                    {
+                        COUT(2) << "Warning: Could not add an InputState with the same priority '"
+                            << static_cast<int>(priority) << "' != 0." << std::endl;
+                        return 0;
+                    }
+                }
+            }
+            InputState* state = new InputState(name, bAlwaysGetsInput, bTransparent, priority);
+            statesByName_[name] = state;
+
+            return state;
+        }
+        else
+        {
+            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
+            return 0;
+        }
+    }
+
+    InputState* InputManager::getState(const std::string& name)
+    {
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    bool InputManager::enterState(const std::string& name)
+    {
+        // get pointer from the map with all stored handlers
+        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+        {
+            // exists
+            if (activeStates_.find(it->second->getPriority()) == activeStates_.end())
+            {
+                // not active
+                if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end())
+                {
+                    // not scheduled for destruction
+                    // prevents a state being added multiple times
+                    stateEnterRequests_.insert(it->second);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    bool InputManager::leaveState(const std::string& name)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        // get pointer from the map with all stored handlers
+        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+        {
+            // exists
+            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
+            {
+                // active
+                stateLeaveRequests_.insert(it->second);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool InputManager::destroyState(const std::string& name)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+        {
+            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
+            {
+                // The state is still active. We have to postpone
+                stateLeaveRequests_.insert(it->second);
+                stateDestroyRequests_.insert(it->second);
+            }
+            else if (this->internalState_ & Ticking)
+            {
+                // cannot remove state while ticking
+                stateDestroyRequests_.insert(it->second);
+            }
+            else
+                destroyStateInternal(it->second);
+
+            return true;
+        }
+        return false;
+    }
+
+    //! Destroys an InputState internally.
+    void InputManager::destroyStateInternal(InputState* state)
+    {
+        assert(state && !(this->internalState_ & Ticking));
+        std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
+        if (it != this->activeStates_.end())
+        {
+            this->activeStates_.erase(it);
+            updateActiveStates();
+        }
+        statesByName_.erase(state->getName());
+        delete state;
+    }
+}
Index: code/trunk/src/libraries/core/input/InputManager.h
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputManager.h	(revision 5781)
@@ -0,0 +1,215 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _InputManager_H__
+#define _InputManager_H__
+
+#include "InputPrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "util/Singleton.h"
+#include "core/WindowEventListener.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Manages the input devices (mouse, keyboard, joy sticks) and the input states.
+
+        Every input device has its own wrapper class which does the actualy input event
+        distribution. The InputManager only creates reloads (on request) those devices.
+
+        The other functionality concerns handling InputStates. They act as a layer
+        between InputHandlers (like the KeyBinder or the GUIManager) and InputDevices.
+        InputStates are memory managed by the IputManager. You cannot create or destroy
+        them on your own. Therefore all states get destroyed with the InputManager d'tor.
+    @note
+        - The actual lists containing all the InputStates for a specific device are stored
+          in the InputDevices themselves.
+        - The devices_ vector always has at least two elements: Keyboard (first) and mouse.
+          You best access them intenally with InputDeviceEnumerator::Keyboard/Mouse
+          The first joy stick is accessed with InputDeviceEnumerator::FirstJoyStick.
+        - Keyboard construction is mandatory , mouse and joy sticks are not.
+          If the OIS::InputManager or the Keyboard fail, an exception is thrown.
+    */
+    class _CoreExport InputManager : public Singleton<InputManager>, public WindowEventListener
+    {
+        friend class Singleton<InputManager>;
+    public:
+        //! Represents internal states of the InputManager.
+        enum State
+        {
+            Nothing       = 0x00,
+            Bad           = 0x02,
+            Ticking       = 0x04,
+            Calibrating   = 0x08,
+            ReloadRequest = 0x10,
+        };
+
+        /**
+        @brief
+            Loads the devices and initialises the KeyDetector and the Calibrator.
+            
+            If either the OIS input system and/or the keyboard could not be created,
+            the constructor fails with an std::exception.
+        */
+        InputManager();
+        //! Destroys all devices AND all input states!
+        ~InputManager();
+        void setConfigValues();
+
+        /**
+        @brief
+            Updates the devices (which distribute the input events) and the input states.
+
+            Any InpuStates changes (destroy, enter, leave) and happens here. If a reload request
+            was submitted while updating, the request wil be postponed until the next update call.
+        */
+        void update(const Clock& time);
+        //! Clears all input device buffers. This usually only includes the pressed button list.
+        void clearBuffers();
+        //! Starts joy stick calibration.
+        void calibrate();
+        /**
+        @brief
+            Reloads all the input devices. Use this method to initialise new joy sticks.
+        @note
+            Only reloads immediately if the call stack doesn't include the update() method.
+        */
+        void reload();
+
+        //-------------------------------
+        // Input States
+        //-------------------------------
+        /**
+        @brief
+            Creates a new InputState that gets managed by the InputManager.
+        @remarks
+            The InputManager will take care of the state completely. That also
+            means it gets deleted when the InputManager is destroyed!
+        @param name
+            Unique name of the InputState when referenced as string
+        @param priority
+            Priority matters when multiple states are active. You can specify any
+            number, but 1 - 99 is preferred (99 means high priority).
+        */
+        InputState* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
+        /**
+        @brief
+            Returns a pointer to a InputState referenced by name.
+        @return
+            Returns NULL if state was not found.
+        */
+        InputState* getState(const std::string& name);
+        /**
+        @brief
+            Activates a specific input state.
+            It might not be actually activated if the priority is too low!
+        @return
+            False if name was not found, true otherwise.
+        */
+        bool enterState(const std::string& name);
+        /**
+        @brief
+            Deactivates a specific input state.
+        @return
+            False if name was not found, true otherwise.
+        */
+        bool leaveState(const std::string& name);
+        /**
+        @brief
+            Removes and destroys an input state.
+        @return
+            True if removal was successful, false if name was not found.
+        @remarks
+            - You can't remove the internal states "empty", "calibrator" and "detector".
+            - The removal process is being postponed if InputManager::update() is currently running.
+        */
+        bool destroyState(const std::string& name);
+
+        //-------------------------------
+        // Various getters and setters
+        //-------------------------------
+        //! Sets the the name of the command used by the KeyDetector as callback.
+        void setKeyDetectorCallback(const std::string& command);
+        //! Returns the number of joy stick that have been created since the c'tor or last call to reload().
+        unsigned int getJoyStickQuantity() const
+            { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
+        //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
+        OIS::InputManager* getOISInputManager() { return this->oisInputManager_; }
+        std::pair<int, int> getMousePosition() const;
+
+    private: // functions
+        // don't mess with a Singleton
+        InputManager(const InputManager&);
+
+        // Intenal methods
+        void loadDevices();
+        void loadMouse();
+        void loadJoySticks();
+        void destroyDevices();
+
+        void stopCalibration();
+        void reloadInternal();
+
+        void destroyStateInternal(InputState* state);
+        void updateActiveStates();
+
+        // From WindowEventListener
+        void windowFocusChanged();
+
+    private: // variables
+        State                               internalState_;        //!< Current internal state
+        OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
+        std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
+        bool                                bExclusiveMouse_;      //!< Currently applied mouse mode
+
+        // some internally handled states and handlers
+        InputState*                         emptyState_;           //!< Lowest priority states (makes handling easier)
+        KeyDetector*                        keyDetector_;          //!< KeyDetector instance
+        //! InputBuffer that reacts to the Enter key when calibrating the joy sticks
+        InputBuffer*                        calibratorCallbackHandler_;
+
+        std::map<std::string, InputState*>  statesByName_;         //!< Contains all the created input states by name
+        std::map<int, InputState*>          activeStates_;         //!< Contains all active input states by priority (std::map is sorted!)
+        std::vector<InputState*>            activeStatesTicked_;   //!< Like activeStates_, but only contains the ones that currently receive events
+
+        std::set<InputState*>               stateEnterRequests_;   //!< Requests to enter a new state
+        std::set<InputState*>               stateLeaveRequests_;   //!< Requests to leave a running state
+        std::set<InputState*>               stateDestroyRequests_; //!< Requests to destroy a state
+
+        static InputManager*                singletonPtr_s;        //!< Pointer reference to the singleton
+    };
+}
+
+#endif /* _InputManager_H__ */
Index: code/trunk/src/libraries/core/input/InputPrereqs.h
===================================================================
--- code/trunk/src/libraries/core/input/InputPrereqs.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputPrereqs.h	(revision 5781)
@@ -0,0 +1,452 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declarations of all key/button/axis code enumeration and string literals
+    and an input device enumeration.
+*/
+
+#ifndef _InputPrereqs_H__
+#define _InputPrereqs_H__
+
+#include "core/CorePrereqs.h"
+
+#include <ois/OISKeyboard.h>
+#include <ois/OISMouse.h>
+#include <ois/OISJoyStick.h>
+
+namespace orxonox
+{
+    //-----------------------------------------------------------------------
+    // Code enumerations
+    //-----------------------------------------------------------------------
+
+    namespace KeyCode
+    {
+        const unsigned int numberOfKeys = 0xEE; // 238
+
+        //! Key codes as enumeration
+        enum ByEnum
+        {
+            Unassigned    = OIS::KC_UNASSIGNED,
+            Escape        = OIS::KC_ESCAPE,
+            NumRow1       = OIS::KC_1,
+            NumRow2       = OIS::KC_2,
+            NumRow3       = OIS::KC_3,
+            NumRow4       = OIS::KC_4,
+            NumRow5       = OIS::KC_5,
+            NumRow6       = OIS::KC_6,
+            NumRow7       = OIS::KC_7,
+            NumRow8       = OIS::KC_8,
+            NumRow9       = OIS::KC_9,
+            NumRow0       = OIS::KC_0,
+            Minus         = OIS::KC_MINUS,           // - on main keyboard
+            Equals        = OIS::KC_EQUALS,
+            Back          = OIS::KC_BACK,            // backspace
+            Tab           = OIS::KC_TAB,
+            Q             = OIS::KC_Q,
+            W             = OIS::KC_W,
+            E             = OIS::KC_E,
+            R             = OIS::KC_R,
+            T             = OIS::KC_T,
+            Y             = OIS::KC_Y,
+            U             = OIS::KC_U,
+            I             = OIS::KC_I,
+            O             = OIS::KC_O,
+            P             = OIS::KC_P,
+            LeftBracket   = OIS::KC_LBRACKET,
+            RightBracket  = OIS::KC_RBRACKET,
+            Return        = OIS::KC_RETURN,          // Enter on main keyboard
+            LeftControl   = OIS::KC_LCONTROL,
+            A             = OIS::KC_A,
+            S             = OIS::KC_S,
+            D             = OIS::KC_D,
+            F             = OIS::KC_F,
+            G             = OIS::KC_G,
+            H             = OIS::KC_H,
+            J             = OIS::KC_J,
+            K             = OIS::KC_K,
+            L             = OIS::KC_L,
+            Semicolon     = OIS::KC_SEMICOLON,
+            Apostrophe    = OIS::KC_APOSTROPHE,
+            Grave         = OIS::KC_GRAVE,           // accent
+            LeftShift     = OIS::KC_LSHIFT,
+            Backslash     = OIS::KC_BACKSLASH,
+            Z             = OIS::KC_Z,
+            X             = OIS::KC_X,
+            C             = OIS::KC_C,
+            V             = OIS::KC_V,
+            B             = OIS::KC_B,
+            N             = OIS::KC_N,
+            M             = OIS::KC_M,
+            Comma         = OIS::KC_COMMA,
+            Period        = OIS::KC_PERIOD,          // . on main keyboard
+            Slash         = OIS::KC_SLASH,           // / on main keyboard
+            RightShift    = OIS::KC_RSHIFT,
+            Multiply      = OIS::KC_MULTIPLY,        // * on numeric keypad
+            LeftAlt       = OIS::KC_LMENU,           // left Alt
+            Space         = OIS::KC_SPACE,
+            CapsLock      = OIS::KC_CAPITAL,
+            F1            = OIS::KC_F1,
+            F2            = OIS::KC_F2,
+            F3            = OIS::KC_F3,
+            F4            = OIS::KC_F4,
+            F5            = OIS::KC_F5,
+            F6            = OIS::KC_F6,
+            F7            = OIS::KC_F7,
+            F8            = OIS::KC_F8,
+            F9            = OIS::KC_F9,
+            F10           = OIS::KC_F10,
+            NumLock       = OIS::KC_NUMLOCK,
+            ScrollLock    = OIS::KC_SCROLL,          // Scroll Lock
+            Numpad7       = OIS::KC_NUMPAD7,
+            Numpad8       = OIS::KC_NUMPAD8,
+            Numpad9       = OIS::KC_NUMPAD9,
+            NumpadSubtract= OIS::KC_SUBTRACT,        // - on numeric keypad
+            Numpad4       = OIS::KC_NUMPAD4,
+            Numpad5       = OIS::KC_NUMPAD5,
+            Numpad6       = OIS::KC_NUMPAD6,
+            NumpadAdd     = OIS::KC_ADD,             // + on numeric keypad
+            Numpad1       = OIS::KC_NUMPAD1,
+            Numpad2       = OIS::KC_NUMPAD2,
+            Numpad3       = OIS::KC_NUMPAD3,
+            Numpad0       = OIS::KC_NUMPAD0,
+            NumpadPeriod  = OIS::KC_DECIMAL,         // . on numeric keypad
+            LessThan      = OIS::KC_OEM_102,         // < > | on UK/Germany keyboards
+            F11           = OIS::KC_F11,
+            F12           = OIS::KC_F12,
+            F13           = OIS::KC_F13,             //                     (NEC PC98)
+            F14           = OIS::KC_F14,             //                     (NEC PC98)
+            F15           = OIS::KC_F15,             //                     (NEC PC98)
+            Kana          = OIS::KC_KANA,            // (Japanese keyboard)
+            ABNT_C1       = OIS::KC_ABNT_C1,         // / ? on Portugese (Brazilian) keyboards
+            Convert       = OIS::KC_CONVERT,         // (Japanese keyboard)
+            NoConvert     = OIS::KC_NOCONVERT,       // (Japanese keyboard)
+            Yen           = OIS::KC_YEN,             // (Japanese keyboard)
+            ABNT_C2       = OIS::KC_ABNT_C2,         // Numpad . on Portugese (Brazilian) keyboards
+            NumpadEquals  = OIS::KC_NUMPADEQUALS,    // = on numeric keypad (NEC PC98)
+            PreviousTrack = OIS::KC_PREVTRACK,       // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
+            AT            = OIS::KC_AT,              //                     (NEC PC98)
+            Colon         = OIS::KC_COLON,           //                     (NEC PC98)
+            Underline     = OIS::KC_UNDERLINE,       //                     (NEC PC98)
+            Kanji         = OIS::KC_KANJI,           // (Japanese keyboard)
+            Stop          = OIS::KC_STOP,            //                     (NEC PC98)
+            AX            = OIS::KC_AX,              //                     (Japan AX)
+            Unlabeled     = OIS::KC_UNLABELED,       //                        (J3100)
+            NextTrack     = OIS::KC_NEXTTRACK,       // Next Track
+            NumpadEnter   = OIS::KC_NUMPADENTER,     // Enter on numeric keypad
+            RightControl  = OIS::KC_RCONTROL,
+            Mute          = OIS::KC_MUTE,            // Mute
+            Calculator    = OIS::KC_CALCULATOR,      // Calculator
+            PlayPause     = OIS::KC_PLAYPAUSE,       // Play / Pause
+            MediaStop     = OIS::KC_MEDIASTOP,       // Media Stop
+            VolumeDown    = OIS::KC_VOLUMEDOWN,      // Volume -
+            VolumeUp      = OIS::KC_VOLUMEUP,        // Volume +
+            WebHome       = OIS::KC_WEBHOME,         // Web home
+            NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
+            Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
+            SystemRequest = OIS::KC_SYSRQ,
+            RightAlt      = OIS::KC_RMENU,           // right Alt
+            Pause         = OIS::KC_PAUSE,           // Pause
+            Home          = OIS::KC_HOME,            // Home on arrow keypad
+            Up            = OIS::KC_UP,              // UpArrow on arrow keypad
+            PageUp        = OIS::KC_PGUP,            // PgUp on arrow keypad
+            Left          = OIS::KC_LEFT,            // LeftArrow on arrow keypad
+            Right         = OIS::KC_RIGHT,           // RightArrow on arrow keypad
+            End           = OIS::KC_END,             // End on arrow keypad
+            Down          = OIS::KC_DOWN,            // DownArrow on arrow keypad
+            PageDown      = OIS::KC_PGDOWN,          // PgDn on arrow keypad
+            Insert        = OIS::KC_INSERT,          // Insert on arrow keypad
+            Delete        = OIS::KC_DELETE,          // Delete on arrow keypad
+            LeftWindows   = OIS::KC_LWIN,            // Left Windows key
+            RightWindows  = OIS::KC_RWIN,            // Right Windows key
+            Apps          = OIS::KC_APPS,            // AppMenu key
+            Power         = OIS::KC_POWER,           // System Power
+            Sleep         = OIS::KC_SLEEP,           // System Sleep
+            Wake          = OIS::KC_WAKE,            // System Wake
+            WebSearch     = OIS::KC_WEBSEARCH,       // Web Search
+            WebFavorites  = OIS::KC_WEBFAVORITES,    // Web Favorites
+            WebRefresh    = OIS::KC_WEBREFRESH,      // Web Refresh
+            WebStop       = OIS::KC_WEBSTOP,         // Web Stop
+            WebForward    = OIS::KC_WEBFORWARD,      // Web Forward
+            WebBack       = OIS::KC_WEBBACK,         // Web Back
+            MyComputer    = OIS::KC_MYCOMPUTER,      // My Computer
+            Mail          = OIS::KC_MAIL,            // Mail
+            MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
+        };
+        
+        //! Key codes as strings
+        const char* const ByString[] =
+        {
+            "Unassigned",
+            "Escape",
+            "NumRow1", "NumRow2", "NumRow3", "NumRow4", "NumRow5",
+            "NumRow6", "NumRow7", "NumRow8", "NumRow9", "NumRow0",
+            "Minus", "Equals", "Back", "Tab",
+            "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+            "LeftBracket", "RightBracket",
+            "Return", "LeftControl",
+            "A", "S", "D", "F", "G", "H", "J", "K", "L",
+            "Semicolon", "Apostrophe", "Grave",
+            "LeftShift", "Backslash",
+            "Z", "X", "C", "V", "B", "N", "M",
+            "Comma", "Period", "Slash",
+            "RightShift",
+            "Multiply",
+            "LeftAlt",
+            "Space",
+            "CapsLock",
+            "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
+            "NumLock", "ScrollLock",
+            "Numpad7", "Numpad8", "Numpad9",
+            "NumpadSubtract",
+            "Numpad4", "Numpad5", "Numpad6",
+            "NumpadAdd",
+            "Numpad1", "Numpad2", "Numpad3", "Numpad0",
+            "NumpadPeriod",
+            "","",
+            "LessThan",
+            "F11", "F12",
+            "","","","","","","","","","","",
+            "F13", "F14", "F15",
+            "","","","","","","","","","",
+            "Kana",
+            "","",
+            "ABNT_C1",
+            "","","","","",
+            "Convert",
+            "",
+            "NoConvert",
+            "",
+            "Yen",
+            "ABNT_C2",
+            "","","","","","","","","","","","","","",
+            "NumpadEquals",
+            "","",
+            "PreviousTrack",
+            "AT",
+            "Colon", "Underline",
+            "Kanji",
+            "Stop",
+            "AX",
+            "Unlabeled",
+            "NextTrack",
+            "","",
+            "NumpadEnter",
+            "RightControl",
+            "","",
+            "Mute",
+            "Calculator",
+            "PlayPause",
+            "",
+            "MediaStop",
+            "","","","","","","","","",
+            "VolumeDown",
+            "",
+            "VolumeUp",
+            "",
+            "WebHome",
+            "NumpadComma",
+            "",
+            "Divide",
+            "",
+            "SystemRequest",
+            "RightAlt",
+            "","","","","","","","","","","","",
+            "Pause",
+            "",
+            "Home",
+            "UP",
+            "PageUp",
+            "",
+            "Left",
+            "",
+            "Right",
+            "",
+            "End", "Down", "PageDown", "Insert", "Delete",
+            "","","","","","","",
+            "LeftWindows", "RightWindows", "Apps",
+            "Power", "Sleep",
+            "","","",
+            "Wake",
+            "",
+            "WebSearch", "WebFavorites", "WebRefresh", "WebStop", "WebForward", "WebBack",
+            "MyComputer", "Mail", "MediaSelect"
+        };
+    }
+
+
+    namespace MouseButtonCode
+    {
+        const unsigned int numberOfButtons = 8;
+
+        //! Mouse button codes as enumeration
+        enum ByEnum
+        {
+            Left    = OIS::MB_Left,
+            Right   = OIS::MB_Right,
+            Middle  = OIS::MB_Middle,
+            Button3 = OIS::MB_Button3,
+            Button4 = OIS::MB_Button4,
+            Button5 = OIS::MB_Button5,
+            Button6 = OIS::MB_Button6,
+            Button7 = OIS::MB_Button7,
+        };
+
+        // Mouse button codes as strings
+        const char* const ByString[] =
+        {
+            "Left",
+            "Right",
+            "Middle",
+            "Button3",
+            "Button4",
+            "Button5",
+            "Button6",
+            "Button7",
+        };
+    }
+
+    namespace MouseAxisCode
+    {
+        const unsigned int numberOfAxes = 2;
+
+        // Mouse axis codes as enumeration
+        enum ByEnum
+        {
+            X,
+            Y
+        };
+
+        // Mouse axis codes as strings
+        const char* const ByString[] =
+        {
+            "X",
+            "Y"
+        };
+    }
+
+
+    namespace JoyStickButtonCode
+    {
+        const unsigned int numberOfButtons = 64;
+
+        // Joy stick button codes as enumeration
+        enum ByEnum
+        {
+            Button0       =  0, Button1       =  1, Button2       =  2, Button3       =  3,
+            Button4       =  4, Button5       =  5, Button6       =  6, Button7       =  7,
+            Button8       =  8, Button9       =  9, Button10      = 10, Button11      = 11,
+            Button12      = 12, Button13      = 13, Button14      = 14, Button15      = 15,
+            Button16      = 16, Button17      = 17, Button18      = 18, Button19      = 19,
+            Button20      = 20, Button21      = 21, Button22      = 22, Button23      = 23,
+            Button24      = 24, Button25      = 25, Button26      = 26, Button27      = 27,
+            Button28      = 28, Button29      = 29, Button30      = 30, Button31      = 31,
+
+            POV0North     = 32, POV0South     = 33, POV0East      = 34, POV0West      = 35,
+            POV0NorthEast = 36, POV0SouthEast = 37, POV0NorthWest = 38, POV0SouthWest = 39,
+
+            POV1North     = 40, POV1South     = 41, POV1East      = 42, POV1West      = 43,
+            POV1NorthEast = 44, POV1SouthEast = 45, POV1NorthWest = 46, POV1SouthWest = 47,
+
+            POV2North     = 48, POV2South     = 49, POV2East      = 50, POV2West      = 51,
+            POV2NorthEast = 52, POV2SouthEast = 53, POV2NorthWest = 54, POV2SouthWest = 55,
+
+            POV3North     = 56, POV3South     = 57, POV3East      = 58, POV3West      = 59,
+            POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63,
+        };
+
+        // Joy stick button codes as strings
+        const char* const ByString[] =
+        {
+            "Button00",      "Button01",      "Button02",      "Button03",
+            "Button04",      "Button05",      "Button06",      "Button07",
+            "Button08",      "Button09",      "Button10",      "Button11",
+            "Button12",      "Button13",      "Button14",      "Button15",
+            "Button16",      "Button17",      "Button18",      "Button19",
+            "Button20",      "Button21",      "Button22",      "Button23",
+            "Button24",      "Button25",      "Button26",      "Button27",
+            "Button28",      "Button29",      "Button30",      "Button31",
+            "POV0North",     "POV0South",     "POV0East",      "POV0West",
+            "POV0NorthEast", "POV0SouthEast", "POV0NorthWest", "POV0SouthWest",
+            "POV1North",     "POV1South",     "POV1East",      "POV1West",
+            "POV1NorthEast", "POV1SouthEast", "POV1NorthWest", "POV1SouthWest",
+            "POV2North",     "POV2South",     "POV2East",      "POV2West",
+            "POV2NorthEast", "POV2SouthEast", "POV2NorthWest", "POV2SouthWest",
+            "POV3North",     "POV3South",     "POV3East",      "POV3West",
+            "POV3NorthEast", "POV3SouthEast", "POV3NorthWest", "POV3SouthWest"
+        };
+    }
+
+    namespace JoyStickAxisCode
+    {
+        const unsigned int numberOfAxes = 24;
+
+        // Joy stick axis codes as enumeration
+        enum ByEnum
+        {
+            Slider0 =  0, Slider1 =  1, Slider2 =  2, Slider3 =  3,
+            Slider4 =  4, Slider5 =  5, Slider6 =  6, Slider7 =  7,
+            Axis0   =  8, Axis1   =  9, Axis2   = 10, Axis3   = 11,
+            Axis4   = 12, Axis5   = 13, Axis6   = 14, Axis7   = 15,
+            Axis8   = 16, Axis9   = 17, Axis10  = 18, Axis11  = 19,
+            Axis12  = 20, Axis13  = 21, Axis14  = 22, Axis15  = 23
+        };
+
+        // Joy stick axis codes as strings
+        const char* const ByString[] =
+        {
+            "Slider0", "Slider1", "Slider2", "Slider3",
+            "Slider4", "Slider5", "Slider6", "Slider7",
+            "Axis00",  "Axis01",  "Axis02",  "Axis03",
+            "Axis04",  "Axis05",  "Axis06",  "Axis07",
+            "Axis08",  "Axis09",  "Axis10",  "Axis11",
+            "Axis12",  "Axis13",  "Axis14",  "Axis15"
+        };
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Miscellaneous
+    //-----------------------------------------------------------------------
+
+    namespace InputDeviceEnumerator
+    {
+        //! Used to access the devices in an array
+        enum Value
+        {
+            Keyboard = 0,
+            Mouse = 1,
+            FirstJoyStick = 2
+        };
+    }
+}
+
+#endif /* _InputPrereqs_H__ */
Index: code/trunk/src/libraries/core/input/InputState.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputState.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputState.cc	(revision 5781)
@@ -0,0 +1,112 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "InputState.h"
+#include "core/Functor.h"
+
+namespace orxonox
+{
+    //! Sets priority of it's a high priority and resizes the handler list
+    InputState::InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+        : name_(name)
+        , bAlwaysGetsInput_(bAlwaysGetsInput)
+        , bTransparent_(bTransparent)
+        , bExclusiveMouse_(true)
+        , bExpired_(true)
+        , handlers_(2)
+        , joyStickHandlerAll_(0)
+        , enterFunctor_(0)
+        , leaveFunctor_(0)
+    {
+        if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            priority_ = priority;
+        else
+            priority_ = 0;
+
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + this->getJoyStickList().size(), NULL);
+    }
+
+    bool InputState::isInputDeviceEnabled(unsigned int device)
+    {
+        if (device < handlers_.size())
+            return handlers_[device] != NULL;
+        else
+            return false;
+    }
+
+    //! Called by JoyStickQuantityListener upon joy stick adding/removal
+    void InputState::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        unsigned int oldSize = handlers_.size();
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + joyStickList.size(), NULL);
+
+        for (unsigned int i = oldSize; i < handlers_.size(); ++i)
+            handlers_[i] = joyStickHandlerAll_;
+
+        bExpired_ = true;
+    }
+
+    bool InputState::setJoyStickHandler(InputHandler* handler, unsigned int joyStick)
+    {
+        unsigned device = joyStick + firstJoyStickIndex_s;
+        if (joyStick >= handlers_.size() - device)
+            return false;
+
+        handlers_[device] = handler;
+        bExpired_ = true;
+        return true;
+    }
+
+    void InputState::setJoyStickHandler(InputHandler* handler)
+    {
+        joyStickHandlerAll_ = handler;
+        for (unsigned int i = firstJoyStickIndex_s; i < handlers_.size(); ++i)
+            handlers_[i] = handler;
+        bExpired_ = true;
+    }
+
+    void InputState::setHandler(InputHandler* handler)
+    {
+        setKeyHandler(handler);
+        setMouseHandler(handler);
+        setJoyStickHandler(handler);
+    }
+
+    void InputState::entered()
+    {
+        if (enterFunctor_)
+            (*enterFunctor_)();
+            
+    }
+
+    void InputState::left()
+    {
+        if (leaveFunctor_)
+            (*leaveFunctor_)();
+    }
+}
Index: code/trunk/src/libraries/core/input/InputState.h
===================================================================
--- code/trunk/src/libraries/core/input/InputState.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/InputState.h	(revision 5781)
@@ -0,0 +1,242 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _InputState_H__
+#define _InputState_H__
+
+#include "InputPrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <vector>
+
+#include "util/OrxEnum.h"
+#include "InputHandler.h"
+#include "JoyStickQuantityListener.h"
+
+namespace orxonox
+{
+    //! Enumeration wrapper for input state priorities
+    struct InputStatePriority : OrxEnum<InputStatePriority>
+    {
+        OrxEnumConstructors(InputStatePriority);
+
+        static const int Empty        = -1;
+        static const int Dynamic      = 0;
+
+        static const int HighPriority = 1000;
+        static const int Console      = HighPriority + 0;
+        static const int Calibrator   = HighPriority + 1;
+        static const int Detector     = HighPriority + 2;
+    };
+
+    /**
+    @brief
+        InputStates allow you to customise the input event targets at runtime.
+
+        The general idea is a stack: Every activated InputState will be pushed on
+        that stack and only the top one gets the input events. This is done for
+        every device (keyboard, mouse, all joy sticks) separately to allow
+        for intance keyboard input capturing for the console while you can still
+        steer a ship with the mouse.
+        There are two exceptions to this behaviour though:
+        - If an InputState is created with the 'Transparent' parameter on, the
+          state will not prevent input from getting to the state below it on the stack.
+          This can be useful for instance if you need to deploy input to multiple
+          handlers: Simply create two InputStates and make the high priority one transparent.
+        - If an InputState is created with the 'AlwaysGetsInput' parameter on, then
+          the state will always receive input as long as it is activated.
+        - Note: If you mark an InputState with both parameters on, then it will
+          not influence ony other InputState at all.
+
+    @par Priorities
+        Every InputState has a priority when on the stack, but mostly this
+        priority is dynamic (InputStatePriority::Dynamic) which means that a state
+        pushed onto the stack will simply have a higher priority than the top one.
+        This behaviour really only applies to normal states that don't have
+        a high priority (InputStatePriority::HighPriority). These 'special' ones
+        are used for features like the KeyDetector or the console. Use with care!
+
+    @par Exclusive/Non-Exclusive mouse Mode
+        You can select a specific mouse mode that tells whether the application
+        should have exclusive accessto it or not.
+        When in non-exclusive mode, you can move the mouse out of the window
+        like with any other normal window (only for windowed mode!).
+        The setting is dictated by the topmost InputState that gets mouse events.
+    */
+    class _CoreExport InputState : public JoyStickQuantityListener
+    {
+        friend class InputManager;
+
+        //! Marks the index in the handler vector for the keyboard handler
+        static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard;
+        //! Marks the index in the handler vector for the mouse handler
+        static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse;
+        //! Marks the index in the handler vector for the first joy stick handler
+        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
+
+    public:
+        //! Sets the keyboard event handler (overwrites if there already was one!)
+        void setKeyHandler     (InputHandler* handler)
+            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
+        //! Sets the mouse event handler (overwrites if there already was one!)
+        void setMouseHandler   (InputHandler* handler)
+            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
+        /**
+        @brief
+            Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!)
+        @return
+            Returns false if the specified device was not found
+        */
+        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
+        //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!)
+        void setJoyStickHandler(InputHandler* handler);
+        //! Sets an InputHandler to be used for all devices
+        void setHandler        (InputHandler* handler);
+
+        void setIsExclusiveMouse(bool value) { bExclusiveMouse_ = value; this->bExpired_ = true; }
+        bool getIsExclusiveMouse() const { return bExclusiveMouse_; }
+
+        //! Returns the name of the state (which is unique!)
+        const std::string& getName() const { return name_; }
+        //! Returns the priority of the state (which is unique if != 0)
+        int getPriority()            const { return priority_; }
+
+        //! Tells whether there a handler installed for a specific device
+        bool isInputDeviceEnabled(unsigned int device);
+
+        //! Returns true if the handler situation has changed
+        bool hasExpired()      { return this->bExpired_; }
+        //! Call this if you have applied the changes resulting from changed handlers
+        void resetExpiration() { bExpired_ = false; }
+
+        //! Updates one specific device handler with #device#Updated
+        void update(float dt, unsigned int device);
+        //! Updates all handlers with allDevicesUpdated
+        void update(float dt);
+
+        //! Generic function that distributes all 9 button events
+        template <typename EventType, class Traits>
+        void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
+
+        //! Event handler
+        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        //! Event handler
+        void mouseScrolled(int abs, int rel);
+        //! Event handler
+        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
+
+        // Functors
+        //! Called when the state is being activated (even if it doesn't get any events afterwards!)
+        void entered();
+        //! Called upon deactivation of the state
+        void left();
+        //! Sets a functor to be called upon activation of the state
+        void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; }
+        //! Sets a functor to be called upon deactivation of the state
+        void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; }
+
+    private:
+        InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority);
+        ~InputState() { }
+
+        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+
+        //! Sets the priority (only to be used by the InputManager!)
+        void setPriority(int priority) { priority_ = priority; }
+
+        const std::string           name_;                  //!< Name of the state
+        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
+        const bool                  bTransparent_;          //!< See class declaration for explanation
+        bool                        bExclusiveMouse_;       //!< See class declaration for explanation
+        int                         priority_;              //!< Current priority (might change)
+        bool                        bExpired_;              //!< See hasExpired()
+        std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID
+        //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached)
+        InputHandler*               joyStickHandlerAll_;
+        Functor*                    enterFunctor_;          //!< Functor to be executed on enter
+        Functor*                    leaveFunctor_;          //!< Functor to be executed on leave
+    };
+
+    FORCEINLINE void InputState::update(float dt)
+    {
+        for (unsigned int i = 0; i < handlers_.size(); ++i)
+            if (handlers_[i] != NULL)
+                handlers_[i]->allDevicesUpdated(dt);
+    }
+
+    FORCEINLINE void InputState::update(float dt, unsigned int device)
+    {
+        switch (device)
+        {
+        case InputDeviceEnumerator::Keyboard:
+            if (handlers_[keyboardIndex_s] != NULL)
+                handlers_[keyboardIndex_s]->keyboardUpdated(dt);
+            break;
+
+        case InputDeviceEnumerator::Mouse:
+            if (handlers_[mouseIndex_s] != NULL)
+                handlers_[mouseIndex_s]->mouseUpdated(dt);
+            break;
+
+        default: // joy sticks
+            if (handlers_[device] != NULL)
+                handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);
+            break;
+        }
+    }
+
+    template <typename EventType, class Traits>
+    FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)
+    {
+        assert(device < handlers_.size());
+        if (handlers_[device] != NULL)
+            handlers_[device]->buttonEvent(device, button, EventType());
+    }
+
+    FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
+    }
+
+    FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
+    }
+
+    FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
+    {
+        assert(device < handlers_.size());
+        if (handlers_[device] != NULL)
+            handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);
+    }
+}
+
+#endif /* _InputState_H__ */
Index: code/trunk/src/libraries/core/input/JoyStick.cc
===================================================================
--- code/trunk/src/libraries/core/input/JoyStick.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/JoyStick.cc	(revision 5781)
@@ -0,0 +1,261 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "JoyStick.h"
+
+#include <climits>
+#include <ois/OISJoyStick.h>
+#include <boost/foreach.hpp>
+
+#include "core/ConfigFileManager.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "util/Convert.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    //! Helper function that loads the config value vector of one coefficient
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
+
+    std::vector<std::string> JoyStick::deviceNames_s;
+
+    JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager)
+        : super(id, oisInputManager)
+    {
+        RegisterRootObject(JoyStick);
+        this->setConfigValues();
+        // Initialise POV and Slider states
+        this->clearBuffersImpl();
+
+        // Generate unique name
+        if (oisDevice_->vendor().empty())
+            deviceName_ = "Unknown_";
+        else
+        {
+            std::string name = oisDevice_->vendor();
+            replaceCharacters(name, ' ', '_');
+            deviceName_ = name + "_";
+        }
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + "_";
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
+        //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
+
+        BOOST_FOREACH(std::string& idString, deviceNames_s)
+        {
+            if (deviceName_ == idString)
+            {
+                // Make the ID unique for this execution time.
+                deviceName_ += "_" + multi_cast<std::string>(this->getDeviceName());
+                break;
+            }
+        }
+
+        COUT(4) << "Created OIS joy stick with ID " << deviceName_ << std::endl;
+
+        // Load calibration
+        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
+        loadCalibration(configMinValues_,  deviceName_, "MinValue",  axes,  -32768);
+        loadCalibration(configMaxValues_,  deviceName_, "MaxValue",  axes,   32768);
+        loadCalibration(configZeroValues_, deviceName_, "ZeroValue", axes, 0);
+        this->evaluateCalibration();
+    }
+
+    //! Callback for the joy stick calibration config file.
+    void JoyStick::calibrationFileCallback()
+    {
+        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
+    }
+
+    void JoyStick::setConfigValues()
+    {
+        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
+            .description("Ini filename for the the joy stick calibration data.")
+            .callback(this, &JoyStick::calibrationFileCallback);
+    }
+
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
+    {
+        list.resize(size);
+        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
+        if (configValueVectorSize > size)
+            configValueVectorSize = size;
+
+        for (unsigned int i = 0; i < configValueVectorSize; ++i)
+        {
+            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
+                ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
+        }
+
+        // fill the rest with default values
+        for (unsigned int i = configValueVectorSize; i < size; ++i)
+            list[i] = defaultValue;
+    }
+
+    //! Called by InputDevice when calibration mode has started
+    void JoyStick::calibrationStarted()
+    {
+        // Set initial values
+        BOOST_FOREACH(int& minVal, configMinValues_)
+            minVal = INT_MAX;
+        BOOST_FOREACH(int& minVal, configMaxValues_)
+            minVal = INT_MIN;
+        BOOST_FOREACH(int& zeroVal, configZeroValues_)
+            zeroVal = 0;
+    }
+
+    //! Called by InputDevice when calibration mode has stopped
+    void JoyStick::calibrationStopped()
+    {
+        // Get the middle positions now
+        unsigned int iAxis = 0;
+        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
+        {
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX;
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY;
+        }
+        // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration()
+        assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
+        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
+
+        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
+        {
+            // Minimum values
+            if (configMinValues_[i] == INT_MAX)
+                configMinValues_[i] = -32768;
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                deviceName_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
+
+            // Maximum values
+            if (configMaxValues_[i] == INT_MIN)
+                configMaxValues_[i] = 32767;
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                deviceName_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
+
+            // Middle values
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                deviceName_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
+        }
+
+        this->evaluateCalibration();
+    }
+
+    //! Evaluates the accumulated values during calibration
+    void JoyStick::evaluateCalibration()
+    {
+        for (unsigned int i = 0; i < configMinValues_.size(); i++)
+        {
+            zeroValues_[i] = configZeroValues_[i];
+            negativeCoeffs_[i] = - 1.0f / (configMinValues_[i] - configZeroValues_[i]);
+            positiveCoeffs_[i] =   1.0f / (configMaxValues_[i] - configZeroValues_[i]);
+        }
+    }
+
+    //! Resets the pov states
+    void JoyStick::clearBuffersImpl()
+    {
+        for (int j = 0; j < 4; ++j)
+            povStates_[j] = 0;
+    }
+
+    //! Generic method to forward axis events
+    void JoyStick::fireAxis(int axis, int value)
+    {
+        if (this->isCalibrating())
+        {
+            if (value < configMinValues_[axis])
+                configMinValues_[axis] = value;
+            if (value > configMaxValues_[axis])
+                configMaxValues_[axis] = value;
+        }
+        else
+        {
+            float fValue = static_cast<float>(value - zeroValues_[axis]);
+            if (fValue > 0.0f)
+                fValue *= positiveCoeffs_[axis];
+            else
+                fValue *= negativeCoeffs_[axis];
+
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
+        }
+    }
+
+    //! OIS joy stick axis event handler
+    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
+    {
+        // keep in mind that the first 8 axes are reserved for the sliders
+        this->fireAxis(axis + sliderAxes_s, arg.state.mAxes[axis].abs);
+
+        return true;
+    }
+
+    //! A Slider always has an X and an Y direction!
+    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        if (sliderStates_[id][0] != arg.state.mSliders[id].abX)
+            fireAxis(id * 2, arg.state.mSliders[id].abX);
+        else if (sliderStates_[id][1] != arg.state.mSliders[id].abY)
+            fireAxis(id * 2 + 1, arg.state.mSliders[id].abY);
+
+        return true;
+    }
+
+    //! A POV is the big button that can point in all directions (but only in one at once)
+    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        // translate the POV into 8 simple buttons
+
+        int lastState = povStates_[id];
+        if (lastState & OIS::Pov::North)
+            buttonReleased(arg, 32 + id * 4 + 0);
+        if (lastState & OIS::Pov::South)
+            buttonReleased(arg, 32 + id * 4 + 1);
+        if (lastState & OIS::Pov::East)
+            buttonReleased(arg, 32 + id * 4 + 2);
+        if (lastState & OIS::Pov::West)
+            buttonReleased(arg, 32 + id * 4 + 3);
+
+        povStates_[id] = arg.state.mPOV[id].direction;
+
+        int currentState = povStates_[id];
+        if (currentState & OIS::Pov::North)
+            buttonPressed(arg, 32 + id * 4 + 0);
+        if (currentState & OIS::Pov::South)
+            buttonPressed(arg, 32 + id * 4 + 1);
+        if (currentState & OIS::Pov::East)
+            buttonPressed(arg, 32 + id * 4 + 2);
+        if (currentState & OIS::Pov::West)
+            buttonPressed(arg, 32 + id * 4 + 3);
+
+        return true;
+    }
+}
Index: code/trunk/src/libraries/core/input/JoyStick.h
===================================================================
--- code/trunk/src/libraries/core/input/JoyStick.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/JoyStick.h	(revision 5781)
@@ -0,0 +1,132 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_JoyStick_H__
+#define _Core_JoyStick_H__
+
+#include "InputPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "InputDevice.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct JoyStickTraits
+    {
+        typedef JoyStick DeviceClass;
+        typedef OIS::JoyStick OISDeviceClass;
+        typedef JoyStickButtonCode::ByEnum ButtonType;
+        typedef JoyStickButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISJoyStick;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::JoyStick and forwards the input events to
+        a list of input states.
+
+        The class also supports joy stick calibration and stores the values
+        in an ini-file.
+    */
+    class _CoreExport JoyStick
+        : public OrxonoxClass
+        , public InputDeviceTemplated<JoyStickTraits>
+        , public OIS::JoyStickListener
+    {
+        friend class InputDeviceTemplated<JoyStickTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<JoyStickTraits> super;
+
+    public:
+        //! Assigns a generated ID string and loads the calibration (if present)
+        JoyStick(unsigned int id, OIS::InputManager* oisInputManager);
+        ~JoyStick() { }
+        void setConfigValues();
+
+        //! Returns the name generated from the number of knobs and the device name
+        const std::string& getDeviceName() const { return this->deviceName_; }
+
+    private:
+        void calibrationStarted();
+        void calibrationStopped();
+        void evaluateCalibration();
+
+        void clearBuffersImpl();
+        void calibrationFileCallback();
+        void fireAxis(int axis, int value);
+
+        //! OIS event handler
+        bool buttonPressed (const OIS::JoyStickEvent &arg, int button)
+        {
+            super::buttonPressed(static_cast<JoyStickButtonCode::ByEnum>(button));
+            return true;
+        }
+
+        //! OIS event handler
+        bool buttonReleased(const OIS::JoyStickEvent &arg, int button)
+        {
+            super::buttonReleased(static_cast<JoyStickButtonCode::ByEnum>(button));
+            return true;
+        }
+
+        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
+        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
+        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
+        //! OIS event handler (don't remove that because of OIS version issues!)
+        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
+
+        //! Returns the class name as string
+        static std::string getClassNameImpl() { return "JoyStick"; }
+
+        std::string deviceName_;              //!< Name generated by the number of knobs and the device name
+        int povStates_[4];                    //!< Internal states for the POVs
+        int sliderStates_[4][2];              //!< Internal states for the Sliders (each slider has X and Y!)
+
+        // calibration
+        int zeroValues_[24];                  //!< Axes values when the knob is in the middle
+        float positiveCoeffs_[24];            //!< Maps the negative part of an axis to a 0.0 to 1.0 floating range
+        float negativeCoeffs_[24];            //!< Maps the positive part of an axis to a 0.0 to 1.0 floating range
+
+        std::vector<int> configZeroValues_;   //!< Config file stored axis values when the knob is in the middle
+        std::vector<int> configMinValues_;    //!< Config file stored minimum axis values
+        std::vector<int> configMaxValues_;    //!< Config file stored maximum axis values
+
+        // ConfigValues
+        std::string calibrationFilename_;     //!< Joy stick calibration ini filename
+
+        //! Contains a list of all names to avoid duplicates
+        static std::vector<std::string> deviceNames_s;
+
+        //!< Maximum number of slider axes
+        static const unsigned int sliderAxes_s = 8;
+    };
+}
+
+#endif /* _Core_JoyStick_H__ */
Index: code/trunk/src/libraries/core/input/JoyStickQuantityListener.cc
===================================================================
--- code/trunk/src/libraries/core/input/JoyStickQuantityListener.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/JoyStickQuantityListener.cc	(revision 5781)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "JoyStickQuantityListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ObjectList.h"
+
+namespace orxonox
+{
+    std::vector<JoyStick*> JoyStickQuantityListener::joyStickList_s;
+
+    JoyStickQuantityListener::JoyStickQuantityListener()
+    {
+        RegisterObject(JoyStickQuantityListener);
+    }
+
+    //! Calls all registered objects and sets the static variable
+    /*static*/ void JoyStickQuantityListener::changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList)
+    {
+        joyStickList_s = joyStickList;
+        for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it)
+            it->JoyStickQuantityChanged(joyStickList);
+    }
+}
Index: code/trunk/src/libraries/core/input/JoyStickQuantityListener.h
===================================================================
--- code/trunk/src/libraries/core/input/JoyStickQuantityListener.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/JoyStickQuantityListener.h	(revision 5781)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief 
+*/
+
+#ifndef _JoyStickQuantityListener_H__
+#define _JoyStickQuantityListener_H__
+
+#include "InputPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    //! Derive from this class to get informed when joy sticks get added/removed
+    class _CoreExport JoyStickQuantityListener : virtual public OrxonoxClass
+    {
+        friend class InputManager;
+    protected:
+        JoyStickQuantityListener();
+        virtual ~JoyStickQuantityListener() { }
+
+        //! Returns a list with all JoySticks currently loaded
+        const std::vector<JoyStick*>& getJoyStickList() const { return joyStickList_s; }
+
+    private:
+        //! Called whenever joy sticks get added/removed
+        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) = 0;
+
+        static void changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList);
+
+        //! Static variable that holds the latest distributed information
+        static std::vector<JoyStick*> joyStickList_s;
+    };
+}
+
+#endif /* _JoyStickQuantityListener_H__ */
Index: code/trunk/src/libraries/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/libraries/core/input/KeyBinder.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/KeyBinder.cc	(revision 5781)
@@ -0,0 +1,511 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+ @file
+ @brief Implementation of the different input handlers.
+ */
+
+#include "KeyBinder.h"
+
+#include "util/Convert.h"
+#include "util/Debug.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigFileManager.h"
+#include "InputCommands.h"
+#include "JoyStick.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor that does as little as necessary.
+    */
+    KeyBinder::KeyBinder()
+        : deriveTime_(0.0f)
+    {
+        mouseRelative_[0] = 0;
+        mouseRelative_[1] = 0;
+        mousePosition_[0] = 0;
+        mousePosition_[1] = 0;
+
+        RegisterRootObject(KeyBinder);
+
+        // intialise all buttons and half axes to avoid creating everything with 'new'
+        // keys
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+        {
+            std::string keyname = KeyCode::ByString[i];
+            if (!keyname.empty())
+                keys_[i].name_ = std::string("Key") + keyname;
+            else
+                keys_[i].name_ = "";
+            keys_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            keys_[i].groupName_ = "Keys";
+        }
+        // mouse buttons plus 4 mouse wheel buttons only 'generated' by KeyBinder
+        const char* const mouseWheelNames[] = { "Wheel1Down", "Wheel1Up", "Wheel2Down", "Wheel2Up" };
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+        {
+            std::string nameSuffix;
+            if (i < MouseButtonCode::numberOfButtons)
+                nameSuffix = MouseButtonCode::ByString[i];
+            else
+                nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons];
+            mouseButtons_[i].name_ = nameSuffix;
+            mouseButtons_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseButtons_[i].groupName_ = "MouseButtons";
+        }
+        // mouse axes
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            mouseAxes_[i].name_ = MouseAxisCode::ByString[i / 2];
+            if (i & 1)
+                mouseAxes_[i].name_ += "Pos";
+            else
+                mouseAxes_[i].name_ += "Neg";
+            mouseAxes_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseAxes_[i].groupName_ = "MouseAxes";
+        }
+
+        // We might not even load any bindings at all (KeyDetector for instance)
+        this->configFile_ = ConfigFileType::NoType;
+
+        // initialise joy sticks separatly to allow for reloading
+        this->JoyStickQuantityChanged(this->getJoyStickList());
+
+        // set them here to use allHalfAxes_
+        setConfigValues();
+    }
+
+    /**
+    @brief
+        Destructor
+    */
+    KeyBinder::~KeyBinder()
+    {
+        // almost no destructors required because most of the arrays are static.
+        clearBindings(); // does some destruction work
+    }
+
+    /**
+    @brief
+        Loader for the key bindings, managed by config values.
+    */
+    void KeyBinder::setConfigValues()
+    {
+        SetConfigValue(analogThreshold_, 0.05f)
+            .description("Threshold for analog axes until which the state is 0.");
+        SetConfigValue(bFilterAnalogNoise_, false)
+            .description("Specifies whether to filter small analog values like joy stick fluctuations.");
+        SetConfigValue(mouseSensitivity_, 1.0f)
+            .description("Mouse sensitivity.");
+        SetConfigValue(bDeriveMouseInput_, false)
+            .description("Whether or not to derive moues movement for the absolute value.");
+        SetConfigValue(derivePeriod_, 0.05f)
+            .description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
+        SetConfigValue(mouseSensitivityDerived_, 1.0f)
+            .description("Mouse sensitivity if mouse input is derived.");
+        SetConfigValue(mouseWheelStepSize_, 120)
+            .description("Equals one step of the mousewheel.");
+        SetConfigValue(buttonThreshold_, 0.80f)
+            .description("Threshold for analog axes until which the button is not pressed.")
+            .callback(this, &KeyBinder::buttonThresholdChanged);
+    }
+
+    void KeyBinder::buttonThresholdChanged()
+    {
+        for (unsigned int i = 0; i < allHalfAxes_.size(); i++)
+            if (!allHalfAxes_[i]->bButtonThresholdUser_)
+                allHalfAxes_[i]->buttonThreshold_ = this->buttonThreshold_;
+    }
+
+    void KeyBinder::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        unsigned int oldValue = joySticks_.size();
+        joySticks_ = joyStickList;
+
+        // initialise joy stick bindings
+        initialiseJoyStickBindings();
+
+        // collect all Buttons and HalfAxes again
+        compilePointerLists();
+
+        // load the bindings if required
+        if (configFile_ != ConfigFileType::NoType)
+        {
+            for (unsigned int iDev = oldValue; iDev < joySticks_.size(); ++iDev)
+            {
+                for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
+                    (*joyStickButtons_[iDev])[i].readConfigValue(this->configFile_);
+                for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
+                    (*joyStickAxes_[iDev])[i].readConfigValue(this->configFile_);
+            }
+        }
+
+        // Set the button threshold for potential new axes
+        buttonThresholdChanged();
+    }
+
+    void KeyBinder::initialiseJoyStickBindings()
+    {
+        while (joyStickAxes_.size() < joySticks_.size())
+            joyStickAxes_.push_back(shared_ptr<JoyStickAxisVector>(new JoyStickAxisVector()));
+        while (joyStickButtons_.size() < joySticks_.size())
+            joyStickButtons_.push_back(shared_ptr<JoyStickButtonVector>(new JoyStickButtonVector()));
+        // For the case the new size is smaller
+        this->joyStickAxes_.resize(joySticks_.size());
+        this->joyStickButtons_.resize(joySticks_.size());
+
+        // reinitialise all joy stick binings (doesn't overwrite the old ones)
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
+        {
+            std::string deviceName = joySticks_[iDev]->getDeviceName();
+            // joy stick buttons
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+            {
+                (*joyStickButtons_[iDev])[i].name_ = JoyStickButtonCode::ByString[i];
+                (*joyStickButtons_[iDev])[i].paramCommandBuffer_ = &paramCommandBuffer_;
+                (*joyStickButtons_[iDev])[i].groupName_ = "JoyStickButtons_" + deviceName;
+            }
+            // joy stick axes
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                (*joyStickAxes_[iDev])[i].name_ = JoyStickAxisCode::ByString[i / 2];
+                if (i & 1)
+                    (*joyStickAxes_[iDev])[i].name_ += "Pos";
+                else
+                    (*joyStickAxes_[iDev])[i].name_ += "Neg";
+                (*joyStickAxes_[iDev])[i].paramCommandBuffer_ = &paramCommandBuffer_;
+                (*joyStickAxes_[iDev])[i].groupName_ = "JoyStickAxes_" + deviceName;
+            }
+        }
+    }
+
+    void KeyBinder::compilePointerLists()
+    {
+        allButtons_.clear();
+        allHalfAxes_.clear();
+
+        // Note: Don't include the dummy keys which don't actually exist in OIS but have a number
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+            if (!keys_[i].name_.empty())
+                allButtons_[keys_[i].groupName_ + "." + keys_[i].name_] = keys_ + i;
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+            allButtons_[mouseButtons_[i].groupName_ + "." + mouseButtons_[i].name_] = mouseButtons_ + i;
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            allButtons_[mouseAxes_[i].groupName_ + "." + mouseAxes_[i].name_] = mouseAxes_ + i;
+            allHalfAxes_.push_back(mouseAxes_ + i);
+        }
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
+        {
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+                allButtons_[(*joyStickButtons_[iDev])[i].groupName_ + "." + (*joyStickButtons_[iDev])[i].name_] = &((*joyStickButtons_[iDev])[i]);
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                allButtons_[(*joyStickAxes_[iDev])[i].groupName_ + "." + (*joyStickAxes_[iDev])[i].name_] = &((*joyStickAxes_[iDev])[i]);
+                allHalfAxes_.push_back(&((*joyStickAxes_[iDev])[i]));
+            }
+        }
+    }
+
+    /**
+    @brief
+        Loads the key and button bindings.
+    @return
+        True if loading succeeded.
+    */
+    void KeyBinder::loadBindings(const std::string& filename)
+    {
+        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
+
+        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);
+
+        // Parse bindings and create the ConfigValueContainers if necessary
+        clearBindings();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->readConfigValue(this->configFile_);
+
+        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
+    }
+
+    bool KeyBinder::setBinding(const std::string& binding, const std::string& name, bool bTemporary)
+    {
+        std::map<std::string, Button*>::iterator it = allButtons_.find(name);
+        if (it != allButtons_.end())
+        {
+            if (bTemporary)
+                it->second->configContainer_->tset(binding);
+            else
+                it->second->configContainer_->set(binding);
+            it->second->configContainer_->getValue(&(it->second->bindingString_), it->second);
+            return true;
+        }
+        else
+        {
+            COUT(2) << "Could not find key/button/axis with name '" << name << "'." << std::endl;
+            return false;
+        }
+    }
+
+    /**
+    @brief
+        Overwrites all bindings with ""
+    */
+    void KeyBinder::clearBindings()
+    {
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->clear();
+
+        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
+            delete paramCommandBuffer_[i];
+        paramCommandBuffer_.clear();
+    }
+
+    void KeyBinder::resetJoyStickAxes()
+    {
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); ++iDev)
+        {
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                (*joyStickAxes_[iDev])[i].absVal_ = 0.0f;
+                (*joyStickAxes_[iDev])[i].relVal_ = 0.0f;
+            }
+        }
+    }
+
+    void KeyBinder::mouseUpdated(float dt)
+    {
+        if (bDeriveMouseInput_)
+        {
+            // only update when derivation dt has passed
+            if (deriveTime_ > derivePeriod_)
+            {
+                for (int i = 0; i < 2; i++)
+                {
+                    if (mouseRelative_[i] < 0)
+                    {
+                        mouseAxes_[2*i + 0].absVal_
+                            = -mouseRelative_[i] / deriveTime_ * 0.0005f * mouseSensitivityDerived_;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
+                    }
+                    else if (mouseRelative_[i] > 0)
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_
+                            =  mouseRelative_[i] / deriveTime_ * 0.0005f * mouseSensitivityDerived_;
+                    }
+                    else
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
+                    }
+                    mouseRelative_[i] = 0;
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
+                }
+                deriveTime_ = 0.0f;
+            }
+            else
+                deriveTime_ += dt;
+        }
+
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            // Why dividing relative value by dt? The reason lies in the simple fact, that when you
+            // press a button that has relative movement, that value has to be multiplied by dt to be
+            // frame rate independent. This can easily (and only) be done in updateInput(float).
+            // Hence we need to divide by dt here for the mouse to compensate, because the relative
+            // move movements have nothing to do with dt.
+            if (dt != 0.0f)
+            {
+                // just ignore if dt == 0.0 because we have multiplied by 0.0 anyway..
+                mouseAxes_[i].relVal_ /= dt;
+            }
+
+            tickHalfAxis(mouseAxes_[i]);
+        }
+    }
+
+    void KeyBinder::joyStickUpdated(unsigned int joyStick, float dt)
+    {
+        for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+        {
+            tickHalfAxis((*joyStickAxes_[joyStick])[i]);
+        }
+    }
+
+    void KeyBinder::tickHalfAxis(HalfAxis& halfAxis)
+    {
+        // button mode
+        // TODO: optimize out all the half axes that don't act as a button at the moment
+        if (halfAxis.hasChanged_)
+        {
+            if (!halfAxis.pressed_ && halfAxis.absVal_ > halfAxis.buttonThreshold_)
+            {
+                // key pressed event
+                halfAxis.pressed_ = true;
+                if (halfAxis.nCommands_[KeybindMode::OnPress])
+                    halfAxis.execute(KeybindMode::OnPress);
+            }
+            else if (halfAxis.pressed_ && halfAxis.absVal_ < halfAxis.buttonThreshold_)
+            {
+                // key released event
+                halfAxis.pressed_ = false;
+                if (halfAxis.nCommands_[KeybindMode::OnRelease])
+                    halfAxis.execute(KeybindMode::OnRelease);
+            }
+            halfAxis.hasChanged_ = false;
+        }
+
+        if (halfAxis.pressed_)
+        {
+            // key held event
+            if (halfAxis.nCommands_[KeybindMode::OnHold])
+                halfAxis.execute(KeybindMode::OnHold);
+        }
+
+        // these are the actually useful axis bindings for analog input
+        if (!bFilterAnalogNoise_ || halfAxis.relVal_ > analogThreshold_ || halfAxis.absVal_ > analogThreshold_)
+        {
+            halfAxis.execute();
+        }
+    }
+
+    /**
+    @brief
+        Event handler for the mouseMoved Event.
+    @param e
+        Mouse state information
+    */
+    void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
+    {
+        // y axis of mouse input is inverted
+        int rel[] = { rel_.x, -rel_.y };
+
+        if (bDeriveMouseInput_)
+        {
+            mouseRelative_[0] += rel[0];
+            mouseRelative_[1] += rel[1];
+        }
+        else
+        {
+            for (int i = 0; i < 2; i++)
+            {
+                if (rel[i]) // performance opt. for the case that rel[i] == 0
+                {
+                    // write absolute values
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
+                    mousePosition_[i] += rel[i];
+
+                    // clip absolute position
+                    if (mousePosition_[i] > mouseClippingSize_)
+                        mousePosition_[i] =  mouseClippingSize_;
+                    if (mousePosition_[i] < -mouseClippingSize_)
+                        mousePosition_[i] = -mouseClippingSize_;
+
+                    if (mousePosition_[i] < 0)
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = -mouseSensitivity_ * mousePosition_[i] / mouseClippingSize_;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
+                    }
+                    else
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ =  mouseSensitivity_ * mousePosition_[i] / mouseClippingSize_;
+                    }
+                }
+            }
+        }
+
+        // relative
+        for (int i = 0; i < 2; i++)
+        {
+            if (rel[i] < 0)
+                mouseAxes_[0 + 2*i].relVal_ = -mouseSensitivity_ * rel[i] / mouseClippingSize_;
+            else
+                mouseAxes_[1 + 2*i].relVal_ =  mouseSensitivity_ * rel[i] / mouseClippingSize_;
+        }
+    }
+
+    /**
+    @brief Event handler for the mouseScrolled Event.
+    @param e Mouse state information
+    */
+    void KeyBinder::mouseScrolled(int abs, int rel)
+    {
+        if (rel < 0)
+            for (int i = 0; i < -rel/mouseWheelStepSize_; i++)
+                mouseButtons_[8].execute(KeybindMode::OnPress, static_cast<float>(abs)/mouseWheelStepSize_);
+        else
+            for (int i = 0; i < rel/mouseWheelStepSize_; i++)
+                mouseButtons_[9].execute(KeybindMode::OnPress, static_cast<float>(abs)/mouseWheelStepSize_);
+    }
+
+    void KeyBinder::axisMoved(unsigned int device, unsigned int axisID, float value)
+    {
+        int i = axisID * 2;
+        JoyStickAxisVector& axis = *joyStickAxes_[device];
+        if (value < 0)
+        {
+            axis[i].absVal_ = -value;
+            axis[i].relVal_ = -value;
+            axis[i].hasChanged_ = true;
+            if (axis[i + 1].absVal_ > 0.0f)
+            {
+                axis[i + 1].absVal_ = -0.0f;
+                axis[i + 1].relVal_ = -0.0f;
+                axis[i + 1].hasChanged_ = true;
+            }
+        }
+        else
+        {
+            axis[i + 1].absVal_ = value;
+            axis[i + 1].relVal_ = value;
+            axis[i + 1].hasChanged_ = true;
+            if (axis[i].absVal_ > 0.0f)
+            {
+                axis[i].absVal_ = -0.0f;
+                axis[i].relVal_ = -0.0f;
+                axis[i].hasChanged_ = true;
+            }
+        }
+    }
+}
Index: code/trunk/src/libraries/core/input/KeyBinder.h
===================================================================
--- code/trunk/src/libraries/core/input/KeyBinder.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/KeyBinder.h	(revision 5781)
@@ -0,0 +1,217 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _KeyBinder_H__
+#define _KeyBinder_H__
+
+#include "InputPrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include "InputHandler.h"
+#include "Button.h"
+#include "HalfAxis.h"
+#include "InputCommands.h"
+#include "JoyStickQuantityListener.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Handles mouse, keyboard and joy stick input while in the actual game mode.
+        Manages the key bindings.
+    */
+    class _CoreExport KeyBinder : public InputHandler, public JoyStickQuantityListener
+    {
+    public:
+        KeyBinder ();
+        virtual ~KeyBinder();
+
+        void loadBindings(const std::string& filename);
+        void clearBindings();
+        bool setBinding(const std::string& binding, const std::string& name, bool bTemporary = false);
+        void setConfigValues();
+        void resetJoyStickAxes();
+
+    protected: // functions
+        void allDevicesUpdated(float dt);
+        void mouseUpdated(float dt);
+        void joyStickUpdated(unsigned int joyStick, float dt);
+        // internal
+        void tickHalfAxis(HalfAxis& halfAxis);
+
+        void buttonThresholdChanged();
+        // from JoyStickQuantityListener interface
+        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+        void initialiseJoyStickBindings();
+        void compilePointerLists();
+
+        void buttonPressed (const KeyEvent& evt);
+        void buttonReleased(const KeyEvent& evt);
+        void buttonHeld    (const KeyEvent& evt);
+
+        void buttonPressed (MouseButtonCode::ByEnum button);
+        void buttonReleased(MouseButtonCode::ByEnum button);
+        void buttonHeld    (MouseButtonCode::ByEnum button);
+        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled (int abs, int rel);
+
+        void buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button);
+        void buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button);
+        void buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button);
+        void axisMoved     (unsigned int device, unsigned int axis, float value);
+
+    protected: // variables
+        //! Currently active joy sticks
+        std::vector<JoyStick*>  joySticks_;
+
+        //! Actual key bindings for keys on the keyboard
+        Button keys_            [KeyCode::numberOfKeys];
+        //! Number of mouse buttons in KeyBinder (+4)
+        static const unsigned int numberOfMouseButtons_ = MouseButtonCode::numberOfButtons + 4;
+        //! Actual key bindings for mouse buttons including the wheel(s)
+        Button mouseButtons_    [numberOfMouseButtons_];
+        //! Actual key bindings for mouse axes
+        HalfAxis mouseAxes_     [MouseAxisCode::numberOfAxes * 2];
+
+        //! Helper class to use something like std:vector<Button[64]>
+        struct JoyStickButtonVector
+        {
+            Button& operator[](unsigned int index) { return buttons[index]; }
+            Button buttons[JoyStickButtonCode::numberOfButtons];
+        };
+        //! Actual key bindings for joy stick buttons
+        std::vector<shared_ptr<JoyStickButtonVector> > joyStickButtons_;
+        //! Helper class to use something like std:vector<HalfAxis[48]>
+        struct JoyStickAxisVector
+        {
+            HalfAxis& operator[](unsigned int index) { return halfAxes[index]; }
+            HalfAxis halfAxes[JoyStickAxisCode::numberOfAxes * 2];
+        };
+        //! Actual key bindings for joy stick axes (and sliders)
+        std::vector<shared_ptr<JoyStickAxisVector> > joyStickAxes_;
+
+        //! Pointer map with all Buttons, including half axes
+        std::map<std::string, Button*> allButtons_;
+        //! Pointer list with all half axes
+        std::vector<HalfAxis*> allHalfAxes_;
+
+        /**
+        @brief
+            Commands that have additional parameters (axes) are executed at the end of
+            update() so that all values can be buffered for single execution.
+        */
+        std::vector<BufferedParamCommand*> paramCommandBuffer_;
+
+        //! Keeps track of the absolute mouse value (incl. scroll wheel)
+        int mousePosition_[2];
+        //! Used to derive mouse input if requested
+        int mouseRelative_[2];
+        float deriveTime_;
+
+        //! Config file used. ConfigFileType::NoType in case of KeyDetector. Also indicates whether we've already loaded.
+        ConfigFileType configFile_;
+
+    private:
+        //##### ConfigValues #####
+        //! Whether to filter small value analog input
+        bool bFilterAnalogNoise_;
+        //! Threshold for analog triggers until which the state is 0.
+        float analogThreshold_;
+        //! Threshold for analog triggers until which the button is not pressed.
+        float buttonThreshold_;
+        //! Derive mouse input for absolute values?
+        bool bDeriveMouseInput_;
+        //! Accuracy of the mouse input deriver. The higher the more precise, but laggier.
+        float derivePeriod_;
+        //! mouse sensitivity
+        float mouseSensitivity_;
+        //! mouse sensitivity if mouse input is derived
+        float mouseSensitivityDerived_;
+        //! Equals one step of the mousewheel
+        int mouseWheelStepSize_;
+
+        //##### Constant config variables #####
+        // Use some value at about 1000. This can be configured with mouseSensitivity_ anyway.
+        static const int mouseClippingSize_ = 1024;
+    };
+
+    inline void KeyBinder::buttonPressed (const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::buttonPressed (MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button)
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button)
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button)
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnHold); }
+
+    inline void KeyBinder::allDevicesUpdated(float dt)
+    {
+        // execute all buffered bindings (additional parameter)
+        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
+        {
+            paramCommandBuffer_[i]->rel_ *= dt;
+            paramCommandBuffer_[i]->execute();
+        }
+
+        // always reset the relative movement of the mouse
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+            mouseAxes_[i].relVal_ = 0.0f;
+    }
+}
+
+#endif /* _KeyBinder_H__ */
Index: code/trunk/src/libraries/core/input/KeyDetector.cc
===================================================================
--- code/trunk/src/libraries/core/input/KeyDetector.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/KeyDetector.cc	(revision 5781)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "KeyDetector.h"
+
+#include "util/Debug.h"
+#include "core/CoreIncludes.h"
+#include "Button.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor
+    */
+    KeyDetector::KeyDetector()
+    {
+        RegisterObject(KeyDetector);
+    }
+
+    /**
+    @brief
+        Destructor
+    */
+    KeyDetector::~KeyDetector()
+    {
+    }
+
+    /**
+    @brief
+        Assigns all the buttons 'command' plus the button's name.
+    */
+    void KeyDetector::setCallbackCommand(const std::string& command)
+    {
+        callbackCommand_ = command;
+        clearBindings();
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+        {
+            it->second->bindingString_ = callbackCommand_ + it->second->groupName_ + "." + it->second->name_;
+            it->second->parse();
+        }
+    }
+
+    void KeyDetector::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        KeyBinder::JoyStickQuantityChanged(joyStickList);
+        if (!callbackCommand_.empty())
+            setCallbackCommand(callbackCommand_);
+    }
+}
Index: code/trunk/src/libraries/core/input/KeyDetector.h
===================================================================
--- code/trunk/src/libraries/core/input/KeyDetector.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/KeyDetector.h	(revision 5781)
@@ -0,0 +1,52 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _KeyDetector_H__
+#define _KeyDetector_H__
+
+#include "InputPrereqs.h"
+
+#include <string>
+#include "KeyBinder.h"
+
+namespace orxonox
+{
+    class _CoreExport KeyDetector : public KeyBinder
+    {
+    public:
+        KeyDetector();
+        ~KeyDetector();
+        void setCallbackCommand(const std::string& command);
+        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+
+    private:
+        std::string callbackCommand_;
+    };
+}
+
+#endif /* _KeyDetector_H__ */
Index: code/trunk/src/libraries/core/input/Keyboard.cc
===================================================================
--- code/trunk/src/libraries/core/input/Keyboard.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/Keyboard.cc	(revision 5781)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Keyboard.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    //! OIS event handler
+    bool Keyboard::keyPressed(const OIS::KeyEvent& arg)
+    {
+        // update modifiers
+        if(arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
+            modifiers_ |= KeyboardModifier::Alt;   // alt key
+        if(arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
+            modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
+        if(arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
+            modifiers_ |= KeyboardModifier::Shift; // shift key
+
+        KeyEvent evt(arg);
+        super::buttonPressed(evt);
+        return true;
+    }
+
+    //! OIS event handler
+    bool Keyboard::keyReleased(const OIS::KeyEvent& arg)
+    {
+        // update modifiers
+        if(arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
+            modifiers_ &= ~KeyboardModifier::Alt;   // alt key
+        if(arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
+            modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
+        if(arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
+            modifiers_ &= ~KeyboardModifier::Shift; // shift key
+
+        KeyEvent evt(arg);
+        super::buttonReleased(evt);
+        return true;
+    }
+}
Index: code/trunk/src/libraries/core/input/Keyboard.h
===================================================================
--- code/trunk/src/libraries/core/input/Keyboard.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/Keyboard.h	(revision 5781)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Keyboard_H__
+#define _Core_Keyboard_H__
+
+#include "InputPrereqs.h"
+
+#include "InputHandler.h"
+#include "InputDevice.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct KeyboardTraits
+    {
+        typedef Keyboard DeviceClass;
+        typedef OIS::Keyboard OISDeviceClass;
+        typedef KeyEvent ButtonType;
+        typedef KeyEvent& ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISKeyboard;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::Mouse and forwards the input events to
+        a list of input states.
+
+        It also saves the state of the keyboard modifiers (like shift, etc.)
+    */
+    class _CoreExport Keyboard
+        : public InputDeviceTemplated<KeyboardTraits>
+        , public OIS::KeyListener
+    {
+        friend class InputDeviceTemplated<KeyboardTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<KeyboardTraits> super;
+
+    public:
+        //! Only resets the keyboard modifiers. Initialising is done in the base class.
+        Keyboard(unsigned int id, OIS::InputManager* oisInputManager) : super(id, oisInputManager), modifiers_(0) { }
+        ~Keyboard() { }
+
+    private:
+        //! Resets the keyboard modifiers
+        void clearBuffersImpl() { this->modifiers_ = 0; }
+        //! Translates the KeyHandle to a KeyEvent
+        KeyEvent& getButtonEventArg(KeyEvent& button)
+        {
+            button.setModifiers(modifiers_);
+            return button;
+        }
+
+        bool keyPressed(const OIS::KeyEvent& arg);
+        bool keyReleased(const OIS::KeyEvent& arg);
+
+        //! Returns the class name as string
+        static std::string getClassNameImpl() { return "Keyboard"; }
+
+        //! Bit mask representing keyboard modifiers
+        int modifiers_;
+    };
+}
+
+#endif /* _Core_Keyboard_H__ */
Index: code/trunk/src/libraries/core/input/Mouse.cc
===================================================================
--- code/trunk/src/libraries/core/input/Mouse.cc	(revision 5781)
+++ code/trunk/src/libraries/core/input/Mouse.cc	(revision 5781)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Mouse.h"
+
+#include <ois/OISMouse.h>
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "InputState.h"
+
+#ifdef ORXONOX_PLATFORM_LINUX
+// include this as last, X11 seems to define some macros...
+#include <ois/linux/LinuxMouse.h>
+#endif
+
+namespace orxonox
+{
+    Mouse::Mouse(unsigned int id, OIS::InputManager* oisInputManager)
+        : super(id, oisInputManager)
+    {
+        RegisterRootObject(Mouse);
+        this->windowResized(this->getWindowWidth(), this->getWindowHeight());
+
+#ifdef ORXONOX_PLATFORM_LINUX
+        {
+            // Mouse grab console command
+            FunctorMember<Mouse>* functor = createFunctor(&Mouse::grab);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "grab"), false);
+        }
+        {
+            // Mouse ungrab console command
+            FunctorMember<Mouse>* functor = createFunctor(&Mouse::ungrab);
+            functor->setObject(this);
+            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "ungrab"), false);
+        }
+#endif
+    }
+
+    //! OIS event handler
+    bool Mouse::mouseMoved(const OIS::MouseEvent &e)
+    {
+        // check for actual moved event
+        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
+        {
+            IntVector2 abs(e.state.X.abs, e.state.Y.abs);
+            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
+            IntVector2 clippingSize(e.state.width, e.state.height);
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->mouseMoved(abs, rel, clippingSize);
+        }
+
+        // check for mouse scrolled event
+        if (e.state.Z.rel != 0)
+        {
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+        }
+
+        return true;
+    }
+
+    void Mouse::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        oisDevice_->getMouseState().width  = newWidth;
+        oisDevice_->getMouseState().height = newHeight;
+    }
+
+#ifdef ORXONOX_PLATFORM_LINUX
+    void Mouse::grab()
+    {
+        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
+        assert(linuxMouse);
+        linuxMouse->grab(true);
+    }
+
+    void Mouse::ungrab()
+    {
+        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
+        assert(linuxMouse);
+        linuxMouse->grab(false);
+    }
+#endif
+}
Index: code/trunk/src/libraries/core/input/Mouse.h
===================================================================
--- code/trunk/src/libraries/core/input/Mouse.h	(revision 5781)
+++ code/trunk/src/libraries/core/input/Mouse.h	(revision 5781)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Mouse_H__
+#define _Core_Mouse_H__
+
+#include "InputPrereqs.h"
+
+#include "InputDevice.h"
+#include "core/WindowEventListener.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct MouseTraits
+    {
+        typedef Mouse DeviceClass;
+        typedef OIS::Mouse OISDeviceClass;
+        typedef MouseButtonCode::ByEnum ButtonType;
+        typedef MouseButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISMouse;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::Mouse and forwards the input events to
+        a list of input states.
+    */
+    class _CoreExport Mouse
+        : public InputDeviceTemplated<MouseTraits>
+        , public OIS::MouseListener
+        , public WindowEventListener
+    {
+        friend class InputDeviceTemplated<MouseTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<MouseTraits> super;
+
+    public:
+        //! Only sets the clipping size. Initialising is done in the base class.
+        Mouse(unsigned int id, OIS::InputManager* oisInputManager);
+        ~Mouse() { }
+
+#ifdef ORXONOX_PLATFORM_LINUX
+        // TODO: Make this a feature rather than a hack
+        void grab();
+        void ungrab();
+#endif
+
+    private:
+        //! OIS event handler
+        bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
+        {
+            super::buttonPressed(static_cast<MouseButtonCode::ByEnum>(id));
+            return true;
+        }
+
+        //! OIS event handler
+        bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
+        {
+            super::buttonReleased(static_cast<MouseButtonCode::ByEnum>(id));
+            return true;
+        }
+
+        bool mouseMoved(const OIS::MouseEvent &arg);
+
+        void windowResized(unsigned int newWidth, unsigned int newHeight);
+
+        // Returns the class name as string
+        static std::string getClassNameImpl() { return "Mouse"; }
+    };
+}
+
+#endif /* _Core_Mouse_H__ */
Index: code/trunk/src/libraries/network/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/network/CMakeLists.txt	(revision 5781)
+++ code/trunk/src/libraries/network/CMakeLists.txt	(revision 5781)
@@ -0,0 +1,74 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        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.
+ #
+
+SET_SOURCE_FILES(NETWORK_SRC_FILES
+  ChatListener.cc
+  Client.cc
+  ClientConnection.cc
+  ClientInformation.cc
+  ClientConnectionListener.cc
+  Connection.cc
+  FunctionCallManager.cc
+  GamestateManager.cc
+  GamestateClient.cc
+  GamestateHandler.cc
+  NetworkFunction.cc
+  Host.cc
+  Server.cc
+  ServerConnection.cc
+  TrafficControl.cc
+)
+
+SET_SOURCE_FILES(NETWORK_HDR_FILES
+  ChatListener.h
+  Client.h
+  ClientConnection.h
+  ClientConnectionListener.h
+  ClientInformation.h
+  Connection.h
+  FunctionCallManager.h
+  GamestateClient.h
+  GamestateHandler.h
+  GamestateManager.h
+  Host.h
+  NetworkFunction.h
+  NetworkPrecompiledHeaders.h
+  NetworkPrereqs.h
+  Server.h
+  ServerConnection.h
+  TrafficControl.h
+)
+
+ADD_SUBDIRECTORY(packet)
+ADD_SUBDIRECTORY(synchronisable)
+
+ORXONOX_ADD_LIBRARY(network
+  DEFINE_SYMBOL
+    "NETWORK_SHARED_BUILD"
+  PCH_FILE
+    NetworkPrecompiledHeaders.h
+  LINK_LIBRARIES
+    ${ZLIB_LIBRARY}
+    ${ENET_LIBRARY}
+    ${Boost_THREAD_LIBRARY}
+    util
+    core
+  SOURCE_FILES
+    ${NETWORK_SRC_FILES} ${NETWORK_HDR_FILES}
+)
Index: code/trunk/src/libraries/network/ChatListener.cc
===================================================================
--- code/trunk/src/libraries/network/ChatListener.cc	(revision 5781)
+++ code/trunk/src/libraries/network/ChatListener.cc	(revision 5781)
@@ -0,0 +1,40 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatListener.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    ChatListener::ChatListener()
+    {
+        RegisterRootObject(ChatListener);
+    }
+}
+
+
Index: code/trunk/src/libraries/network/ChatListener.h
===================================================================
--- code/trunk/src/libraries/network/ChatListener.h	(revision 5781)
+++ code/trunk/src/libraries/network/ChatListener.h	(revision 5781)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_ChatListener__
+#define _NETWORK_ChatListener__
+
+#include "NetworkPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _NetworkExport ChatListener : virtual public OrxonoxClass
+    {
+        public:
+            ChatListener();
+            virtual ~ChatListener() {}
+
+            virtual void incomingChat(const std::string& message, unsigned int senderID) = 0;
+    };
+}
+
+#endif /* _NETWORK_ChatListener__ */
Index: code/trunk/src/libraries/network/Client.cc
===================================================================
--- code/trunk/src/libraries/network/Client.cc	(revision 5781)
+++ code/trunk/src/libraries/network/Client.cc	(revision 5781)
@@ -0,0 +1,161 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: Client
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "Client.h"
+
+#include <cassert>
+
+#include "util/Debug.h"
+#include "core/Clock.h"
+#include "synchronisable/Synchronisable.h"
+#include "packet/Chat.h"
+#include "packet/Gamestate.h"
+#include "FunctionCallManager.h"
+
+namespace orxonox
+{
+
+
+  /**
+  * Constructor for the Client class
+  * initializes the address and the port to default localhost:NETWORK_PORT
+  */
+  Client::Client():
+      isSynched_(false),
+      gameStateFailure_(false)
+  {
+  }
+
+  /**
+  * Constructor for the Client class
+  * @param address the server address
+  * @param port port of the application on the server
+  */
+  Client::Client(const std::string& address, int port):
+      isSynched_(false),
+      gameStateFailure_(false)
+  {
+      setPort( port );
+      setServerAddress( address );
+  }
+
+  Client::~Client(){
+    if ( ClientConnection::isConnected() )
+      closeConnection();
+  }
+
+  /**
+  * Establish the Connection to the Server
+  * @return true/false
+  */
+  bool Client::establishConnection(){
+    Synchronisable::setClient(true);
+    return ClientConnection::establishConnection();
+  }
+
+  /**
+  * closes the Connection to the Server
+  * @return true/false
+  */
+  bool Client::closeConnection(){
+    return ClientConnection::closeConnection();
+  }
+
+  bool Client::queuePacket(ENetPacket *packet, int clientID){
+    bool b = ClientConnection::addPacket(packet);
+    assert(b);
+    return b;
+  }
+
+  bool Client::processChat(const std::string& message, unsigned int playerID){
+//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
+    return true;
+  }
+
+  /**
+   * This function implements the method of sending a chat message to the server
+   * @param message message to be sent
+   * @return result(true/false)
+   */
+  bool Client::chat(const std::string& message){
+    packet::Chat *m = new packet::Chat(message, Host::getPlayerID());
+    return m->send();
+  }
+
+
+  /**
+   * Processes incoming packets, sends a gamestate to the server and does the cleanup
+   * @param time
+   */
+  void Client::update(const Clock& time){
+    //this steers our network frequency
+    timeSinceLastUpdate_+=time.getDeltaTime();
+    if(timeSinceLastUpdate_>=NETWORK_PERIOD)
+    {
+      timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
+      //     COUT(3) << ".";
+      if ( isConnected() && isSynched_ )
+      {
+        COUT(4) << "popping partial gamestate: " << std::endl;
+        packet::Gamestate *gs = gamestate.getGamestate();
+        //assert(gs); <--- there might be the case that no data has to be sent, so its commented out now
+        if(gs){
+          COUT(4) << "client tick: sending gs " << gs << std::endl;
+          if( !gs->send() )
+            COUT(3) << "Problem adding partial gamestate to queue" << std::endl;
+        // gs gets automatically deleted by enet callback
+        }
+        FunctionCallManager::sendCalls();
+      }
+    }
+    sendPackets(); // flush the enet queue
+    
+    Connection::processQueue();
+    if(gamestate.processGamestates())
+    {
+      if(!isSynched_)
+        isSynched_=true;
+    }
+    gamestate.cleanup();
+
+    return;
+  }
+
+}
Index: code/trunk/src/libraries/network/Client.h
===================================================================
--- code/trunk/src/libraries/network/Client.h	(revision 5781)
+++ code/trunk/src/libraries/network/Client.h	(revision 5781)
@@ -0,0 +1,89 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: Client
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef _Client_H__
+#define _Client_H__
+
+#include "NetworkPrereqs.h"
+
+#include <string>
+#include "ClientConnection.h"
+#include "GamestateClient.h"
+#include "Host.h"
+
+namespace orxonox
+{
+  /**
+  Client *client;
+  * The network/Client class
+  * This class implements all necessary function for the network communication
+  * It is the root class of the network module
+  *
+  */
+  class _NetworkExport Client : public Host, public ClientConnection{
+  public:
+    Client();
+    Client(const std::string& address, int port);
+    ~Client();
+
+    bool establishConnection();
+    bool closeConnection();
+    bool queuePacket(ENetPacket *packet, int clientID);
+    bool processChat(const std::string& message, unsigned int playerID);
+    virtual bool chat(const std::string& message);
+    virtual bool broadcast(const std::string& message) { return false; }
+
+    void update(const Clock& time);
+
+  private:
+    Client(const Client& copy); // not used
+    virtual bool isServer_(){return false;}
+
+    GamestateClient gamestate;
+    bool isSynched_;
+
+    bool gameStateFailure_;
+    float timeSinceLastUpdate_;
+  };
+
+
+}
+
+#endif /* _Client_H__ */
Index: code/trunk/src/libraries/network/ClientConnection.cc
===================================================================
--- code/trunk/src/libraries/network/ClientConnection.cc	(revision 5781)
+++ code/trunk/src/libraries/network/ClientConnection.cc	(revision 5781)
@@ -0,0 +1,146 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ClientConnection.h"
+
+#include <cassert>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include "util/Debug.h"
+
+namespace orxonox
+{
+  const unsigned int NETWORK_CLIENT_WAIT_TIME = 1;
+  const unsigned int NETWORK_CLIENT_CONNECTION_TIMEOUT = 3000; //millisecs
+  const unsigned int NETWORK_CLIENT_MAX_CONNECTIONS = 5;
+  const unsigned int NETWORK_CLIENT_CHANNELS = 2;
+
+
+  ClientConnection::ClientConnection():
+    established_(false),
+    server_(NULL)
+  {
+    this->serverAddress_ = new ENetAddress();
+    //set standard address and port
+    enet_address_set_host(this->serverAddress_, "127.0.0.1");
+    serverAddress_->port = NETWORK_PORT;
+  }
+
+  ClientConnection::~ClientConnection(){
+    if(this->established_)
+      closeConnection();
+    delete this->serverAddress_; // surely was created
+  }
+
+  void ClientConnection::setServerAddress( const std::string& serverAddress ) {
+    enet_address_set_host (this->serverAddress_, serverAddress.c_str());
+  }
+
+  void ClientConnection::setPort( unsigned int port ) {
+    this->serverAddress_->port = port;
+  }
+
+  bool ClientConnection::establishConnection()
+  {
+    ENetEvent event;
+    
+    this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
+    if ( this->host_ == NULL )
+    {
+      COUT(2) << "ClientConnection: host_ == NULL" << std::endl;
+      // error handling
+      return false;
+    }
+    this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CLIENT_CHANNELS);
+    if ( this->server_==NULL )
+    {
+      COUT(2) << "ClientConnection: server == NULL" << std::endl;
+      // error handling
+      return false;
+    }
+    // handshake
+    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++ )
+    {
+      if( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && event.type == ENET_EVENT_TYPE_CONNECT )
+      {
+        this->established_=true;
+        return true;
+      }
+    }
+    COUT(1) << "Could not connect to server" << endl;
+    return false;
+  }
+
+  bool ClientConnection::closeConnection() {
+    ENetEvent event;
+    
+    if ( !this->established_ )
+      return true;
+    this->established_ = false;
+    enet_peer_disconnect(this->server_, 0);
+    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++)
+    {
+      if ( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME) >= 0 )
+      {
+        switch (event.type)
+        {
+          case ENET_EVENT_TYPE_NONE:
+          case ENET_EVENT_TYPE_CONNECT:
+            break;
+          case ENET_EVENT_TYPE_RECEIVE:
+            enet_packet_destroy(event.packet);
+            break;
+          case ENET_EVENT_TYPE_DISCONNECT:
+            COUT(4) << "received disconnect confirmation from server" << endl;
+            return true;
+        }
+      }
+    }
+    enet_peer_reset( this->server_ );
+    return false;
+  }
+
+
+  bool ClientConnection::addPacket(ENetPacket *packet) {
+    assert( this->server_ );
+    assert( packet );
+    return Connection::addPacket( packet, this->server_ );
+  }
+
+  void ClientConnection::addClient(ENetEvent* event)
+  {
+    assert(0);
+  }
+  void ClientConnection::disconnectPeer(ENetEvent* event)
+  {
+    this->established_=false;
+    COUT(1) << "Received disconnect Packet from Server!" << endl;
+        // server closed the connection
+  }
+
+}
Index: code/trunk/src/libraries/network/ClientConnection.h
===================================================================
--- code/trunk/src/libraries/network/ClientConnection.h	(revision 5781)
+++ code/trunk/src/libraries/network/ClientConnection.h	(revision 5781)
@@ -0,0 +1,70 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+ 
+#ifndef _ClientConnection_H__
+#define _ClientConnection_H__
+
+#include "NetworkPrereqs.h"
+#include "Connection.h"
+
+namespace orxonox
+{
+
+  class _NetworkExport ClientConnection: public Connection{
+  public:
+    ClientConnection();
+    virtual ~ClientConnection();
+    
+    void setServerAddress( const std::string& serverAddress );
+    void setPort( unsigned int port );
+    
+    ENetEvent *getEvent();
+    // check wheter the packet queue is empty
+    bool queueEmpty();
+    // create a new listener thread
+    virtual bool establishConnection();
+    virtual bool closeConnection();
+    // add a packet to queue for the server
+    bool addPacket(ENetPacket *packet);
+    inline bool isConnected(){ return this->established_; }
+  private:
+    virtual void addClient(ENetEvent* event);
+    virtual void disconnectPeer(ENetEvent* event);
+    
+    bool disconnectConnection();
+    // enet stuff
+    ENetAddress *serverAddress_;
+    bool established_;
+    // clientlist
+    ENetPeer *server_;
+};
+
+
+}
+
+#endif /* _ClientConnection_H__ */
Index: code/trunk/src/libraries/network/ClientConnectionListener.cc
===================================================================
--- code/trunk/src/libraries/network/ClientConnectionListener.cc	(revision 5781)
+++ code/trunk/src/libraries/network/ClientConnectionListener.cc	(revision 5781)
@@ -0,0 +1,54 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ClientConnectionListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "ClientInformation.h"
+
+namespace orxonox{
+
+  ClientConnectionListener::ClientConnectionListener()
+  { 
+    RegisterRootObject(ClientConnectionListener); 
+  }
+
+  void ClientConnectionListener::getConnectedClients(){
+    if(GameMode::showsGraphics())
+      this->clientConnected(0); //server client id
+    ClientInformation *client = ClientInformation::getBegin();
+    while(client){
+      this->clientConnected(client->getID());
+      client=client->next();
+    }
+  }
+
+}
+
+
Index: code/trunk/src/libraries/network/ClientConnectionListener.h
===================================================================
--- code/trunk/src/libraries/network/ClientConnectionListener.h	(revision 5781)
+++ code/trunk/src/libraries/network/ClientConnectionListener.h	(revision 5781)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ClientConnectionListener_H__
+#define _ClientConnectionListener_H__
+
+#include "NetworkPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox{
+
+  class _NetworkExport ClientConnectionListener : virtual public OrxonoxClass
+  {
+    friend class Server;
+
+  public:
+    ClientConnectionListener();
+    virtual ~ClientConnectionListener() {}
+
+    void getConnectedClients();
+
+  protected:
+    virtual void clientConnected(unsigned int clientID) = 0;
+    virtual void clientDisconnected(unsigned int clientID) = 0;
+  };
+
+}
+
+
+#endif /* _ClientConnectionListener_H__ */
Index: code/trunk/src/libraries/network/ClientInformation.cc
===================================================================
--- code/trunk/src/libraries/network/ClientInformation.cc	(revision 5781)
+++ code/trunk/src/libraries/network/ClientInformation.cc	(revision 5781)
@@ -0,0 +1,272 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: ClientInformation
+//
+// Description:
+//
+//
+// Author:  <>, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "ClientInformation.h"
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+
+namespace orxonox
+{
+  
+
+  ClientInformation *ClientInformation::head_=0;
+
+  ClientInformation::ClientInformation() {
+    if(!head_)
+      head_=this;
+    gamestateID_=GAMESTATEID_INITIAL;
+    preve=0;
+    nexte=0;
+    partialGamestateID_=GAMESTATEID_INITIAL-1;
+    synched_=false;
+  }
+
+  ClientInformation::~ClientInformation() {
+    if(prev()!=0)
+      prev()->setNext(this->next());
+    if(next()!=0)
+      next()->setPrev(this->prev());
+    if(this==head_)
+      head_=next();
+  }
+
+  ClientInformation *ClientInformation::next() {
+    if(this!=0)
+      return this->nexte;
+    else
+      return 0;
+  }
+  ClientInformation *ClientInformation::prev() {
+    if(this!=0)
+      return this->preve;
+    else
+      return 0;
+  }
+
+  bool ClientInformation::setPrev(ClientInformation *prev) {
+    if(this==head_)
+      head_=prev;
+    this->preve = prev;
+    return true;
+  }
+
+  bool ClientInformation::setNext(ClientInformation *next) {
+    this->nexte = next;
+    return true;
+  }
+
+  ClientInformation *ClientInformation::insertAfter(ClientInformation *ins) {
+    this->next()->setPrev(ins);
+    ins->setNext(this->next());
+    ins->setPrev(this);
+    this->nexte = ins;
+    return ins;
+  }
+
+  ClientInformation *ClientInformation::insertBefore(ClientInformation *ins){
+    if(!this)
+      return NULL;
+    this->prev()->setNext(ins);
+    ins->setPrev(this->prev());
+    this->preve=ins;
+    ins->setNext(this);
+    return ins;
+  }
+
+  void ClientInformation::setID(int clientID){
+    if(!this)
+      return;
+    clientID_ = clientID;
+  }
+
+  bool ClientInformation::setPeer(ENetPeer *peer){
+    if(!this)
+      return false;
+    peer_ = peer;
+    return true;
+  }
+
+  bool ClientInformation::setGamestateID(int id){
+    if(!this)
+      return false;
+    gamestateID_=id;
+    return true;
+  }
+
+  bool ClientInformation::setPartialGamestateID(int id){
+    if(!this)
+      return false;
+    partialGamestateID_=id;
+    return true;
+  }
+
+  unsigned int ClientInformation::getID() {
+    if(!this)
+      return CLIENTID_UNKNOWN;
+    else
+      return clientID_;
+  }
+
+  ENetPeer *ClientInformation::getPeer() {
+    if(this)
+      return peer_;
+    else
+      return NULL;
+  }
+
+  int ClientInformation::getFailures(){
+    return failures_;
+  }
+  void ClientInformation::addFailure(){
+    failures_++;
+  }
+  void ClientInformation::resetFailures(){
+    failures_=0;
+  }
+
+  uint32_t ClientInformation::getRTT(){
+    return this->peer_->roundTripTime;
+  }
+
+  double ClientInformation::getPacketLoss(){
+    return static_cast<double>(this->peer_->packetLoss)/ENET_PEER_PACKET_LOSS_SCALE;
+  }
+
+  unsigned int ClientInformation::getGamestateID() {
+    if(this)
+      return gamestateID_;
+    else
+      return static_cast<unsigned int>(-1);
+  }
+
+  unsigned int ClientInformation::getPartialGamestateID() {
+    if(this)
+      return partialGamestateID_;
+    else
+      return static_cast<unsigned int>(-1);
+  }
+
+  ClientInformation *ClientInformation::insertBack(ClientInformation *ins) {
+    ClientInformation *temp = head_;
+    if(temp==ins){
+      return head_;
+    }
+    while(temp->next()!=0){
+      temp = temp->next();
+    }
+    temp->setNext(ins);
+    ins->setPrev(temp);
+    return ins;
+  }
+
+  bool ClientInformation::removeClient(unsigned int clientID) {
+    if(clientID==CLIENTID_UNKNOWN)
+      return false;
+    ClientInformation *temp = head_;
+    while(temp!=0 && temp->getID()!=clientID)
+      temp = temp->next();
+    if(temp==0)
+      return false;
+    delete temp;
+    return true;
+  }
+
+  bool ClientInformation::removeClient(ENetPeer *peer) {
+    if(!peer)
+      return false;
+    ClientInformation *temp = head_;
+    while(temp!=0){
+      if(temp->getPeer()->address.host==peer->address.host && temp->getPeer()->address.port==peer->address.port)
+        break;
+      temp = temp->next();
+    }
+    if(temp==0)
+      return false;
+    delete temp;
+    return true;
+  }
+
+  /**
+  * This function goes forward through the list and looks for an element with clientID
+  * This function should only be applied to the head of the list
+  * @param clientID id to look for
+  * @return pointer to the last element in the list or 0 if the search was unsuccessfull
+  */
+  ClientInformation *ClientInformation::findClient(unsigned int clientID, bool look_backwards) {
+    ClientInformation *temp = head_;
+    while(temp!=0 && temp->getID()!=clientID){
+      temp = temp->next();
+    }
+    // returns 0 if nothing has been found
+    return temp;
+  }
+
+  /**
+  * This function goes forward through the list and looks for an element with clientID
+  * This function should only be applied to the head of the list
+  * @param peer peer to look for
+  * @return pointer to the element in the list
+  */
+  ClientInformation *ClientInformation::findClient(ENetAddress *address, bool look_backwards) {
+    ClientInformation *temp = head_;
+    while(temp!=0){
+      if(temp->getPeer()->address.host==address->host && temp->getPeer()->address.port == address->port)
+        break;
+      temp = temp->next();
+    }
+    // returns 0 if nothing has been found
+    return temp;
+  }
+
+  bool ClientInformation::setSynched(bool s) {
+    if(!this)
+      return false;
+    synched_=s;
+    return true;
+  }
+
+  bool ClientInformation::getSynched() {
+    if(this)
+      return synched_;
+    else
+      return false;
+  }
+
+}
Index: code/trunk/src/libraries/network/ClientInformation.h
===================================================================
--- code/trunk/src/libraries/network/ClientInformation.h	(revision 5781)
+++ code/trunk/src/libraries/network/ClientInformation.h	(revision 5781)
@@ -0,0 +1,117 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: ClientInformation
+//
+// Description:
+//
+//
+// Author:  <>, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _ClientInformation_H__
+#define _ClientInformation_H__
+
+#include "NetworkPrereqs.h"
+
+// WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
+
+namespace orxonox
+{
+
+  /**
+  * This class implements a list for client information
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport ClientInformation{
+  public:
+    ClientInformation();
+    //   ClientInformation(ClientInformation *prev, ClientInformation *next);
+    //   ClientInformation(ClientInformation *prev);
+    ~ClientInformation();
+    ClientInformation *next();
+    ClientInformation *prev();
+    static ClientInformation *insertBack(ClientInformation *ins);
+
+    // set functions
+    void setID(int clientID);
+    bool setPeer(ENetPeer *peer);
+    bool setGamestateID(int id);
+    bool setPartialGamestateID(int id);
+    inline void setShipID(unsigned int id){ShipID_=id;}
+
+    // get functions
+    inline unsigned int getShipID(){return ShipID_;}
+    unsigned int getID();
+    unsigned int getGamestateID();
+    unsigned int getPartialGamestateID();
+    ENetPeer *getPeer();
+
+    int getFailures();
+    void addFailure();
+    void resetFailures();
+    uint32_t getRTT();
+    double getPacketLoss();
+
+    static bool removeClient(unsigned int clientID);
+    static bool removeClient(ENetPeer *peer);
+    static ClientInformation *findClient(unsigned int clientID, bool look_backwards=false);
+    static ClientInformation *findClient(ENetAddress *address, bool look_backwards=false);
+    static ClientInformation *getBegin(){return head_;}
+    static bool hasClients(){ return ClientInformation::head_!=0; }
+
+    bool setSynched(bool s);
+    bool getSynched();
+
+  private:
+    static ClientInformation *head_;
+
+    bool setNext(ClientInformation *next);
+    bool setPrev(ClientInformation *prev);
+    ClientInformation *insertAfter(ClientInformation *ins);
+    ClientInformation *insertBefore(ClientInformation *ins);
+
+    ClientInformation *preve;
+    ClientInformation *nexte;
+    //actual information:
+    ENetPeer *peer_;
+    unsigned int clientID_;
+    unsigned int gamestateID_;
+    unsigned int partialGamestateID_;
+    unsigned int ShipID_;   // this is the unique objectID
+    bool synched_;
+    unsigned short failures_;
+
+  };
+
+}
+
+#endif /* _ClientInformation_H__ */
Index: code/trunk/src/libraries/network/Connection.cc
===================================================================
--- code/trunk/src/libraries/network/Connection.cc	(revision 5781)
+++ code/trunk/src/libraries/network/Connection.cc	(revision 5781)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Connection.h"
+
+#include <cassert>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include "packet/Packet.h"
+
+namespace orxonox
+{
+  Connection *Connection::instance_=0;
+
+  Connection::Connection():
+    host_(0)
+  {
+    assert(instance_==0);
+    Connection::instance_=this;
+    enet_initialize();
+    atexit(enet_deinitialize);
+  }
+
+  Connection::~Connection(){
+    Connection::instance_=0;
+  }
+
+  int Connection::service(ENetEvent* event) {
+    return enet_host_service( this->host_, event, NETWORK_WAIT_TIMEOUT );
+  }
+
+  void Connection::disconnectPeer(ENetPeer *peer) {
+    enet_peer_disconnect(peer, 0);
+  }
+
+  bool Connection::addPacket(ENetPacket *packet, ENetPeer *peer) {
+    if(enet_peer_send(peer, NETWORK_DEFAULT_CHANNEL, packet)!=0)
+      return false;
+    else
+      return true;
+  }
+
+  bool Connection::sendPackets() {
+    if ( !Connection::instance_ || this->host_==NULL )
+      return false;
+    enet_host_flush(this->host_);
+    return true;
+  }
+
+  void Connection::processQueue() {
+    ENetEvent event;
+    
+    assert(this->host_);
+
+    while( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
+    {
+      switch(event.type){
+        // log handling ================
+        case ENET_EVENT_TYPE_CONNECT:
+          addClient( &event );
+          break;
+        case ENET_EVENT_TYPE_DISCONNECT:
+          disconnectPeer( &event );
+          break;
+        case ENET_EVENT_TYPE_RECEIVE:
+          processPacket( &event );
+          break;
+        case ENET_EVENT_TYPE_NONE:
+          break;
+      }
+    }
+  }
+
+  bool Connection::processPacket(ENetEvent* event) {
+    packet::Packet *p = packet::Packet::createPacket(event->packet, event->peer);
+    return p->process();
+  }
+
+}
Index: code/trunk/src/libraries/network/Connection.h
===================================================================
--- code/trunk/src/libraries/network/Connection.h	(revision 5781)
+++ code/trunk/src/libraries/network/Connection.h	(revision 5781)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: Connection
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _Connection_H__
+#define _Connection_H__
+
+#include "NetworkPrereqs.h"
+
+namespace orxonox
+{
+    const unsigned int NETWORK_PORT = 55556;
+    const unsigned int NETWORK_MAX_CONNECTIONS = 50;
+    const unsigned int NETWORK_WAIT_TIMEOUT = 0;
+    const unsigned int NETWORK_DEFAULT_CHANNEL = 0;
+    const unsigned int NETWORK_MAX_QUEUE_PROCESS_TIME = 5;
+
+  class _NetworkExport Connection{
+  public:
+    virtual ~Connection();
+    
+    static bool addPacket(ENetPacket *packet, ENetPeer *peer);
+    bool sendPackets();
+    ENetHost* getHost(){ return this->host_; }
+
+  protected:
+    Connection();
+    static Connection* getInstance(){ return Connection::instance_; }
+    
+    int service(ENetEvent* event);
+    void disconnectPeer(ENetPeer *peer);
+    
+    void processQueue();
+    virtual void addClient(ENetEvent* event)=0;
+    virtual void disconnectPeer(ENetEvent* event)=0;
+    virtual bool processPacket(ENetEvent* event);
+    
+    ENetHost *host_;
+  private:
+    ENetAddress *bindAddress_;
+
+    static Connection *instance_;
+
+  };
+
+}
+
+#endif /* _Connection_H__ */
Index: code/trunk/src/libraries/network/FunctionCallManager.cc
===================================================================
--- code/trunk/src/libraries/network/FunctionCallManager.cc	(revision 5781)
+++ code/trunk/src/libraries/network/FunctionCallManager.cc	(revision 5781)
@@ -0,0 +1,165 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionCallManager.h"
+#include "packet/FunctionCalls.h"
+
+namespace orxonox {
+    
+std::map<uint32_t, packet::FunctionCalls*> FunctionCallManager::clientMap_;
+
+// Static calls
+
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::	clientMap_[clientID]->addCallStatic(functionID);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+{  
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4, &mt5);
+}
+
+
+// MemberCalls
+
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+{ 
+  if(clientMap_.find(clientID)==clientMap_.end()) 
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls; 
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID); 
+  } 
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4, &mt5);
+}
+
+// Send calls
+
+void FunctionCallManager::sendCalls()
+{
+  std::map<uint32_t, packet::FunctionCalls*>::iterator it;
+  for (it = FunctionCallManager::clientMap_.begin(); it != FunctionCallManager::clientMap_.end(); it++ )
+  {
+    assert(!FunctionCallManager::clientMap_.empty());
+    it->second->send();
+  }
+  FunctionCallManager::clientMap_.clear();
+}
+
+
+} //namespace orxonox
Index: code/trunk/src/libraries/network/FunctionCallManager.h
===================================================================
--- code/trunk/src/libraries/network/FunctionCallManager.h	(revision 5781)
+++ code/trunk/src/libraries/network/FunctionCallManager.h	(revision 5781)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FunctionCallManager_H__
+#define _FunctionCallManager_H__
+
+#include "NetworkPrereqs.h"
+
+#include <map>
+#include "util/UtilPrereqs.h"
+
+namespace orxonox {
+/**
+	@author
+*/
+
+class _NetworkExport FunctionCallManager
+{
+public:
+  static void addCallStatic(uint32_t functionID, uint32_t clientID);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
+  
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
+  
+  static void sendCalls();
+  
+  static std::map<uint32_t, packet::FunctionCalls*> clientMap_;
+protected:
+  FunctionCallManager();
+  ~FunctionCallManager();
+};
+
+} //namespace orxonox
+
+#endif /* _FunctionCallManager_H__ */
Index: code/trunk/src/libraries/network/GamestateClient.cc
===================================================================
--- code/trunk/src/libraries/network/GamestateClient.cc	(revision 5781)
+++ code/trunk/src/libraries/network/GamestateClient.cc	(revision 5781)
@@ -0,0 +1,186 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      Dumeni Manatschal
+ *
+ */
+
+#include "GamestateClient.h"
+
+#include "util/Debug.h"
+#include "core/ObjectList.h"
+#include "synchronisable/Synchronisable.h"
+#include "synchronisable/NetworkCallbackManager.h"
+#include "packet/Acknowledgement.h"
+#include "packet/Gamestate.h"
+
+
+namespace orxonox
+{
+  struct _NetworkExport GameStateItem{
+    packet::Gamestate *state;
+    unsigned int id;
+  };
+
+  GamestateClient::GamestateClient() {
+    COUT(5) << "this: " << this << std::endl;
+    last_diff_=0;
+    last_gamestate_=GAMESTATEID_INITIAL-1;
+    tempGamestate_=NULL;
+  }
+
+  GamestateClient::~GamestateClient() {
+      std::map<unsigned int, packet::Gamestate *>::iterator it;
+      for ( it = this->gamestateMap_.begin(); it != this->gamestateMap_.end(); ++it )
+          delete (*it).second;
+      if( this->tempGamestate_ )
+          delete this->tempGamestate_;
+  }
+
+  bool GamestateClient::ack(unsigned int gamestateID, unsigned int clientID){
+    return true;
+  }
+
+  bool GamestateClient::add(packet::Gamestate *gs, unsigned int clientID){
+    if(tempGamestate_!=NULL){
+      //delete the obsolete gamestate
+      if(tempGamestate_->getID()>gs->getID())
+        return false;
+      delete tempGamestate_;
+    }
+    tempGamestate_=gs;
+    return true;
+  }
+
+  bool GamestateClient::processGamestates(){
+    if(tempGamestate_==NULL)
+      return false;
+    bool isDiffed = tempGamestate_->isDiffed();
+    int id = GAMESTATEID_INITIAL;
+    packet::Gamestate *processed = processGamestate(tempGamestate_);
+    assert(processed);
+    
+    //now call the queued callbacks
+    NetworkCallbackManager::callCallbacks();
+    
+    if (!processed){
+      sendAck(0);
+      return false;
+    }
+    //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
+    tempGamestate_=NULL;
+    gamestateMap_[processed->getID()]=processed;
+    if(isDiffed)
+      last_diff_ = processed->getBaseID();
+    id = processed->getID();
+    sendAck(id);
+    return true;
+  }
+
+
+  /**
+  * This function removes a Synchronisable out of the universe
+  * @param it iterator of the list pointing to the object
+  * @return iterator pointing to the next object in the list
+  */
+  void GamestateClient::removeObject(ObjectList<Synchronisable>::iterator &it) {
+    ObjectList<Synchronisable>::iterator temp=it;
+    ++it;
+    delete  *temp;
+  }
+
+  packet::Gamestate *GamestateClient::getGamestate(){
+    packet::Gamestate *gs = new packet::Gamestate();
+    if(!gs->collectData(0,0x2)){
+      delete gs;
+      return 0;
+    }
+    return gs;
+  }
+
+  void GamestateClient::cleanup(){
+    std::map<unsigned int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
+    while(it!=gamestateMap_.end()){
+      if(it->first>=last_diff_)
+        break;
+      // otherwise delete that stuff
+      delete (*it).second;
+      temp=it++;
+      gamestateMap_.erase(temp);
+    }
+    tempGamestate_=NULL;
+  }
+
+  void GamestateClient::printGamestateMap(){
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    COUT(4) << "gamestates: ";
+    for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++){
+      COUT(4) << it->first << ":" << it->second << "|";
+    }
+    COUT(4) << std::endl;
+
+  }
+
+  bool GamestateClient::sendAck(unsigned int gamestateID){
+    packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, 0);
+    if(!ack->send()){
+      COUT(3) << "could not ack gamestate: " << gamestateID << std::endl;
+      return false;
+    }
+    else{
+      COUT(5) << "acked a gamestate: " << gamestateID << std::endl;
+      return true;
+    }
+  }
+
+  packet::Gamestate *GamestateClient::processGamestate(packet::Gamestate *gs){
+    if(gs->isCompressed())
+    {
+      bool b = gs->decompressData();
+      assert(b);
+    }
+    if(gs->isDiffed()){
+      packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
+      if(!base){
+        COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
+        delete gs;
+        return 0;
+      }
+//       assert(base); //TODO: fix this
+      packet::Gamestate *undiffed = gs->undiff(base);
+      delete gs;
+      gs=undiffed;
+      COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
+    }
+    if(gs->spreadData(0x2))
+      return gs;
+    else
+    {
+      COUT(3) << "could not spread gamestate" << endl;
+      return NULL;
+    }
+  }
+
+}
+
Index: code/trunk/src/libraries/network/GamestateClient.h
===================================================================
--- code/trunk/src/libraries/network/GamestateClient.h	(revision 5781)
+++ code/trunk/src/libraries/network/GamestateClient.h	(revision 5781)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      Dumeni Manatschal
+ *
+ */
+
+//
+// C++ Interface: GameStateClient
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _GamestateClient_H__
+#define _GamestateClient_H__
+
+#include "NetworkPrereqs.h"
+
+#include <map>
+#include "core/CorePrereqs.h"
+#include "GamestateHandler.h"
+
+const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1);
+
+namespace orxonox
+{
+  class _NetworkExport GamestateClient: public GamestateHandler
+  {
+  public:
+    GamestateClient();
+    ~GamestateClient();
+
+    bool add(packet::Gamestate *gs, unsigned int clientID);
+    bool ack(unsigned int gamestateID, unsigned int clientID);
+
+    bool processGamestates();
+    packet::Gamestate *getGamestate();
+    void cleanup();
+  private:
+    packet::Gamestate *processGamestate(packet::Gamestate *gs);
+    void removeObject(ObjectListIterator<Synchronisable> &it);
+    void printGamestateMap();
+    bool sendAck(unsigned int gamestateID);
+
+    unsigned int           last_diff_;
+    unsigned int           last_gamestate_;
+    std::map<unsigned int, packet::Gamestate *> gamestateMap_;
+    packet::Gamestate *tempGamestate_; // we save the received gamestates here during processQueue
+
+  };
+
+}
+
+#endif /* _GamestateClient_H__ */
Index: code/trunk/src/libraries/network/GamestateHandler.cc
===================================================================
--- code/trunk/src/libraries/network/GamestateHandler.cc	(revision 5781)
+++ code/trunk/src/libraries/network/GamestateHandler.cc	(revision 5781)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GamestateHandler.h"
+#include <cassert>
+
+namespace orxonox {
+
+GamestateHandler *GamestateHandler::instance_=0;
+  
+GamestateHandler::GamestateHandler()
+{
+  assert(instance_==0);
+  instance_=this;
+}
+
+
+GamestateHandler::~GamestateHandler()
+{
+  instance_=0;
+}
+
+
+
+}//namespace orxonox
Index: code/trunk/src/libraries/network/GamestateHandler.h
===================================================================
--- code/trunk/src/libraries/network/GamestateHandler.h	(revision 5781)
+++ code/trunk/src/libraries/network/GamestateHandler.h	(revision 5781)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GamestateHandler_H__
+#define _GamestateHandler_H__
+
+#include "NetworkPrereqs.h"
+
+namespace orxonox {
+
+/**
+	@author Oliver Scheuss
+*/
+class _NetworkExport GamestateHandler{
+  private:
+    virtual bool add(packet::Gamestate *gs, unsigned int clientID)=0;
+    virtual bool ack(unsigned int gamestateID, unsigned int clientID)=0;
+
+    static GamestateHandler *instance_;
+
+
+  protected:
+    GamestateHandler();
+    virtual ~GamestateHandler();
+
+  public:
+    static bool addGamestate(packet::Gamestate *gs, unsigned int clientID){ return instance_->add(gs, clientID); }
+    static bool ackGamestate(unsigned int gamestateID, unsigned int clientID){ return instance_->ack(gamestateID, clientID); }
+};
+
+}
+
+#endif /* _GamestateHandler_H__ */
Index: code/trunk/src/libraries/network/GamestateManager.cc
===================================================================
--- code/trunk/src/libraries/network/GamestateManager.cc	(revision 5781)
+++ code/trunk/src/libraries/network/GamestateManager.cc	(revision 5781)
@@ -0,0 +1,277 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: GameStateManager
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "GamestateManager.h"
+
+#include <cassert>
+#include <queue>
+// #include <boost/thread/mutex.hpp>
+
+#include "util/Debug.h"
+#include "core/Executor.h"
+#include "core/ThreadPool.h"
+#include "ClientInformation.h"
+#include "packet/Acknowledgement.h"
+#include "packet/Gamestate.h"
+#include "synchronisable/NetworkCallbackManager.h"
+#include "TrafficControl.h"
+
+namespace orxonox
+{
+  GamestateManager::GamestateManager() :
+  reference(0), id_(0)
+  {
+    trafficControl_ = new TrafficControl();
+//     threadMutex_ = new boost::mutex();
+//     threadPool_ = new ThreadPool();
+  }
+
+  GamestateManager::~GamestateManager()
+  {
+    if( this->reference )
+        delete this->reference;std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for( it = gamestateQueue.begin(); it != gamestateQueue.end(); ++it )
+      delete (*it).second;
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator it1;
+    std::map<unsigned int, packet::Gamestate*>::iterator it2;
+    for( it1 = gamestateMap_.begin(); it1 != gamestateMap_.end(); ++it1 )
+    {
+      for( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
+        delete (*it2).second;
+    }
+    delete this->trafficControl_;
+//     delete this->threadMutex_;
+//     delete this->threadPool_;
+  }
+
+  bool GamestateManager::update(){
+//     cleanup();
+    return getSnapshot();
+  }
+
+  bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
+    assert(gs);
+    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
+    if(it!=gamestateQueue.end()){
+      // delete obsolete gamestate
+      delete it->second;
+    }
+    gamestateQueue[clientID] = gs;
+    return true;
+  }
+
+  bool GamestateManager::processGamestates(){
+    if( this->gamestateQueue.empty() )
+        return true;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    // now push only the most recent gamestates we received (ignore obsolete ones)
+    for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){
+      bool b = processGamestate(it->second);
+      assert(b);
+      delete it->second;
+    }
+    // now clear the queue
+    gamestateQueue.clear();
+    //and call all queued callbacks
+    NetworkCallbackManager::callCallbacks();
+    return true;
+  }
+
+
+  bool GamestateManager::getSnapshot(){
+    if ( reference != 0 )
+      delete reference;
+    reference = new packet::Gamestate();
+    if(!reference->collectData(++id_, 0x1)){ //we have no data to send
+      delete reference;
+      reference=0;
+    }
+    return true;
+  }
+  
+  void GamestateManager::sendGamestates()
+  {
+    ClientInformation *temp = ClientInformation::getBegin();
+    std::queue<packet::Gamestate*> clientGamestates;
+    while(temp != NULL){
+      if( !(temp->getSynched()) ){
+        COUT(5) << "Server: not sending gamestate" << std::endl;
+        temp=temp->next();
+        if(!temp)
+          break;
+        continue;
+      }
+      COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss() << std::endl;
+      COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl;
+      int cid = temp->getID(); //get client id
+      
+      unsigned int gID = temp->getGamestateID();
+      if(!reference)
+        return;
+      
+      packet::Gamestate *client=0;
+      if(gID != GAMESTATEID_INITIAL){
+        assert(gamestateMap_.find(cid)!=gamestateMap_.end());
+        std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[cid].find(gID);
+        if(it!=gamestateMap_[cid].end())
+        {
+          client = it->second;
+        }
+      }
+      
+      clientGamestates.push(0);
+      finishGamestate( cid, &clientGamestates.back(), client, reference );
+      //FunctorMember<GamestateManager>* functor = 
+//       ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate) );
+//       executor->setObject(this);
+//       executor->setDefaultValues( cid, &clientGamestates.back(), client, reference );
+//       (*static_cast<Executor*>(executor))();
+//       this->threadPool_->passFunction( executor, true );
+//       (*functor)( cid, &(clientGamestates.back()), client, reference );
+      
+      temp = temp->next();
+    }
+    
+//     threadPool_->synchronise();
+    
+    while( !clientGamestates.empty() )
+    {
+      if(clientGamestates.front())
+        clientGamestates.front()->send();
+      clientGamestates.pop();
+    }
+  }
+
+
+  void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate** destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
+    //why are we searching the same client's gamestate id as we searched in
+    //Server::sendGameState?
+    // save the (undiffed) gamestate in the clients gamestate map
+    //chose wheather the next gamestate is the first or not
+    
+    packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
+//     packet::Gamestate *gs = new packet::Gamestate(*gamestate);
+//     packet::Gamestate *gs = new packet::Gamestate();
+//     gs->collectData( id_, 0x1 );
+//     this->threadMutex_->lock();
+    gamestateMap_[clientID][gamestate->getID()]=gs;
+//     this->threadMutex_->unlock();
+    
+    if(base)
+    {
+        
+//       COUT(3) << "diffing" << std::endl;
+//       packet::Gamestate* gs1  = gs;
+      packet::Gamestate *diffed = gs->diff(base);
+      //packet::Gamestate *gs2 = diffed->undiff(gs);
+//       assert(*gs == *gs2);
+      gs = diffed;
+//       packet::Gamestate* gs2 = gs->undiff(client);
+//       gs = new packet::Gamestate(*gs);
+//       assert(*gs1==*gs2);
+    }
+    else{
+      gs = new packet::Gamestate(*gs);
+    }
+    
+    
+    bool b = gs->compressData();
+    assert(b);
+//     COUT(4) << "sending gamestate with id " << gs->getID();
+//     if(gamestate->isDiffed())
+//     COUT(4) << " and baseid " << gs->getBaseID() << endl;
+//     else
+//     COUT(4) << endl;
+    gs->setClientID(clientID);
+    *destgamestate = gs;
+  }
+
+
+  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
+    ClientInformation *temp = ClientInformation::findClient(clientID);
+    assert(temp);
+    unsigned int curid = temp->getGamestateID();
+
+    if(gamestateID == ACKID_NACK){
+      temp->setGamestateID(GAMESTATEID_INITIAL);
+      // now delete all saved gamestates for this client
+      std::map<unsigned int, packet::Gamestate*>::iterator it;
+      for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
+        delete it->second;
+
+        gamestateMap_[clientID].erase(it++);
+      }
+      return true;
+    }
+
+    assert(curid==GAMESTATEID_INITIAL || curid<gamestateID);
+    COUT(5) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
+      delete it->second;
+      gamestateMap_[clientID].erase(it++);
+    }
+    temp->setGamestateID(gamestateID);
+    TrafficControl::processAck(clientID, gamestateID);
+    return true;
+  }
+
+  void GamestateManager::removeClient(ClientInformation* client){
+    assert(client);
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
+    // first delete all remained gamestates
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
+      delete it->second;
+    // now delete the clients gamestatemap
+    gamestateMap_.erase(clientMap);
+  }
+
+  bool GamestateManager::processGamestate(packet::Gamestate *gs){
+    if(gs->isCompressed())
+    {
+       bool b = gs->decompressData();
+       assert(b);
+    }
+    assert(!gs->isDiffed());
+    return gs->spreadData(0x1);
+  }
+
+}
Index: code/trunk/src/libraries/network/GamestateManager.h
===================================================================
--- code/trunk/src/libraries/network/GamestateManager.h	(revision 5781)
+++ code/trunk/src/libraries/network/GamestateManager.h	(revision 5781)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: GamestateManager
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _GamestateManager_H__
+#define _GamestateManager_H__
+
+#include "NetworkPrereqs.h"
+
+#include <map>
+#include "GamestateHandler.h"
+#include "core/CorePrereqs.h"
+
+namespace orxonox
+{
+
+  const int KEEP_GAMESTATES = 10;
+
+  /**
+  * This Class implements a manager for gamestates:
+  * - creating snapshots of gamestates
+  * - writing gamestates to universe
+  * - diffing gamestates
+  * EN/DECODATION:
+  * a: last Gamestate a client has received
+  * b: new Gamestate
+  * x: diffed and compressed gamestate
+  * x=(a^b)
+  * b=(a^x)
+  * diff(a,diff(a,x))=x (hope this is correct)
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport GamestateManager: public GamestateHandler{
+  public:
+    GamestateManager();
+    ~GamestateManager();
+
+    bool add(packet::Gamestate *gs, unsigned int clientID);
+    bool processGamestates();
+    bool update();
+    void sendGamestates();
+//     packet::Gamestate *popGameState(unsigned int clientID);
+    void finishGamestate( unsigned int clientID, packet::Gamestate** destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );
+
+    bool getSnapshot();
+
+    bool ack(unsigned int gamestateID, unsigned int clientID);
+    void removeClient(ClientInformation *client);
+  private:
+    bool processGamestate(packet::Gamestate *gs);
+
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_;
+    std::map<unsigned int, packet::Gamestate*> gamestateQueue;
+    packet::Gamestate *reference;
+    TrafficControl *trafficControl_;
+    unsigned int id_;
+//     boost::mutex* threadMutex_;
+    ThreadPool*   /*thread*/Pool_;
+  };
+
+}
+
+#endif /* _GameStateManager_H__ */
Index: code/trunk/src/libraries/network/Host.cc
===================================================================
--- code/trunk/src/libraries/network/Host.cc	(revision 5781)
+++ code/trunk/src/libraries/network/Host.cc	(revision 5781)
@@ -0,0 +1,114 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Host.h"
+
+#include <cassert>
+#include <string>
+
+#include "core/ConsoleCommand.h"
+#include "core/ObjectList.h"
+#include "ChatListener.h"
+
+namespace orxonox {
+
+SetConsoleCommandShortcut(Host, Chat);
+
+Host *Host::instance_=0;
+
+/**
+ * @brief Constructor: assures that only one reference will be created and sets the pointer
+ */
+Host::Host()
+{
+  clientID_=0;
+  assert(instance_==0);
+  instance_=this;
+}
+
+
+/**
+ * @brief Destructor: resets the instance pointer to 0
+ */
+Host::~Host()
+{
+  instance_=0;
+}
+
+/**
+ * This function is used to add an enetpacket to be sent to another peer
+ * @param packet Packet to be added
+ * @param clientID ID of the client the packet should be sent to
+ * @return success?
+ */
+bool Host::addPacket(ENetPacket *packet, int clientID){
+  if(instance_)
+    return instance_->queuePacket(packet, clientID);
+  else
+    return false;
+}
+
+/**
+ * This function returns the ID of the player
+ * @return playerID
+ */
+unsigned int Host::getPlayerID(){
+  if(!instance_)
+    return 0;
+  return instance_->clientID_;
+}
+
+bool Host::Chat(const std::string& message){
+  if(!instance_)
+  {
+    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, 0);
+    return true;
+  }
+  return instance_->chat(message);
+}
+
+bool Host::Broadcast(const std::string& message){
+  if(!instance_)
+  {
+    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, CLIENTID_UNKNOWN);
+    return true;
+  }
+  else
+    return instance_->broadcast(message);
+}
+
+bool Host::incomingChat(const std::string& message, unsigned int playerID){
+  for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+    it->incomingChat(message, playerID);
+
+  return instance_->processChat(message, playerID);
+}
+
+}//namespace orxonox
Index: code/trunk/src/libraries/network/Host.h
===================================================================
--- code/trunk/src/libraries/network/Host.h	(revision 5781)
+++ code/trunk/src/libraries/network/Host.h	(revision 5781)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_Host_H__
+#define _NETWORK_Host_H__
+
+#include "NetworkPrereqs.h"
+
+namespace orxonox {
+
+  const unsigned int CLIENTID_SERVER = 0;
+  const unsigned int NETWORK_FREQUENCY = 30;
+  const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
+
+/**
+*       @brief Base class of Server and Client
+*       This is the Base class of the Server and Client classes
+*       - Makes server and client a singleton
+*       - defines static functions available on both server and client
+*       - is the interface to be used when communicating with the network
+*	@author Oliver Scheuss
+*/
+class _NetworkExport Host{
+  private:
+    //TODO add theese functions or adequate
+    //virtual bool processChat(packet::Chat *message, unsigned int clientID)=0;
+    //virtual bool sendChat(packet::Chat *chat)=0;
+    virtual bool queuePacket(ENetPacket *packet, int clientID)=0;
+    virtual bool chat(const std::string& message)=0;
+    virtual bool broadcast(const std::string& message)=0;
+    virtual bool processChat(const std::string& message, unsigned int playerID)=0;
+    virtual bool isServer_()=0;
+
+
+
+  protected:
+    Host();
+    virtual ~Host();
+    static Host *instance_;
+    unsigned int clientID_;
+    unsigned int shipID_;
+
+  public:
+    static bool running(){return instance_!=0;}
+    static bool addPacket(ENetPacket *packet, int clientID=0);
+    //static bool chat(std::string& message);
+//     static bool receiveChat(packet::Chat *message, unsigned int clientID);
+    static unsigned int getPlayerID();
+    static unsigned int getShipID(){return instance_->shipID_;}
+    static void setClientID(unsigned int id){ instance_->clientID_ = id; }
+    static void setShipID(unsigned int id){ instance_->shipID_ = id; }
+    static bool isServer(){ return instance_->isServer_(); }
+    static bool Chat(const std::string& message);
+    static bool Broadcast(const std::string& message);
+    static bool incomingChat(const std::string& message, unsigned int playerID);
+  private:
+};
+
+}
+
+#endif /* _NETWORK_Host_H__ */
Index: code/trunk/src/libraries/network/NetworkFunction.cc
===================================================================
--- code/trunk/src/libraries/network/NetworkFunction.cc	(revision 5781)
+++ code/trunk/src/libraries/network/NetworkFunction.cc	(revision 5781)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NetworkFunction.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+  std::map<std::string, NetworkFunctionBase*> NetworkFunctionBase::nameMap_;
+  std::map<uint32_t, bool> NetworkFunctionBase::isStaticMap_;
+  
+  std::map<NetworkFunctionPointer, NetworkFunctionStatic*> NetworkFunctionStatic::functorMap_;
+  std::map<uint32_t, NetworkFunctionStatic*> NetworkFunctionStatic::idMap_;
+      
+  std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> NetworkMemberFunctionBase::functorMap_;
+  std::map<uint32_t, NetworkMemberFunctionBase*> NetworkMemberFunctionBase::idMap_;
+
+  NetworkFunctionBase::NetworkFunctionBase(const std::string& name)
+  {
+    RegisterRootObject(NetworkFunctionBase);
+    
+    static uint32_t networkID = 0;
+    this->networkID_ = networkID++;
+    
+    this->name_ = name;
+    nameMap_[name] = this;
+  }
+  NetworkFunctionBase::~NetworkFunctionBase()
+  {
+  }
+  
+  
+  void NetworkFunctionBase::destroyAllNetworkFunctions()
+  {
+    std::map<std::string, NetworkFunctionBase*>::iterator it;
+    for( it=NetworkFunctionBase::nameMap_.begin(); it!=NetworkFunctionBase::nameMap_.end(); ++it )
+      delete it->second;
+  }
+  
+  
+  NetworkFunctionStatic::NetworkFunctionStatic(FunctorStatic* functor, const std::string& name, const NetworkFunctionPointer& p):
+    NetworkFunctionBase(name)
+  {
+    RegisterObject(NetworkFunctionStatic);
+    
+    this->functor_ = functor;
+    functorMap_[p] = this;
+    idMap_[ this->getNetworkID() ] = this;
+  }
+  
+  NetworkFunctionStatic::~NetworkFunctionStatic()
+  {
+    delete this->functor_;
+  }
+  
+  
+  
+  NetworkMemberFunctionBase::NetworkMemberFunctionBase(const std::string& name, const NetworkFunctionPointer& p):
+    NetworkFunctionBase(name)
+  {
+    RegisterObject(NetworkMemberFunctionBase);
+    
+    functorMap_[p] = this;
+    idMap_[ this->getNetworkID() ] = this;
+  }
+  
+  NetworkMemberFunctionBase::~NetworkMemberFunctionBase()
+  {
+  }
+  
+
+}
Index: code/trunk/src/libraries/network/NetworkFunction.h
===================================================================
--- code/trunk/src/libraries/network/NetworkFunction.h	(revision 5781)
+++ code/trunk/src/libraries/network/NetworkFunction.h	(revision 5781)
@@ -0,0 +1,246 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NetworkFunction_H__
+#define _NetworkFunction_H__
+
+#include "NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include <map>
+#include <string>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/static_assert.hpp>
+
+#include "core/Functor.h"
+#include "core/Identifier.h"
+#include "FunctionCallManager.h"
+#include "synchronisable/Synchronisable.h"
+
+namespace orxonox
+{
+
+#if defined(ORXONOX_COMPILER_GCC) && defined(ORXONOX_ARCH_32)
+static const unsigned int MAX_FUNCTION_POINTER_SIZE = 8;
+#else
+static const unsigned int MAX_FUNCTION_POINTER_SIZE = 16;
+#endif //ORXONOX_COMPILER_GCC
+static const unsigned int MAX_FUNCTION_POINTER_INTS = (MAX_FUNCTION_POINTER_SIZE-1)/4+1;
+
+struct _NetworkExport NetworkFunctionPointer {
+  uint32_t pointer[MAX_FUNCTION_POINTER_INTS];
+  bool operator<(const NetworkFunctionPointer& b) const
+  {
+#if defined(ORXONOX_COMPILER_GCC) && defined(ORXONOX_ARCH_32)
+    return pointer[0]<b.pointer[0] ? true : pointer[1]<b.pointer[1];
+#else //ORXONOX_COMPILER_GCC
+    return pointer[0]<b.pointer[0] ? true : ( pointer[1]<b.pointer[1] ? true : ( pointer[2]<b.pointer[2] ? true : pointer[3]<b.pointer[3] ) );
+#endif //ORXONOX_COMPILER_GCC
+  }
+};
+
+
+
+
+
+class _NetworkExport NetworkFunctionBase: virtual public OrxonoxClass {
+  public:
+    NetworkFunctionBase(const std::string& name);
+    ~NetworkFunctionBase();
+    
+    virtual void        setNetworkID(uint32_t id)       { this->networkID_ = id; }
+    inline uint32_t     getNetworkID() const            { return this->networkID_; }
+    inline const std::string& getName() const           { return name_; }
+    static inline bool  isStatic( uint32_t networkID )  { return isStaticMap_[networkID]; }
+    
+    static inline void setNetworkID(const std::string& name, uint32_t id){ assert( nameMap_.find(name)!=nameMap_.end() ); nameMap_[name]->setNetworkID(id); }
+    
+    static void destroyAllNetworkFunctions();
+    
+  protected:
+    static std::map<uint32_t, bool> isStaticMap_;
+    
+  private:
+    static std::map<std::string, NetworkFunctionBase*> nameMap_;
+    uint32_t networkID_;
+    std::string name_;
+      
+};
+
+
+class _NetworkExport NetworkFunctionStatic: public NetworkFunctionBase {
+  public:
+    NetworkFunctionStatic(FunctorStatic* functor, const std::string& name, const NetworkFunctionPointer& p);
+    ~NetworkFunctionStatic();
+    
+    inline void call(){ (*this->functor_)(); }
+    inline void call(const MultiType& mt1){ (*this->functor_)(mt1); }
+    inline void call(const MultiType& mt1, const MultiType& mt2){ (*this->functor_)(mt1, mt2); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3){ (*this->functor_)(mt1, mt2, mt3); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4){ (*this->functor_)(mt1, mt2, mt3, mt4); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5){ (*this->functor_)(mt1, mt2, mt3, mt4, mt5); }
+    
+    virtual void setNetworkID( uint32_t id ){ NetworkFunctionBase::setNetworkID( id ); idMap_[id] = this; }
+    static inline NetworkFunctionStatic* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
+    static NetworkFunctionStatic* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
+    static NetworkFunctionStatic* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
+    
+  private:
+    static std::map<NetworkFunctionPointer, NetworkFunctionStatic*> functorMap_;
+    static std::map<uint32_t, NetworkFunctionStatic*> idMap_;
+    
+    FunctorStatic* functor_;
+    
+};
+
+
+class _NetworkExport NetworkMemberFunctionBase: public NetworkFunctionBase {
+  public:
+    NetworkMemberFunctionBase(const std::string& name, const NetworkFunctionPointer& p);
+    ~NetworkMemberFunctionBase();
+    
+    virtual void setNetworkID( uint32_t id ){ NetworkFunctionBase::setNetworkID( id ); idMap_[id] = this; }
+    static inline NetworkMemberFunctionBase* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
+    static NetworkMemberFunctionBase* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
+    static NetworkMemberFunctionBase* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
+    
+    // 
+    virtual void call(uint32_t objectID)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)=0;
+    
+  private:
+    static std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> functorMap_;
+    static std::map<uint32_t, NetworkMemberFunctionBase*> idMap_;
+};
+
+
+template <class T> class NetworkMemberFunction: public NetworkMemberFunctionBase {
+  public:
+    NetworkMemberFunction(FunctorMember<T>* functor, const std::string& name, const NetworkFunctionPointer& p);
+    ~NetworkMemberFunction();
+    
+    inline void call(uint32_t objectID)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)));
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+    { 
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4, mt5);
+    }
+    
+  private:
+    FunctorMember<T>* functor_;
+};
+
+template <class T> NetworkMemberFunction<T>::NetworkMemberFunction(FunctorMember<T>* functor, const std::string& name, const NetworkFunctionPointer& p):
+    NetworkMemberFunctionBase(name, p), functor_(functor)
+{
+}
+template <class T> NetworkMemberFunction<T>::~NetworkMemberFunction()
+{
+  delete this->functor_;
+}
+
+template<class T> inline void copyPtr( T ptr, NetworkFunctionPointer& destptr)
+{
+  if( sizeof(NetworkFunctionPointer)-sizeof(T) > 0)
+    memset((uint8_t*)&destptr + sizeof(T), 0, sizeof(NetworkFunctionPointer)-sizeof(T));
+  T p2 = ptr;
+  memcpy( &destptr, &p2, sizeof(T) );
+//   for(unsigned int i=0; i<(sizeof(T)-1/4)+1; i++)
+//     *((uint32_t*)destptr+i) = p2>>32*i;
+}
+
+template<class T> inline void* registerStaticNetworkFunctionFct( T ptr, const std::string& name )
+{
+  BOOST_STATIC_ASSERT( sizeof(T)<=sizeof(NetworkFunctionPointer) ); // if this fails your compiler uses bigger pointers for static functions than defined above
+  NetworkFunctionPointer destptr;
+  copyPtr( ptr, destptr );
+  new NetworkFunctionStatic( createFunctor(ptr), name, destptr );
+  return 0;
+}
+
+template<class T, class PT> inline void* registerMemberNetworkFunctionFct( PT ptr, const std::string& name )
+{
+  BOOST_STATIC_ASSERT( sizeof(PT)<=sizeof(NetworkFunctionPointer) ); // if this fails your compiler uses bigger pointers for a specific kind of member functions than defined above
+  NetworkFunctionPointer destptr;
+  copyPtr( ptr, destptr );
+  new NetworkMemberFunction<T>( createFunctor(ptr), name, destptr );
+  return 0;
+}
+
+#define registerStaticNetworkFunction( functionPointer ) \
+  static void* BOOST_PP_CAT( NETWORK_FUNCTION_, __LINE__ ) = registerStaticNetworkFunctionFct( functionPointer, #functionPointer );
+#define registerMemberNetworkFunction( class, function ) \
+  static void* BOOST_PP_CAT( NETWORK_FUNCTION_##class, __LINE__ ) = registerMemberNetworkFunctionFct<class>( &class::function, #class "_" #function);
+  // call it with functionPointer, clientID, args
+#define callStaticNetworkFunction( functionPointer, ...) \
+  { \
+    NetworkFunctionPointer p1; \
+    copyPtr( functionPointer, p1 ); \
+    FunctionCallManager::addCallStatic(NetworkFunctionStatic::getFunction(p1)->getNetworkID(), __VA_ARGS__); \
+  }
+  // call it with class, function, objectID, clientID, args
+#define callMemberNetworkFunction( class, function, objectID, ...) \
+  { \
+    NetworkFunctionPointer p1; \
+    copyPtr( &class::function, p1 ); \
+    FunctionCallManager::addCallMember(NetworkMemberFunctionBase::getFunction(p1)->getNetworkID(), objectID, __VA_ARGS__); \
+  }
+
+
+}
+
+#endif /* _NetworkFunction_H__ */
Index: code/trunk/src/libraries/network/NetworkPrecompiledHeaders.h
===================================================================
--- code/trunk/src/libraries/network/NetworkPrecompiledHeaders.h	(revision 5781)
+++ code/trunk/src/libraries/network/NetworkPrecompiledHeaders.h	(revision 5781)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the network library
+@details
+    Updated: 13. September 2009
+    Total Files: 28
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <cstring>  // 26
+#include <cassert>  // 24
+#include <string>   // 23
+#include <vector>   // 23
+#include <map>      // 23
+#include <fstream>  // 22
+#include <iostream> // 22
+#include <sstream>  // 22
+#include <set>      // 20
+
+#include "util/Debug.h"      // 20
+#include "util/TypeTraits.h" // 18
+
+#ifdef ORXONOX_COMPILER_MSVC
+
+#include <deque>    // 17
+#include <queue>    // 17
+#include <list>     // 16
+#include <cmath>    // 15
+
+#include <OgreMath.h>        // 15
+#include <OgreVector2.h>     // 15
+#include <OgreVector3.h>     // 15
+#include <OgreVector4.h>     // 15
+#include <OgreQuaternion.h>  // 15
+#include <OgreColourValue.h> // 15
+
+#include "util/mbool.h" // 11
+
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h> // 6, 3.1MB
+
+#endif /*ORXONOX_COMPILER_MSVC */
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: code/trunk/src/libraries/network/NetworkPrereqs.h
===================================================================
--- code/trunk/src/libraries/network/NetworkPrereqs.h	(revision 5781)
+++ code/trunk/src/libraries/network/NetworkPrereqs.h	(revision 5781)
@@ -0,0 +1,143 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+  @file
+  @brief Contains all the necessary forward declarations for all classes and structs.
+*/
+
+#ifndef _NetworkPrereqs_H__
+#define _NetworkPrereqs_H__
+
+#include "OrxonoxConfig.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined( NETWORK_STATIC_BUILD )
+#  ifdef NETWORK_SHARED_BUILD
+#    define _NetworkExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _NetworkExport
+#    else
+#      define _NetworkExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _NetworkExport  __attribute__ ((visibility("default")))
+#else
+#  define _NetworkExport
+#endif
+
+//-----------------------------------------------------------------------
+// Library global contants
+//-----------------------------------------------------------------------
+namespace orxonox
+{
+  static const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1);
+  static const unsigned int CLIENTID_UNKNOWN    = static_cast<unsigned int>(-2);
+  static const uint32_t     OBJECTID_UNKNOWN    = static_cast<uint32_t>(-1);
+}
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+// from ENet
+struct _ENetPeer;
+typedef _ENetPeer ENetPeer;
+struct _ENetPacket;
+typedef _ENetPacket ENetPacket;
+struct _ENetEvent;
+typedef _ENetEvent ENetEvent;
+struct _ENetHost;
+typedef _ENetHost ENetHost;
+struct _ENetAddress;
+typedef _ENetAddress ENetAddress;
+
+namespace orxonox
+{
+  class Client;
+  class ClientConnection;
+  class ClientConnectionListener;
+  class ClientFrameListener;
+  class ClientInformation;
+  class Connection;
+  class FunctionCallManager;
+  class GamestateClient;
+  class GamestateManager;
+  class GamestateHandler;
+  class NetworkCallbackBase;
+  template <class T> class NetworkCallback;
+  class NetworkCallbackManager;
+  class NetworkFunctionBase;
+  class NetworkFunctionStatic;
+  class NetworkMemberFunctionBase;
+  template <class T> class NetworkMemeberFunction;
+  struct NetworkFunctionPointer;
+  class Server;
+  class ServerConnection;
+  class ServerFrameListener;
+  class Synchronisable;
+  class SynchronisableVariableBase;
+  template <class T> class SynchronisableVariable;
+  template <class T> class SynchronisableVariableBidirectional;
+  struct ClientList;
+  struct PacketEnvelope;
+  struct QueueItem;
+  struct syncData;
+  class TrafficControl;
+  class obj;
+  class objInfo;
+
+  namespace packet
+  {
+    class Acknowledgement;
+    class Chat;
+    class ClassID;
+    class FunctionCalls;
+    class FunctionIDs;
+    class Gamestate;
+    class NetworkIDs;
+    class Packet;
+    class Welcome;
+
+    namespace PacketFlag
+    {
+      enum Value
+      {
+        Reliable   = 1,
+        Unsequence = 2,
+        NoAllocate = 4
+      };
+    }
+  }
+}
+
+#endif /* _NetworkPrereqs_H__ */
Index: code/trunk/src/libraries/network/Server.cc
===================================================================
--- code/trunk/src/libraries/network/Server.cc	(revision 5781)
+++ code/trunk/src/libraries/network/Server.cc	(revision 5781)
@@ -0,0 +1,376 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: Server
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "Server.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include <cassert>
+#include <string>
+
+#include "util/Debug.h"
+#include "core/Clock.h"
+#include "core/ObjectList.h"
+#include "core/Executor.h"
+#include "packet/Chat.h"
+#include "packet/ClassID.h"
+#include "packet/DeleteObjects.h"
+#include "packet/FunctionIDs.h"
+#include "packet/Gamestate.h"
+#include "packet/Welcome.h"
+#include "ChatListener.h"
+#include "ClientInformation.h"
+#include "FunctionCallManager.h"
+#include "GamestateManager.h"
+
+namespace orxonox
+{
+  const unsigned int MAX_FAILURES = 20;
+
+  /**
+  * Constructor for default values (bindaddress is set to ENET_HOST_ANY
+  *
+  */
+  Server::Server() {
+    this->timeSinceLastUpdate_=0;
+  }
+
+  Server::Server(int port){
+    this->setPort( port );
+    this->timeSinceLastUpdate_=0;
+  }
+
+  /**
+  * Constructor
+  * @param port Port to listen on
+  * @param bindAddress Address to listen on
+  */
+  Server::Server(int port, const std::string& bindAddress) {
+    this->setPort( port );
+    this->setBindAddress( bindAddress );
+    this->timeSinceLastUpdate_=0;
+  }
+
+  /**
+  * @brief Destructor
+  */
+  Server::~Server(){
+  }
+
+  /**
+  * This function opens the server by creating the listener thread
+  */
+  void Server::open() {
+    COUT(4) << "opening server" << endl;
+    this->openListener();
+    return;
+  }
+
+  /**
+  * This function closes the server
+  */
+  void Server::close() {
+    COUT(4) << "closing server" << endl;
+    this->disconnectClients();
+    this->closeListener();
+    return;
+  }
+
+  bool Server::processChat(const std::string& message, unsigned int playerID){
+    ClientInformation *temp = ClientInformation::getBegin();
+    packet::Chat *chat;
+    while(temp){
+      chat = new packet::Chat(message, playerID);
+      chat->setClientID(temp->getID());
+      if(!chat->send())
+        COUT(3) << "could not send Chat message to client ID: " << temp->getID() << std::endl;
+      temp = temp->next();
+    }
+//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
+    return true;
+  }
+
+
+  /**
+  * Run this function once every tick
+  * calls processQueue and updateGamestate
+  * @param time time since last tick
+  */
+  void Server::update(const Clock& time) {
+    // receive incoming packets
+    Connection::processQueue();
+    
+    if ( ClientInformation::hasClients() )
+    {
+      // process incoming gamestates
+      GamestateManager::processGamestates();
+      
+      // send function calls to clients
+      FunctionCallManager::sendCalls();
+      
+      //this steers our network frequency
+      timeSinceLastUpdate_+=time.getDeltaTime();
+      if(timeSinceLastUpdate_>=NETWORK_PERIOD)
+      {
+        timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
+        updateGamestate();
+      }
+      sendPackets(); // flush the enet queue
+    }
+  }
+
+  bool Server::queuePacket(ENetPacket *packet, int clientID){
+    return ServerConnection::addPacket(packet, clientID);
+  }
+  
+  /**
+   * @brief: returns ping time to client in milliseconds 
+   */
+  unsigned int Server::getPing(unsigned int clientID){
+    assert(ClientInformation::findClient(clientID));
+    return ClientInformation::findClient(clientID)->getRTT();
+  }
+
+  /**
+   * @brief: return packet loss ratio to client (scales from 0 to 1)
+   */
+  double Server::getPacketLoss(unsigned int clientID){
+    assert(ClientInformation::findClient(clientID));
+    return ClientInformation::findClient(clientID)->getPacketLoss();
+  }
+
+  /**
+  * takes a new snapshot of the gamestate and sends it to the clients
+  */
+  void Server::updateGamestate() {
+    if( ClientInformation::getBegin()==NULL )
+      //no client connected
+      return;
+    GamestateManager::update();
+    COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl;
+    //std::cout << "updated gamestate, sending it" << std::endl;
+    //if(clients->getGamestateID()!=GAMESTATEID_INITIAL)
+    sendGameState();
+    sendObjectDeletes();
+    COUT(5) << "Server: one sendGameState turn complete, repeat in next tick" << std::endl;
+    //std::cout << "sent gamestate" << std::endl;
+  }
+
+  bool Server::processPacket( ENetPacket *packet, ENetPeer *peer ){
+    packet::Packet *p = packet::Packet::createPacket(packet, peer);
+    return p->process();
+  }
+
+  /**
+  * sends the gamestate
+  */
+  bool Server::sendGameState() {
+//     COUT(5) << "Server: starting function sendGameState" << std::endl;
+//     ClientInformation *temp = ClientInformation::getBegin();
+//     bool added=false;
+//     while(temp != NULL){
+//       if( !(temp->getSynched()) ){
+//         COUT(5) << "Server: not sending gamestate" << std::endl;
+//         temp=temp->next();
+//         if(!temp)
+//           break;
+//         continue;
+//       }
+//       COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss() << std::endl;
+//       COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl;
+//       int cid = temp->getID(); //get client id
+//       packet::Gamestate *gs = GamestateManager::popGameState(cid);
+//       if(gs==NULL){
+//         COUT(2) << "Server: could not generate gamestate (NULL from compress)" << std::endl;
+//         temp = temp->next();
+//         continue;
+//       }
+//       //std::cout << "adding gamestate" << std::endl;
+//       gs->setClientID(cid);
+//       if ( !gs->send() ){
+//         COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
+//         temp->addFailure();
+//       }else
+//         temp->resetFailures();
+//       added=true;
+//       temp=temp->next();
+//       // gs gets automatically deleted by enet callback
+//     }
+    GamestateManager::sendGamestates();
+    return true;
+  }
+
+  bool Server::sendObjectDeletes(){
+    ClientInformation *temp = ClientInformation::getBegin();
+    if( temp == NULL )
+      //no client connected
+      return true;
+    packet::DeleteObjects *del = new packet::DeleteObjects();
+    if(!del->fetchIDs())
+      return true;  //everything ok (no deletes this tick)
+//     COUT(3) << "sending DeleteObjects" << std::endl;
+    while(temp != NULL){
+      if( !(temp->getSynched()) ){
+        COUT(5) << "Server: not sending gamestate" << std::endl;
+        temp=temp->next();
+        continue;
+      }
+      int cid = temp->getID(); //get client id
+      packet::DeleteObjects *cd = new packet::DeleteObjects(*del);
+      assert(cd);
+      cd->setClientID(cid);
+      if ( !cd->send() )
+        COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
+      temp=temp->next();
+      // gs gets automatically deleted by enet callback
+    }
+    delete del;
+    return true;
+  }
+
+
+  void Server::addClient(ENetEvent *event){
+    static unsigned int newid=1;
+
+    COUT(2) << "Server: adding client" << std::endl;
+    ClientInformation *temp = ClientInformation::insertBack(new ClientInformation);
+    if(!temp){
+      COUT(2) << "Server: could not add client" << std::endl;
+    }
+    temp->setID(newid);
+    temp->setPeer(event->peer);
+
+    // inform all the listeners
+    ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
+    while(listener){
+      listener->clientConnected(newid);
+      listener++;
+    }
+
+    ++newid;
+
+    COUT(3) << "Server: added client id: " << temp->getID() << std::endl;
+    createClient(temp->getID());
+}
+
+  bool Server::createClient(int clientID){
+    ClientInformation *temp = ClientInformation::findClient(clientID);
+    if(!temp){
+      COUT(2) << "Conn.Man. could not create client with id: " << clientID << std::endl;
+      return false;
+    }
+    COUT(5) << "Con.Man: creating client id: " << temp->getID() << std::endl;
+    
+    // synchronise class ids
+    syncClassid(temp->getID());
+    
+    // now synchronise functionIDs
+    packet::FunctionIDs *fIDs = new packet::FunctionIDs();
+    fIDs->setClientID(clientID);
+    bool b = fIDs->send();
+    assert(b);
+    
+    temp->setSynched(true);
+    COUT(4) << "sending welcome" << std::endl;
+    packet::Welcome *w = new packet::Welcome(temp->getID(), temp->getShipID());
+    w->setClientID(temp->getID());
+    b = w->send();
+    assert(b);
+    packet::Gamestate *g = new packet::Gamestate();
+    g->setClientID(temp->getID());
+    b = g->collectData(0,0x1);
+    if(!b)
+      return false; //no data for the client
+    b = g->compressData();
+    assert(b);
+    b = g->send();
+    assert(b);
+    return true;
+  }
+  
+  void Server::disconnectClient( ClientInformation *client ){
+    ServerConnection::disconnectClient( client );
+    GamestateManager::removeClient(client);
+// inform all the listeners
+    ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
+    while(listener){
+      listener->clientDisconnected(client->getID());
+      ++listener;
+    }
+    delete client; //remove client from list
+  }
+
+  bool Server::chat(const std::string& message){
+      return this->sendChat(message, Host::getPlayerID());
+  }
+
+  bool Server::broadcast(const std::string& message){
+      return this->sendChat(message, CLIENTID_UNKNOWN);
+  }
+
+  bool Server::sendChat(const std::string& message, unsigned int clientID){
+    ClientInformation *temp = ClientInformation::getBegin();
+    packet::Chat *chat;
+    while(temp){
+      chat = new packet::Chat(message, clientID);
+      chat->setClientID(temp->getID());
+      if(!chat->send())
+        COUT(3) << "could not send Chat message to client ID: " << temp->getID() << std::endl;
+      temp = temp->next();
+    }
+//    COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl;
+    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, clientID);
+
+    return true;
+  }
+
+  void Server::syncClassid(unsigned int clientID) {
+    int failures=0;
+    packet::ClassID *classid = new packet::ClassID();
+    classid->setClientID(clientID);
+    while(!classid->send() && failures < 10){
+      failures++;
+    }
+    assert(failures<10);
+    COUT(4) << "syncClassid:\tall synchClassID packets have been sent" << std::endl;
+  }
+
+}
Index: code/trunk/src/libraries/network/Server.h
===================================================================
--- code/trunk/src/libraries/network/Server.h	(revision 5781)
+++ code/trunk/src/libraries/network/Server.h	(revision 5781)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Server_H__
+#define _Server_H__
+
+#include "NetworkPrereqs.h"
+
+#include "core/CorePrereqs.h"
+#include "Host.h"
+#include "GamestateManager.h"
+#include "ServerConnection.h"
+
+namespace orxonox
+{
+
+  /**
+  * This class is the root class of the network module for a server.
+  * It implements all functions necessary for a Server
+  */
+  class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager{
+  public:
+    Server();
+    Server(int port);
+    Server(int port, const std::string& bindAddress);
+    ~Server();
+
+    void open();
+    void close();
+    bool processChat(const std::string& message, unsigned int playerID);
+    bool queuePacket(ENetPacket *packet, int clientID);
+    void update(const Clock& time);
+    unsigned int getPing(unsigned int clientID);
+    double getPacketLoss(unsigned int clientID);
+  protected:
+    void updateGamestate();
+  private:
+    virtual bool isServer_(){return true;}
+    unsigned int shipID(){return 0;}
+    unsigned int playerID(){return 0;}
+    
+    void addClient(ENetEvent *event);
+    bool createClient(int clientID);
+    void disconnectClient( ClientInformation *client);
+    bool processPacket( ENetPacket *packet, ENetPeer *peer );
+    bool sendGameState();
+    bool sendObjectDeletes();
+    virtual bool chat(const std::string& message);
+    virtual bool broadcast(const std::string& message);
+    bool sendChat(const std::string& message, unsigned int clientID);
+    void syncClassid(unsigned int clientID);
+
+    float timeSinceLastUpdate_;
+  };
+
+
+
+
+}
+
+#endif /* _Server_H__ */
Index: code/trunk/src/libraries/network/ServerConnection.cc
===================================================================
--- code/trunk/src/libraries/network/ServerConnection.cc	(revision 5781)
+++ code/trunk/src/libraries/network/ServerConnection.cc	(revision 5781)
@@ -0,0 +1,167 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ServerConnection.h"
+
+#include <cassert>
+#include <string>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+
+#include "util/Debug.h"
+#include "ClientInformation.h"
+
+namespace orxonox
+{
+
+  ServerConnection::ServerConnection():
+    bListening_(false)
+  {
+    this->bindAddress_ = new ENetAddress();
+    this->bindAddress_->host = ENET_HOST_ANY;
+    this->bindAddress_->port = NETWORK_PORT;
+  }
+
+  ServerConnection::~ServerConnection(){
+    if ( this->bListening_ )
+      closeListener();
+    delete this->bindAddress_;
+  }
+
+  void ServerConnection::setBindAddress( const std::string& bindAddress ) {
+    enet_address_set_host (this->bindAddress_, bindAddress.c_str());
+  }
+
+  void ServerConnection::setPort( unsigned int port ) {
+      this->bindAddress_->port = port;
+  }
+
+  bool ServerConnection::openListener() {
+    this->host_ = enet_host_create(this->bindAddress_, NETWORK_MAX_CONNECTIONS, 0, 0);
+    if ( this->host_ == NULL )
+      return false;
+    else
+      return true;
+  }
+
+  bool ServerConnection::closeListener() {
+    this->bListening_=false;
+    disconnectClients();
+    enet_host_destroy(this->host_);
+    return true;
+  }
+
+  bool ServerConnection::addPacket(ENetPacket *packet, unsigned int clientID) {
+    if ( clientID == CLIENTID_UNKNOWN )
+    {
+      return addPacketAll(packet);
+    }
+    else
+    {
+      ClientInformation *temp = ClientInformation::findClient(clientID);
+      if(!temp){
+        COUT(3) << "C.Man: addPacket findClient failed" << std::endl;
+        return false;
+      }
+      return Connection::addPacket(packet, temp->getPeer());
+    }
+  }
+
+  bool ServerConnection::addPacketAll(ENetPacket *packet) {
+    if ( !Connection::getInstance() )
+      return false;
+    enet_host_broadcast( Connection::getInstance()->getHost(), 0, packet);
+    return true;
+  }
+  
+  void ServerConnection::disconnectClient(ClientInformation *client)
+  {
+    Connection::disconnectPeer( client->getPeer() );
+    delete client;
+  }
+  
+  void ServerConnection::disconnectPeer( ENetEvent* event )
+  {
+    COUT(4) << "removing client from list" << std::endl;
+    ClientInformation *client = ClientInformation::findClient(&event->peer->address);
+    if(!client)
+      return;
+    else
+      ServerConnection::disconnectClient( client );
+  }
+  
+  void ServerConnection::disconnectClient(int clientID){
+    ClientInformation *client = ClientInformation::findClient(clientID);
+    if(client)
+      disconnectClient(client);
+  }
+
+  void ServerConnection::disconnectClients() {
+    ENetEvent event;
+    ClientInformation *temp = ClientInformation::getBegin();
+    while(temp!=0){
+      disconnectClient( temp );
+      temp = temp->next();
+    }
+    temp = ClientInformation::getBegin();
+    while( temp!=0 ){
+      if( service( &event ) )
+      {
+        switch (event.type)
+        {
+        case ENET_EVENT_TYPE_NONE: break;
+        case ENET_EVENT_TYPE_CONNECT: break;
+        case ENET_EVENT_TYPE_RECEIVE:
+          enet_packet_destroy(event.packet);
+          break;
+        case ENET_EVENT_TYPE_DISCONNECT:
+          if(ClientInformation::findClient(&(event.peer->address)))
+            delete ClientInformation::findClient(&(event.peer->address));
+          temp = ClientInformation::getBegin();
+          break;
+        }
+      }
+    }
+    return;
+  }
+
+
+  int ServerConnection::getClientID(ENetPeer* peer) {
+    return getClientID(&(peer->address));
+  }
+
+  int ServerConnection::getClientID(ENetAddress* address) {
+    return ClientInformation::findClient(address)->getID();
+  }
+
+  ENetPeer *ServerConnection::getClientPeer(int clientID) {
+    return ClientInformation::findClient(clientID)->getPeer();
+  }
+
+
+}
Index: code/trunk/src/libraries/network/ServerConnection.h
===================================================================
--- code/trunk/src/libraries/network/ServerConnection.h	(revision 5781)
+++ code/trunk/src/libraries/network/ServerConnection.h	(revision 5781)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: ServerConnection
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _ServerConnection_H__
+#define _ServerConnection_H__
+
+#include "NetworkPrereqs.h"
+#include "Connection.h"
+
+namespace orxonox
+{
+
+  class _NetworkExport ServerConnection : public Connection{
+  public:
+    ~ServerConnection();
+    
+    void setBindAddress( const std::string& bindAddress );
+    void setPort( unsigned int port );
+    
+    bool openListener();
+    bool closeListener();
+    static bool addPacket(ENetPacket *packet, unsigned int ID);
+    static bool addPacketAll(ENetPacket *packet);
+    virtual void disconnectClient(ClientInformation *client);
+    void disconnectPeer( ENetEvent* event );
+    void disconnectClient(int clientID);
+  protected:
+    ServerConnection();
+    void disconnectClients();
+
+  private:
+    int getClientID(ENetPeer* peer);
+    int getClientID(ENetAddress* address);
+    ENetPeer* getClientPeer(int clientID);
+
+    ENetAddress* bindAddress_;
+
+    bool bListening_;
+
+  };
+
+}
+
+#endif /* _ServerConnection_H__ */
Index: code/trunk/src/libraries/network/TODO
===================================================================
--- code/trunk/src/libraries/network/TODO	(revision 5781)
+++ code/trunk/src/libraries/network/TODO	(revision 5781)
@@ -0,0 +1,11 @@
+todo: 
+	test network functionality with paketloss/delay: http://www.linuxfoundation.org/en/Net:Netem#Packet_loss
+
+	minimize synchronisableHeader
+
+	!!! ensure that objects get synched, when newly created, even if not their tick
+
+	setvariable mode
+	objectmode
+	priorities (put into gamestatehandler)
+		manage delete object handling (only send deletes of acked objects)
Index: code/trunk/src/libraries/network/TrafficControl.cc
===================================================================
--- code/trunk/src/libraries/network/TrafficControl.cc	(revision 5781)
+++ code/trunk/src/libraries/network/TrafficControl.cc	(revision 5781)
@@ -0,0 +1,327 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TrafficControl.h"
+
+#include <cassert>
+#include <boost/bind.hpp>
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "synchronisable/Synchronisable.h"
+
+namespace orxonox {
+
+  static const unsigned int SCHED_PRIORITY_OFFSET = static_cast<unsigned int>(-1);
+
+  objInfo::objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched)
+  {
+    objID = ID; objCreatorID = creatorID; objCurGS = curGsID; objDiffGS = diffGsID; objSize = size; objValuePerm = prioperm; objValueSched = priosched;
+  }
+
+  objInfo::objInfo()
+  {
+    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objCurGS = GAMESTATEID_INITIAL; objDiffGS = objCurGS; objSize = 0; objValuePerm = 0; objValueSched = 0;
+  }
+
+
+
+  obj::obj()
+  {
+    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objSize = 0; objDataOffset = 0;
+  }
+  obj::obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset )
+  {
+    objID = ID; objCreatorID = creatorID; objSize = size; objDataOffset = offset;
+  }
+
+/**
+*Initializing protected members
+*/
+	TrafficControl *TrafficControl::instance_=0;
+
+	/**
+	* @brief Constructor: assures that only one reference will be created and sets the pointer
+	*/
+	TrafficControl::TrafficControl()
+	{
+    RegisterObject(TrafficControl);
+	  assert(instance_==0);
+	  instance_=this;
+    this->setConfigValues();
+	}
+
+	/**
+	* @brief Destructor: resets the instance pointer to 0
+	*/
+	TrafficControl::~TrafficControl()
+	{
+	  instance_=0;
+	}
+
+/**
+*Definition of public members
+*/
+
+  void TrafficControl::setConfigValues()
+  {
+    SetConfigValue ( bActive_, false );
+    SetConfigValue ( targetSize, 10000 );
+  }
+
+  /**
+  * sort-algorithm for sorting the objectlist after priorities
+  */
+  bool TrafficControl::prioritySort(uint32_t clientID, obj i, obj j)
+  {
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end());  //make sure the client exists in our list
+    assert(clientListPerm_[clientID].find(i.objID) != clientListPerm_[clientID].end()); // make sure the object i is in the client list
+    assert(clientListPerm_[clientID].find(j.objID) != clientListPerm_[clientID].end()); // make sure the object j is in the client list
+
+    int prio1 = clientListPerm_[clientID][i.objID].objValuePerm + clientListPerm_[clientID][i.objID].objValueSched;
+    int prio2 = clientListPerm_[clientID][j.objID].objValuePerm + clientListPerm_[clientID][j.objID].objValueSched;
+    return prio1 < prio2;
+  }
+
+  /**
+  * sort-algorithm for sorting the objectList after position in original data stream
+  */
+  bool TrafficControl::dataSort(obj i, obj j)
+  {
+    int pos1 = i.objDataOffset;
+    int pos2 = j.objDataOffset;
+    return pos1 < pos2;
+  }
+
+
+
+	void TrafficControl::processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj>& list)
+	{
+	  currentClientID=clientID;
+	  currentGamestateID=gamestateID;
+	  evaluateList(clientID, list);
+	  return;
+	}
+
+  TrafficControl *TrafficControl::getInstance()
+  {
+    assert(instance_);
+    return instance_;
+  }
+
+	void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
+	{
+    if ( !this->bActive_ )
+      return;
+	  std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
+
+    //assertions to make sure the maps already exist
+    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
+    assert( clientListTemp_[clientID].find(gamestateID) != clientListTemp_[clientID].end() );
+    
+    // shortcut for maps
+    std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+    std::map<unsigned int, std::list<obj> >& objectListTemp = clientListTemp_[clientID];
+
+    for(itvec = objectListTemp[gamestateID].begin(); itvec != objectListTemp[gamestateID].end(); itvec++)
+	  {
+      if(objectListPerm.find((*itvec).objID) != objectListPerm.end()) // check whether the obj already exists in our lists
+      {
+        objectListPerm[(*itvec).objID].objCurGS = gamestateID;
+        objectListPerm[(*itvec).objID].objValueSched = 0; //set scheduling value back
+      }
+      else
+      {
+        assert(0);
+        objectListPerm[(*itvec).objID].objCurGS = gamestateID;
+        objectListPerm[(*itvec).objID].objID = (*itvec).objID;
+        objectListPerm[(*itvec).objID].objCreatorID = (*itvec).objCreatorID;
+        objectListPerm[(*itvec).objID].objSize = (*itvec).objSize;
+      }
+	  }
+	   // remove temporary list (with acked objects) from the map
+    objectListTemp.erase( objectListTemp.find(gamestateID) );
+	}
+
+/**
+*Definition of private members
+*/
+
+	/**
+	*updateClientListPerm
+	*returns void
+	*/
+	void TrafficControl::insertinClientListPerm(unsigned int clientID, obj objinf)
+	{
+	  std::map<unsigned int,std::map<unsigned int, objInfo> >::iterator itperm;//iterator clientListPerm over clientIDs
+    unsigned int gsid=GAMESTATEID_INITIAL, gsdiff=currentGamestateID, prioperm=Synchronisable::getSynchronisable(objinf.objID)->getPriority(), priomom=0;
+    clientListPerm_[clientID][objinf.objID] = objInfo(objinf.objID, objinf.objCreatorID,gsid,gsdiff, objinf.objSize,prioperm,priomom);
+	}
+
+  /**
+  * updateClientListTemp
+  * takes the shortened list which will be sent to the gsmanager and puts the *info into clientListTemp
+  */
+  void TrafficControl::updateClientListTemp(std::list<obj>& list)
+  {
+    clientListTemp_[currentClientID][currentGamestateID] = list;
+  }
+
+  /**
+  *cut
+  *takes the current list that has to be returned to the gsmanager and shortens it in criteria of bandwidth of clientID(XY)
+  */
+  void TrafficControl::cut(std::list<obj>& list, unsigned int targetsize)
+  {
+    unsigned int size=0;
+    std::list<obj>::iterator itvec, ittemp;
+    assert(!list.empty());
+    for(itvec = list.begin(); itvec != list.end();)
+    {
+      assert( (*itvec).objSize < 1000);
+      if ( ( size + (*itvec).objSize ) < targetsize )
+      {
+        size += (*itvec).objSize;//objSize is given in bytes
+        ++itvec;
+      }
+      else
+      {
+        clientListPerm_[currentClientID][(*itvec).objID].objValueSched += SCHED_PRIORITY_OFFSET; // NOTE: SCHED_PRIORITY_OFFSET is negative
+        list.erase(itvec, list.end());
+        break;
+      }
+//       printList(list, currentClientID);
+    }
+    assert(!list.empty());
+  }
+
+
+	/**
+	*evaluateList evaluates whether new obj are there, whether there are things to be updatet and manipulates all this.
+	*/
+	void TrafficControl::evaluateList(unsigned int clientID, std::list<obj>& list)
+	{
+
+    if( bActive_ )
+    {
+      //now the sorting
+
+      //compare listToProcess vs clientListPerm
+      //if listToProcess contains new Objects, add them to clientListPerm
+      std::list<obj>::iterator itvec;
+    
+      std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+    
+      for( itvec=list.begin(); itvec != list.end(); itvec++)
+      {
+        if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
+        {
+        // we already have the object in our map
+        //obj bleibt in liste und permanente prio wird berechnet
+          objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
+          continue;//check next objId
+        }
+        else
+        {
+        // insert the object into clientListPerm
+          insertinClientListPerm(clientID,*itvec);
+          continue;//check next objId
+        }
+      }
+    //end compare listToProcess vs clientListPerm
+      
+      //sort copied list according to priorities
+      // use boost bind here because we need to pass a memberfunction to stl sort
+//       sort( list.begin(), list.end(), boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+      list.sort( boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+      
+//       list.sort(boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+
+      //now we check, that the creator of an object always exists on a client
+      std::list<obj>::iterator itcreator;
+      for(itvec = list.begin(); itvec != list.end(); itvec++)
+      {
+        fixCreatorDependencies(itvec, list, clientID);
+      }
+      //end of sorting
+      //now the cutting, work the same obj out in processobjectlist and copiedlist, compression rate muss noch festgelegt werden.
+//       printList(list, clientID);
+      cut(list, targetSize);
+      //now sort again after objDataOffset
+//       sort(list.begin(), list.end(), boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+      list.sort( boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+      
+      //diese Funktion updateClientList muss noch gemacht werden
+      updateClientListTemp(list);
+      //end of sorting
+    }
+  }
+
+  void TrafficControl::printList(std::list<obj>& list, unsigned int clientID)
+  {
+    std::list<obj>::iterator it;
+    COUT(0) << "=========== Objectlist ===========" << endl;
+    for( it=list.begin(); it!=list.end(); it++)
+      COUT(0) << "ObjectID: " << (*it).objID << " creatorID: " << (*it).objCreatorID << " Priority: " << clientListPerm_[clientID][(*it).objID].objValuePerm + clientListPerm_[clientID][(*it).objID].objValueSched << " size: " << (*it).objSize << endl;
+  }
+
+  void TrafficControl::fixCreatorDependencies(std::list<obj>::iterator it1, std::list<obj>& list, unsigned int clientID)
+  {
+    if ( (*it1).objCreatorID == OBJECTID_UNKNOWN )
+      return;
+    if( clientListPerm_[clientID][(*it1).objCreatorID].objCurGS != GAMESTATEID_INITIAL )
+      return;
+    std::list<obj>::iterator it2, it3=it1;
+    for( it2 = ++it3; it2 != list.end(); it2++ )
+    {
+      if( (*it2).objID == (*it1).objCreatorID )
+      {
+        it3 = list.insert(it1, *it2); //insert creator before it1
+        list.erase(it2);
+//         printList(list, clientID);
+        fixCreatorDependencies( it3, list, clientID );
+        break;
+      }
+    }
+  }
+
+  void TrafficControl::clientDisconnected(unsigned int clientID)
+  {
+    if( clientListPerm_.find(clientID) == clientListPerm_.end() )
+    {
+      assert(!this->bActive_);
+      return;
+    }
+    clientListTemp_.erase(clientListTemp_.find(clientID));
+    if( clientListTemp_.find(clientID) != clientListTemp_.end() )
+      clientListPerm_.erase(clientListPerm_.find(clientID));
+  }
+
+
+}//namespace network
Index: code/trunk/src/libraries/network/TrafficControl.h
===================================================================
--- code/trunk/src/libraries/network/TrafficControl.h	(revision 5781)
+++ code/trunk/src/libraries/network/TrafficControl.h	(revision 5781)
@@ -0,0 +1,142 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+
+ */
+#ifndef _TrafficControl_H__
+#define _TrafficControl_H__
+
+#include "NetworkPrereqs.h"
+
+#include <list>
+#include <map>
+#include "network/ClientConnectionListener.h"
+
+namespace orxonox {
+
+
+  /**
+   *a list of objects of this type will be given by the Server's Gamestate Manager
+   */
+  class objInfo
+  {
+    public:
+      uint32_t objID;
+      uint32_t objCreatorID;
+      uint32_t objCurGS;//current GameState ID
+      uint32_t objDiffGS;//difference between current and latest GameState
+      uint32_t objSize;
+      int objValuePerm;
+      int objValueSched;
+      objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched);
+      objInfo();
+  };
+
+/**
+   *a list of objects of this type will be given by the Server's Gamestate Manager
+ */
+  class obj
+  {
+    public:
+      uint32_t objID;
+      uint32_t objCreatorID;
+      uint32_t objSize;
+      uint32_t objDataOffset;
+      obj();
+      obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset );
+  };
+  
+
+
+
+/**
+*
+*/
+class TrafficControl : public ClientConnectionListener {
+  private:
+
+    /**
+    *permanent client list: contains client ids, object ids and objectInfos (in this order)
+    */
+    std::map<unsigned int, std::map<unsigned int, objInfo > > clientListPerm_;
+    //has to be created with constructor and then needs to be updated by evaluateList().
+
+    /**
+    *temporary client list: contains client ids, gamestate ids and object ids (in this order)
+    */
+    std::map<unsigned int, std::map<unsigned int, std::list<obj> > > clientListTemp_;
+
+    /**updateReferenceList
+    *currentGamestateID and currentClientID will be defined as soon as TrafficControl is being called by Server
+    */
+    unsigned int currentGamestateID;
+    unsigned int currentClientID;
+    unsigned int targetSize;
+    bool         bActive_;
+    
+    void insertinClientListPerm(unsigned int clientID, obj objinf);
+    
+    void cut(std::list<obj>& list, unsigned int targetsize);
+    void updateClientListTemp(std::list<obj>& list);//done
+    /**
+    *evaluates Data given (list) and produces result(->Data to be updated)
+    */
+    void evaluateList(unsigned int clientID, std::list<obj>& list);//done    
+    void ack(unsigned int clientID, unsigned int gamestateID);  // this function gets called when the server receives an ack from the client
+    
+    //ClientConnectionListener functions
+    virtual void clientConnected(unsigned int clientID){};
+    virtual void clientDisconnected(unsigned int clientID);
+
+ 
+  protected:
+    static TrafficControl *instance_;
+
+  public:
+    TrafficControl();
+    virtual ~TrafficControl();
+    /**
+    *is being used by GSManager from Server:
+    *list contains: ObjIds, CreatorIds, Size (in this order) from Client XY 
+    *Elements of list are accessed by *list[i]
+    *Elements of struct i are therefore: *list[i].objID
+    */
+    void setConfigValues();
+    static TrafficControl *getInstance();
+    void processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj>& list); //gets a pointer to the list (containing objectIDs) and sorts it
+    static void processAck(unsigned int clientID, unsigned int gamestateID)
+    { return instance_->ack(clientID, gamestateID); }
+    void deleteObject(unsigned int objectID);				// this function gets called when an object has been deleted (in order to clean up lists and maps)
+    
+    bool prioritySort(uint32_t clientID, obj i, obj j);
+    bool dataSort(obj i, obj j);
+    void printList(std::list<obj>& list, unsigned int clientID);
+    void fixCreatorDependencies(std::list<obj>::iterator it, std::list<obj>& list, unsigned int clientID);
+};
+
+}
+
+#endif /* _TrafficControl_H__ */
Index: code/trunk/src/libraries/network/packet/Acknowledgement.cc
===================================================================
--- code/trunk/src/libraries/network/packet/Acknowledgement.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Acknowledgement.cc	(revision 5781)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Acknowledgement.h"
+
+#include "util/Debug.h"
+#include "network/GamestateHandler.h"
+
+namespace orxonox {
+namespace packet {
+
+#define PACKET_FLAGS_ACK    0
+#define _PACKETID           0
+#define _ACKID              _PACKETID + sizeof(packet::Type::Value)
+  
+Acknowledgement::Acknowledgement( unsigned int id, unsigned int clientID )
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_ACK;
+  data_=new uint8_t[ getSize() ];
+  *(Type::Value *)(data_ + _PACKETID ) = Type::Acknowledgement;
+  *(uint32_t *)(data_ + _ACKID ) = id;
+  clientID_=clientID;
+}
+
+Acknowledgement::Acknowledgement( uint8_t *data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+Acknowledgement::~Acknowledgement()
+{
+}
+
+unsigned int Acknowledgement::getSize() const{
+  return _ACKID + sizeof(uint32_t);
+}
+
+bool Acknowledgement::process(){
+  COUT(5) << "processing ACK with ID: " << getAckID() << endl;
+  bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
+  delete this;
+  return b;
+}
+
+unsigned int Acknowledgement::getAckID(){
+  return *(uint32_t *)(data_ + _ACKID);
+}
+
+} //namespace packet
+} //namespace orxonox
Index: code/trunk/src/libraries/network/packet/Acknowledgement.h
===================================================================
--- code/trunk/src/libraries/network/packet/Acknowledgement.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Acknowledgement.h	(revision 5781)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Acknowledgement_H__
+#define _Acknowledgement_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+const unsigned int ACKID_NACK = 0;
+namespace packet {
+/**
+	@author
+*/
+class _NetworkExport Acknowledgement : public Packet
+{
+public:
+  Acknowledgement( unsigned int id, unsigned int clientID );
+  Acknowledgement( uint8_t* data, unsigned int clientID );
+  ~Acknowledgement();
+
+  inline unsigned int getSize() const;
+  bool process();
+
+  unsigned int getAckID();
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _Acknowledgement_H__ */
Index: code/trunk/src/libraries/network/packet/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/network/packet/CMakeLists.txt	(revision 5781)
+++ code/trunk/src/libraries/network/packet/CMakeLists.txt	(revision 5781)
@@ -0,0 +1,24 @@
+ADD_SOURCE_FILES(NETWORK_SRC_FILES
+  Acknowledgement.cc
+  Chat.cc
+  ClassID.cc
+  DeleteObjects.cc
+  FunctionIDs.cc
+  FunctionCalls.cc
+  Gamestate.cc
+  Packet.cc
+  Welcome.cc
+)
+
+ADD_SOURCE_FILES(NETWORK_HDR_FILES
+  Acknowledgement.h
+  Chat.cc
+  Chat.h
+  ClassID.h
+  DeleteObjects.h
+  FunctionCalls.h
+  FunctionIDs.h
+  Gamestate.h
+  Packet.h
+  Welcome.h
+)
Index: code/trunk/src/libraries/network/packet/Chat.cc
===================================================================
--- code/trunk/src/libraries/network/packet/Chat.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Chat.cc	(revision 5781)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Chat.h"
+
+#include <cstring>
+#include <string>
+#include "network/Host.h"
+
+namespace orxonox {
+namespace packet {
+  
+#define   PACKET_FLAGS_CHAT PacketFlag::Reliable
+#define   _PACKETID         0
+const int _PLAYERID     =   _PACKETID + sizeof(Type::Value);
+#define   _MESSAGELENGTH    _PLAYERID + sizeof(uint32_t)
+#define   _MESSAGE          _MESSAGELENGTH + sizeof(uint32_t)
+
+Chat::Chat( const std::string& message, unsigned int playerID )
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_CHAT;
+  messageLength_ = message.length()+1;
+  data_=new unsigned char[ getSize() ];
+  *(Type::Value *)(data_ + _PACKETID ) = Type::Chat;
+  *(unsigned int *)(data_ + _PLAYERID ) = playerID;
+  *(unsigned int *)(data_ + _MESSAGELENGTH ) = messageLength_;
+  memcpy( data_+_MESSAGE, static_cast<void*>(const_cast<char*>(message.c_str())), messageLength_ );
+}
+
+Chat::Chat( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+  messageLength_ = *(uint32_t *)(data + _MESSAGELENGTH );
+}
+
+Chat::~Chat()
+{
+}
+
+unsigned int Chat::getSize() const{
+  return _MESSAGE + messageLength_;
+}
+
+bool Chat::process(){
+  bool b = Host::incomingChat(std::string((const char*)data_+_MESSAGE), *(uint32_t *)(data_+_PLAYERID));
+  delete this;
+  return b;
+}
+
+unsigned char *Chat::getMessage(){
+  return data_ + _MESSAGE;
+}
+
+} //namespace packet
+} //namespace orxonox
Index: code/trunk/src/libraries/network/packet/Chat.h
===================================================================
--- code/trunk/src/libraries/network/packet/Chat.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Chat.h	(revision 5781)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_Chat_H__
+#define _NETWORK_Chat_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+/**
+	@author
+*/
+class _NetworkExport Chat : public Packet
+{
+public:
+  Chat( const std::string& message, unsigned int playerID );
+  Chat( uint8_t* data, unsigned int clientID );
+  ~Chat();
+
+  inline unsigned int getSize() const;
+  bool process();
+
+  unsigned int getMessageLength(){ return messageLength_; };
+  unsigned char *getMessage();
+private:
+  uint32_t messageLength_;
+  unsigned int clientID_;
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _NETWORK_Chat_H__ */
Index: code/trunk/src/libraries/network/packet/ClassID.cc
===================================================================
--- code/trunk/src/libraries/network/packet/ClassID.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/ClassID.cc	(revision 5781)
@@ -0,0 +1,158 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ClassID.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <queue>
+#include <string>
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox {
+namespace packet {
+
+
+#define PACKET_FLAGS_CLASSID  PacketFlag::Reliable
+#define _PACKETID             0
+
+
+ClassID::ClassID( ) : Packet(){
+  Identifier *id;
+  std::string classname;
+  unsigned int nrOfClasses=0; 
+  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nrofclasses
+  uint32_t network_id;
+  flags_ = flags_ | PACKET_FLAGS_CLASSID;
+  std::queue<std::pair<uint32_t, std::string> > tempQueue;
+  
+  //calculate total needed size (for all strings and integers)
+  std::map<std::string, Identifier*>::const_iterator it = Factory::getFactoryMapBegin();
+  for(;it != Factory::getFactoryMapEnd();++it){
+    id = (*it).second;
+    if(id == NULL)
+      continue;
+    classname = id->getName();
+    network_id = id->getNetworkID();
+    if(network_id==0)
+      COUT(3) << "we got a null class id: " << id->getName() << std::endl;
+    // now push the network id and the classname to the stack
+    tempQueue.push( std::pair<unsigned int, std::string>(network_id, classname) );
+    ++nrOfClasses;
+    packetSize += (classname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t);
+  }
+  
+  this->data_=new uint8_t[ packetSize ];
+  //set the appropriate packet id
+  assert(this->data_);
+  *(Type::Value *)(this->data_ + _PACKETID ) = Type::ClassID;
+  
+  uint8_t *temp=data_+sizeof(uint32_t);
+  // save the number of all classes
+  *(uint32_t*)temp = nrOfClasses;
+  temp += sizeof(uint32_t);
+  
+  // now save all classids and classnames
+  std::pair<uint32_t, std::string> tempPair;
+  while( !tempQueue.empty() ){
+    tempPair = tempQueue.front();
+    tempQueue.pop();
+    *(uint32_t*)temp = tempPair.first;
+    *(uint32_t*)(temp+sizeof(uint32_t)) = tempPair.second.size()+1;
+    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
+    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
+  }
+  
+  COUT(5) << "classid packetSize is " << packetSize << endl;
+  
+}
+
+ClassID::ClassID( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+ClassID::~ClassID()
+{
+}
+
+uint32_t ClassID::getSize() const{
+  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
+  uint32_t totalsize = sizeof(uint32_t); // packet identification
+  uint32_t nrOfClasses = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  totalsize += sizeof(uint32_t); // storage size for nr of all classes
+  
+  for(unsigned int i=0; i<nrOfClasses; i++){
+    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
+  }
+  return totalsize;
+}
+
+
+bool ClassID::process(){
+  int nrOfClasses;
+  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
+  uint32_t networkID;
+  uint32_t stringsize;
+  unsigned char *classname;
+  
+  
+  //clean the map of network ids
+  Factory::cleanNetworkIDs();
+  
+  COUT(4) << "=== processing classids: " << endl;
+  std::pair<uint32_t, std::string> tempPair;
+  Identifier *id;
+  // read the total number of classes
+  nrOfClasses = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  
+  for( int i=0; i<nrOfClasses; i++){
+    networkID = *(uint32_t*)temp;
+    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
+    classname = temp+2*sizeof(uint32_t);
+    id=ClassByString( std::string((const char*)classname) );
+    COUT(3) << "processing classid: " << networkID << " name: " << classname << " id: " << id << std::endl;
+    if(id==NULL){
+      COUT(0) << "Recieved a bad classname" << endl;
+      abort();
+    }
+    id->setNetworkID( networkID );
+    temp += 2*sizeof(uint32_t) + stringsize;
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: code/trunk/src/libraries/network/packet/ClassID.h
===================================================================
--- code/trunk/src/libraries/network/packet/ClassID.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/ClassID.h	(revision 5781)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_ClassID_H__
+#define _NETWORK_ClassID_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+  
+/**
+	@author
+*/
+class _NetworkExport ClassID : public Packet
+{
+public:
+  ClassID( );
+  ClassID( uint8_t* data, unsigned int clientID );
+  ~ClassID();
+
+  uint32_t getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _NETWORK_ClassID_H__ */
Index: code/trunk/src/libraries/network/packet/DeleteObjects.cc
===================================================================
--- code/trunk/src/libraries/network/packet/DeleteObjects.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/DeleteObjects.cc	(revision 5781)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "DeleteObjects.h"
+
+#include <cassert>
+#include "util/Debug.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox {
+namespace packet {
+
+#define PACKET_FLAG_DELETE  PacketFlag::Reliable
+#define _PACKETID           0
+#define _QUANTITY           _PACKETID + sizeof(Type::Value)
+#define _OBJECTIDS          _QUANTITY + sizeof(uint32_t)
+  
+DeleteObjects::DeleteObjects()
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAG_DELETE;
+}
+
+DeleteObjects::DeleteObjects( uint8_t *data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+DeleteObjects::~DeleteObjects()
+{
+}
+
+bool DeleteObjects::fetchIDs(){
+  unsigned int number = Synchronisable::getNumberOfDeletedObject();
+  if(number==0)
+    return false;
+  COUT(4) << "sending DeleteObjects: ";
+  unsigned int size = sizeof(Type::Value) + sizeof(uint32_t)*(number+1);
+  data_ = new uint8_t[size];
+  uint8_t *tdata = data_;
+  *reinterpret_cast<Type::Value*>(tdata) = Type::DeleteObjects;
+  tdata += sizeof(Type::Value);
+  *(uint32_t *)tdata = number;
+  tdata += sizeof(uint32_t);
+  for(unsigned int i=0; i<number; i++){
+    unsigned int temp = Synchronisable::popDeletedObject();
+//     assert(temp<10000); //ugly hack
+    *reinterpret_cast<uint32_t*>(tdata) = temp;
+    COUT(4) << temp << " ";
+    tdata += sizeof(uint32_t);
+  }
+  COUT(4) << std::endl;
+  return true;
+}
+
+unsigned int DeleteObjects::getSize() const{
+  assert(data_);
+  return _OBJECTIDS + *(uint32_t*)(data_+_QUANTITY)*sizeof(uint32_t);
+}
+
+bool DeleteObjects::process(){
+  for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){
+    COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
+    Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+} //namespace orxonox
Index: code/trunk/src/libraries/network/packet/DeleteObjects.h
===================================================================
--- code/trunk/src/libraries/network/packet/DeleteObjects.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/DeleteObjects.h	(revision 5781)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef _DeleteObjects_H__
+#define _DeleteObjects_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+/**
+	@author
+*/
+class _NetworkExport DeleteObjects : public Packet
+{
+public:
+  DeleteObjects( );
+  DeleteObjects( uint8_t* data, unsigned int clientID );
+  ~DeleteObjects();
+
+  bool fetchIDs();
+
+  inline unsigned int getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _DeleteObjects_H__ */
Index: code/trunk/src/libraries/network/packet/FunctionCalls.cc
===================================================================
--- code/trunk/src/libraries/network/packet/FunctionCalls.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/FunctionCalls.cc	(revision 5781)
@@ -0,0 +1,321 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionCalls.h"
+
+#include <cassert>
+#include <cstring>
+#include "util/MultiType.h"
+#include "network/NetworkFunction.h"
+
+namespace orxonox {
+namespace packet {
+  
+#define   PACKET_FLAGS_FUNCTIONCALLS PacketFlag::Reliable
+#define   _PACKETID         0
+const unsigned int FUNCTIONCALLS_MEM_ALLOCATION = 1000;
+    
+FunctionCalls::FunctionCalls()
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_FUNCTIONCALLS;
+  currentSize_ = 2*sizeof(uint32_t); // for packetid and nrOfCalls
+  nrOfCalls_ = 0;
+  currentMemBlocks_ = 1;
+  data_=new uint8_t[ FUNCTIONCALLS_MEM_ALLOCATION ];
+  *(Type::Value *)(data_ + _PACKETID ) = Type::FunctionCalls;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = 0; // set nrOfCalls to 0
+}
+
+FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+FunctionCalls::~FunctionCalls()
+{
+}
+
+
+bool FunctionCalls::process(){
+  assert(isDataENetAllocated());
+  uint8_t* temp = data_+sizeof(uint32_t); //skip packetid
+  this->nrOfCalls_ = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  for( unsigned int i = 0; i<this->nrOfCalls_; i++ )
+  {
+    uint32_t functionID = *(uint32_t*)temp;
+    bool isStatic = *(uint8_t*)(temp+sizeof(uint32_t));
+    if( isStatic )
+    {
+      MultiType mt1, mt2, mt3, mt4, mt5;
+      NetworkFunctionStatic *fct = NetworkFunctionStatic::getFunction( functionID );
+      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
+      temp+=2*sizeof(uint32_t)+sizeof(uint8_t);
+      switch(nrOfArguments)
+      {
+        case 0:
+          fct->call();
+          break;
+        case 1:
+          mt1.importData(temp);
+          fct->call(mt1);
+          break;
+        case 2:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          fct->call(mt1, mt2);
+          break;
+        case 3:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          fct->call(mt1, mt2, mt3);
+          break;
+        case 4:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          fct->call(mt1, mt2, mt3, mt4);
+          break;
+        case 5:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          mt5.importData(temp);
+          fct->call(mt1, mt2, mt3, mt4, mt5);
+          break;
+        default:
+          assert(0);
+      }
+    }
+    else // not a static function, so also handle the objectID
+    {
+      MultiType mt1, mt2, mt3, mt4, mt5;
+      NetworkMemberFunctionBase *fct = NetworkMemberFunctionBase::getFunction( functionID );
+      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
+      uint32_t objectID = *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t));
+      temp+=3*sizeof(uint32_t)+sizeof(uint8_t);
+      switch(nrOfArguments)
+      {
+        case 0:
+          fct->call(objectID);
+          break;
+        case 1:
+          mt1.importData(temp);
+          fct->call(objectID, mt1);
+          break;
+        case 2:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          fct->call(objectID, mt1, mt2);
+          break;
+        case 3:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3);
+          break;
+        case 4:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3, mt4);
+          break;
+        case 5:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          mt5.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3, mt4, mt5);
+          break;
+        default:
+          assert(0);
+          break;
+      }
+    }
+  }
+  delete this;
+  return true;
+}
+
+void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+  assert(!isDataENetAllocated());
+  
+  // first determine the size that has to be reserved for this call
+  uint32_t callsize = 2*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and for bool isStatic
+  uint32_t nrOfArguments = 0;
+  if(mt1)
+  {
+    nrOfArguments++;
+    callsize += mt1->getNetworkSize();
+    if(mt2)
+    {
+      nrOfArguments++;
+      callsize += mt2->getNetworkSize();
+      if(mt3)
+      {
+        nrOfArguments++;
+        callsize += mt3->getNetworkSize();
+        if(mt4)
+        {
+          nrOfArguments++;
+          callsize += mt4->getNetworkSize();
+          if(mt5)
+          {
+            nrOfArguments++;
+            callsize += mt5->getNetworkSize();
+          }
+        }
+      }
+    }
+  }
+  
+  // now allocated mem if neccessary
+  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
+  {
+    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
+    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
+    memcpy( temp, data_, currentSize_ );
+    delete[] data_;
+    data_ = temp;
+  }
+  
+  // now serialise the mt values and copy the function id and isStatic
+  uint8_t* temp = data_+currentSize_;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
+  *(uint32_t*)temp = networkID;
+  *(uint8_t*)(temp+sizeof(uint32_t)) = true;
+  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
+  temp += 2*sizeof(uint32_t)+sizeof(uint8_t);
+  if(mt1)
+  {
+    mt1->exportData( temp ); //temp gets automatically increased
+    if(mt2)
+    {
+      mt2->exportData( temp ); //temp gets automatically increased
+      if(mt3)
+      {
+        mt3->exportData( temp ); //temp gets automatically increased
+        if(mt4)
+        {
+          mt4->exportData( temp ); //temp gets automatically increased
+          if(mt5)
+          {
+            mt5->exportData( temp ); //temp gets automatically increased
+          }
+        }
+      }
+    }
+  }
+  //currentSize_ += callsize;
+  currentSize_ = temp-data_;
+  
+}
+
+void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+  assert(!isDataENetAllocated());
+  
+  // first determine the size that has to be reserved for this call
+  uint32_t callsize = 3*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and the objectID
+  uint32_t nrOfArguments = 0;
+  if(mt1)
+  {
+    nrOfArguments++;
+    callsize += mt1->getNetworkSize();
+    if(mt2)
+    {
+      nrOfArguments++;
+      callsize += mt2->getNetworkSize();
+      if(mt3)
+      {
+        nrOfArguments++;
+        callsize += mt3->getNetworkSize();
+        if(mt4)
+        {
+          nrOfArguments++;
+          callsize += mt4->getNetworkSize();
+          if(mt5)
+          {
+            nrOfArguments++;
+            callsize += mt5->getNetworkSize();
+          }
+        }
+      }
+    }
+  }
+  
+  // now allocated mem if neccessary
+  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
+  {
+    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
+    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
+    memcpy( temp, data_, currentSize_ );
+    delete[] data_;
+    data_ = temp;
+  }
+  
+  // now serialise the mt values and copy the function id
+  uint8_t* temp = data_+currentSize_;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
+  *(uint32_t*)temp = networkID;
+  *(uint8_t*)(temp+sizeof(uint32_t)) = false;
+  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
+  *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t)) = objectID;
+  temp += 3*sizeof(uint32_t)+sizeof(uint8_t);
+  if(mt1)
+  {
+    mt1->exportData( temp ); //temp gets automatically increased
+    if(mt2)
+    {
+      mt2->exportData( temp ); //temp gets automatically increased
+      if(mt3)
+      {
+        mt3->exportData( temp ); //temp gets automatically increased
+        if(mt4)
+        {
+          mt4->exportData( temp ); //temp gets automatically increased
+          if(mt5)
+          {
+            mt5->exportData( temp ); //temp gets automatically increased
+          }
+        }
+      }
+    }
+  }
+  currentSize_ += callsize;
+  
+}
+
+
+} //namespace packet
+} //namespace orxonox
Index: code/trunk/src/libraries/network/packet/FunctionCalls.h
===================================================================
--- code/trunk/src/libraries/network/packet/FunctionCalls.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/FunctionCalls.h	(revision 5781)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FunctionCalls_H__
+#define _FunctionCalls_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include "util/UtilPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+
+namespace packet {
+/**
+	@author
+*/
+
+
+class _NetworkExport FunctionCalls : public Packet
+{
+public:
+  FunctionCalls();
+  FunctionCalls( uint8_t* data, unsigned int clientID );
+  ~FunctionCalls();
+
+  inline unsigned int getSize() const
+    { assert(!this->isDataENetAllocated()); return currentSize_; }
+  bool process();
+
+  void addCallStatic( uint32_t networkID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
+  void addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
+private:
+  uint32_t nrOfCalls_;
+  unsigned int clientID_;
+  uint32_t currentSize_;
+  uint32_t currentMemBlocks_; // this saves the number of memory blocks (of size FUNCTIONCALLS_MEM_ALLOCATION) allocated
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _FunctionCalls_H__ */
Index: code/trunk/src/libraries/network/packet/FunctionIDs.cc
===================================================================
--- code/trunk/src/libraries/network/packet/FunctionIDs.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/FunctionIDs.cc	(revision 5781)
@@ -0,0 +1,144 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionIDs.h"
+
+#include <cassert>
+#include <cstring>
+#include <queue>
+#include <string>
+
+#include "util/Debug.h"
+#include "core/ObjectList.h"
+#include "network/NetworkFunction.h"
+
+namespace orxonox {
+namespace packet {
+
+
+#define PACKET_FLAGS_FUNCTIONIDS  PacketFlag::Reliable
+#define _PACKETID                 0
+
+
+FunctionIDs::FunctionIDs( ) : Packet(){
+  std::string functionname;
+  unsigned int nrOfFunctions=0; 
+  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nroffunctions
+  uint32_t networkID;
+  flags_ = flags_ | PACKET_FLAGS_FUNCTIONIDS;
+  std::queue<std::pair<uint32_t, std::string> > tempQueue;
+  
+  //calculate total needed size (for all strings and integers)
+  ObjectList<NetworkFunctionBase>::iterator it;
+  for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it){
+    functionname = it->getName();
+    networkID = it->getNetworkID();
+    // now push the network id and the classname to the stack
+    tempQueue.push( std::pair<unsigned int, std::string>(networkID, functionname) );
+    ++nrOfFunctions;
+    packetSize += (functionname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t); // reserver size for the functionname string, the functionname length and the networkID
+  }
+  
+  this->data_=new uint8_t[ packetSize ];
+  //set the appropriate packet id
+  assert(this->data_);
+  *(Type::Value *)(this->data_ + _PACKETID ) = Type::FunctionIDs;
+  
+  uint8_t *temp=data_+sizeof(uint32_t);
+  // save the number of all classes
+  *(uint32_t*)temp = nrOfFunctions;
+  temp += sizeof(uint32_t);
+  
+  // now save all classids and classnames
+  std::pair<uint32_t, std::string> tempPair;
+  while( !tempQueue.empty() ){
+    tempPair = tempQueue.front();
+    tempQueue.pop();
+    *(uint32_t*)temp = tempPair.first;
+    *(uint32_t*)(temp+sizeof(uint32_t)) = tempPair.second.size()+1;
+    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
+    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
+  }
+  
+  COUT(5) << "FunctionIDs packetSize is " << packetSize << endl;
+  
+}
+
+FunctionIDs::FunctionIDs( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+FunctionIDs::~FunctionIDs()
+{
+}
+
+uint32_t FunctionIDs::getSize() const{
+  assert(this->data_);
+  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
+  uint32_t totalsize = sizeof(uint32_t); // data size
+  uint32_t nrOfFunctions = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  totalsize += sizeof(uint32_t); // storage size for nr of all classes
+  
+  for(unsigned int i=0; i<nrOfFunctions; i++){
+    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t)); // for each network function add size for id, sizeof(string) and length of string itself to totalsize
+    temp += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
+  }
+  return totalsize;
+}
+
+
+bool FunctionIDs::process(){
+  int nrOfFunctions;
+  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
+  uint32_t networkID;
+  uint32_t stringsize;
+  unsigned char *functionname;
+  
+  COUT(4) << "=== processing functionids: " << endl;
+  std::pair<uint32_t, std::string> tempPair;
+  // read the total number of classes
+  nrOfFunctions = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  
+  for( int i=0; i<nrOfFunctions; i++){
+    networkID = *(uint32_t*)temp;
+    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
+    functionname = temp+2*sizeof(uint32_t);
+    COUT(3) << "processing functionid: " << networkID << " name: " << functionname << std::endl;
+    NetworkFunctionBase::setNetworkID((const char*)functionname, networkID);
+    temp += 2*sizeof(uint32_t) + stringsize;
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: code/trunk/src/libraries/network/packet/FunctionIDs.h
===================================================================
--- code/trunk/src/libraries/network/packet/FunctionIDs.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/FunctionIDs.h	(revision 5781)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FunctionIDs_H__
+#define _FunctionIDs_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+  
+/**
+	@author
+*/
+class _NetworkExport FunctionIDs : public Packet
+{
+public:
+  FunctionIDs( );
+  FunctionIDs( uint8_t* data, unsigned int clientID );
+  ~FunctionIDs();
+
+  uint32_t getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _FunctionIDs_H__ */
Index: code/trunk/src/libraries/network/packet/Gamestate.cc
===================================================================
--- code/trunk/src/libraries/network/packet/Gamestate.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Gamestate.cc	(revision 5781)
@@ -0,0 +1,622 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Gamestate.h"
+
+#include <zlib.h>
+
+#include "util/Debug.h"
+#include "core/GameMode.h"
+#include "core/ObjectList.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "network/GamestateHandler.h"
+
+namespace orxonox {
+
+namespace packet {
+
+#define GAMESTATE_START(data) (data + GamestateHeader::getSize())
+
+#define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
+
+
+Gamestate::Gamestate()
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = 0;
+}
+
+Gamestate::Gamestate(uint8_t *data, unsigned int clientID):
+    Packet(data, clientID)
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = new GamestateHeader(data_);
+}
+
+Gamestate::Gamestate(uint8_t *data)
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  data_=data;
+  header_ = new GamestateHeader(data_);
+}
+
+Gamestate::Gamestate(const Gamestate& g) :
+    Packet( *(Packet*)&g )
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = new GamestateHeader(data_);
+}
+
+
+Gamestate::~Gamestate()
+{
+  if( header_ )
+    delete header_;
+}
+
+bool Gamestate::collectData(int id, uint8_t mode)
+{
+  assert(this->header_==0); // make sure the header didn't exist before
+  uint32_t tempsize=0, currentsize=0;
+  assert(data_==0);
+  uint32_t size = calcGamestateSize(id, mode);
+
+  COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
+  if(size==0)
+    return false;
+  data_ = new uint8_t[size + GamestateHeader::getSize()];
+  if(!data_){
+    COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
+    return false;
+  }
+  
+  // create the header object
+  assert( header_ == 0 );
+  header_ = new GamestateHeader(data_);
+
+  //start collect data synchronisable by synchronisable
+  uint8_t *mem=data_;
+  mem += GamestateHeader::getSize();
+  ObjectList<Synchronisable>::iterator it;
+  for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+    
+//     tempsize=it->getSize(id, mode);
+
+    tempsize = it->getData(mem, id, mode);
+    if ( tempsize != 0 )
+      dataVector_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
+    
+#ifndef NDEBUG
+    if(currentsize+tempsize > size){
+      assert(0); // if we don't use multithreading this part shouldn't be neccessary
+      // start allocate additional memory
+      COUT(3) << "G.St.Man: need additional memory" << std::endl;
+      ObjectList<Synchronisable>::iterator temp = it;
+      uint32_t addsize=tempsize;
+      while(++temp)
+        addsize+=temp->getSize(id, mode);
+      data_ = (uint8_t *)realloc(data_, GamestateHeader::getSize() + currentsize + addsize);
+      if(!data_)
+        return false;
+      size = currentsize+addsize;
+    }// stop allocate additional memory
+#endif
+//     if(!it->getData(mem, id, mode))
+//       return false; // mem pointer gets automatically increased because of call by reference
+    // increase size counter by size of current synchronisable
+    currentsize+=tempsize;
+  }
+
+
+  //start write gamestate header
+  header_->setDataSize( currentsize );
+  header_->setID( id );
+  header_->setBaseID( GAMESTATEID_INITIAL );
+  header_->setDiffed( false );
+  header_->setComplete( true );
+  header_->setCompressed( false );
+  //stop write gamestate header
+
+  COUT(5) << "G.ST.Man: Gamestate size: " << currentsize << std::endl;
+  COUT(5) << "G.ST.Man: 'estimated' (and corrected) Gamestate size: " << size << std::endl;
+  return true;
+}
+
+bool Gamestate::spreadData(uint8_t mode)
+{
+  COUT(4) << "processing gamestate with id " << header_->getID() << endl;
+  assert(data_);
+  assert(!header_->isCompressed());
+  assert(!header_->isDiffed());
+  uint8_t *mem=data_+GamestateHeader::getSize();
+  Synchronisable *s;
+
+  // update the data of the objects we received
+  while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){
+    SynchronisableHeader objectheader(mem);
+
+    s = Synchronisable::getSynchronisable( objectheader.getObjectID() );
+    if(!s)
+    {
+      if (!GameMode::isMaster())
+      {
+        Synchronisable::fabricate(mem, mode);
+      }
+      else
+      {
+        mem += objectheader.getDataSize();
+      }
+    }
+    else
+    {
+      bool b = s->updateData(mem, mode);
+      assert(b);
+    }
+  }
+   // In debug mode, check first, whether there are no duplicate objectIDs
+#ifndef NDEBUG
+  if(this->getID()%1000==0){
+    std::list<uint32_t> v1;
+    ObjectList<Synchronisable>::iterator it;
+    for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) {
+      if (it->getObjectID() == OBJECTID_UNKNOWN) {
+        if (it->objectMode_ != 0x0) {
+          COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl;
+          COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl;
+          COUT(0) << "Objects class: " << it->getIdentifier()->getName() << std::endl;
+          assert(false);
+        }
+      }
+      else {
+        std::list<uint32_t>::iterator it2;
+        for (it2 = v1.begin(); it2 != v1.end(); ++it2) {
+          if (it->getObjectID() == *it2) {
+            COUT(0) << "Found duplicate objectIDs on the client!" << std::endl
+                    << "Are you sure you don't create a Sychnronisable objcect with 'new' \
+                        that doesn't have objectMode = 0x0?" << std::endl;
+            assert(false);
+          }
+        }
+        v1.push_back(it->getObjectID());
+      }
+    }
+  }
+#endif
+  return true;
+}
+
+uint32_t Gamestate::getSize() const
+{
+  assert(data_);
+  if(header_->isCompressed())
+    return header_->getCompSize()+GamestateHeader::getSize();
+  else
+  {
+    return header_->getDataSize()+GamestateHeader::getSize();
+  }
+}
+
+bool Gamestate::operator==(packet::Gamestate gs){
+  uint8_t *d1 = data_+GamestateHeader::getSize();
+  uint8_t *d2 = gs.data_+GamestateHeader::getSize();
+  GamestateHeader* h1 = new GamestateHeader(data_);
+  GamestateHeader* h2 = new GamestateHeader(gs.data_);
+  assert(h1->getDataSize() == h2->getDataSize());
+  assert(!isCompressed());
+  assert(!gs.isCompressed());
+  return memcmp(d1, d2, h1->getDataSize())==0;
+}
+
+bool Gamestate::process()
+{
+  return GamestateHandler::addGamestate(this, getClientID());
+}
+
+
+
+bool Gamestate::compressData()
+{
+  assert(data_);
+  assert(!header_->isCompressed());
+  uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1);
+  if(buffer==0)
+    return false;
+
+  uint8_t *ndata = new uint8_t[buffer+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  uint8_t *source = data_ + GamestateHeader::getSize();
+  int retval;
+  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
+  switch ( retval ) {
+    case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
+    case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; return false;
+    case Z_BUF_ERROR: COUT(2) << "G.St.Man: compress: not enough memory available in the buffer in gamestate.compress" << std::endl; return false;
+    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
+  }
+
+  //copy and modify header
+  GamestateHeader *temp = header_;
+  header_ = new GamestateHeader(ndata, temp);
+  delete temp;
+  //delete old data
+  delete[] data_;
+  //save new data
+  data_ = ndata;
+  header_->setCompSize( buffer );
+  header_->setCompressed( true );
+  COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
+  return true;
+}
+bool Gamestate::decompressData()
+{
+  assert(data_);
+  assert(header_->isCompressed());
+  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;
+  uint32_t datasize = header_->getDataSize();
+  uint32_t compsize = header_->getCompSize();
+  uint32_t bufsize;
+  bufsize = datasize;
+  assert(bufsize!=0);
+  uint8_t *ndata = new uint8_t[bufsize + GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  uint8_t *source = data_ + GamestateHeader::getSize();
+  int retval;
+  uLongf length=bufsize;
+  retval = uncompress( dest, &length, source, (uLong)compsize );
+  switch ( retval ) {
+    case Z_OK: COUT(5) << "successfully decompressed" << std::endl; break;
+    case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return false;
+    case Z_BUF_ERROR: COUT(2) << "not enough memory available in the buffer" << std::endl; return false;
+    case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
+  }
+
+  //copy over the header
+  GamestateHeader *temp = header_;
+  header_ = new GamestateHeader( data_, header_ );
+  delete temp;
+
+  if (this->bDataENetAllocated_){
+    // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will
+    // deallocated it anyway. So data and packet stay together.
+    this->bDataENetAllocated_ = false;
+  }
+  else{
+    // We allocated the memory in the first place (unlikely). So we destroy the old data
+    // and overwrite it with the new decompressed data.
+    delete[] this->data_;
+  }
+
+  //set new pointers
+  data_ = ndata;
+  header_->setCompressed( false );
+  assert(header_->getDataSize()==datasize);
+  assert(header_->getCompSize()==compsize);
+  return true;
+}
+
+/*Gamestate *Gamestate::diff(Gamestate *base)
+{
+  assert(data_);
+  assert(!header_->isCompressed());
+  assert(!header_->isDiffed());
+  GamestateHeader diffHeader(base->data_);
+  uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
+  uint32_t of=0; // pointers offset
+  uint32_t dest_length=0;
+  dest_length=header_->getDataSize();
+  if(dest_length==0)
+    return NULL;
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  while(of < diffHeader.getDataSize() && of < header_->getDataSize()){
+    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
+    ++of;
+  }
+  if(diffHeader.getDataSize()!=header_->getDataSize()){
+    uint8_t n=0;
+    if(diffHeader.getDataSize() < header_->getDataSize()){
+      while(of<dest_length){
+        *(dest+of)=n^*(gs+of);
+        of++;
+      }
+    }
+  }
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  return g;
+}*/
+
+Gamestate *Gamestate::diff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(!header_->isDiffed());
+  
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+  
+  if(dest_length==0)
+    return NULL;
+  
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = GAMESTATE_START(ndata);
+  
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+#ifndef NDEBUG
+  uint8_t *dest2 = new uint8_t[dest_length];
+  rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+  assert( memcmp( dest2, gs, dest_length) == 0 );
+#endif
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+Gamestate *Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(header_->isDiffed());
+  
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+  
+  if(dest_length==0)
+    return NULL;
+  
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+  
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+
+// Gamestate *Gamestate::diff(Gamestate *base)
+// {
+//   assert(data_);
+//   assert(!header_->isCompressed());
+//   assert(!header_->isDiffed());
+//   GamestateHeader diffHeader(base->data_);
+//   uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
+//   uint32_t of=0; // pointers offset
+//   uint32_t dest_length=0;
+//   dest_length=header_->getDataSize();
+//   if(dest_length==0)
+//     return NULL;
+//   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+//   uint8_t *dest = ndata + GamestateHeader::getSize();
+//   
+//   
+//   // LOOP-UNROLLED DIFFING
+//   uint32_t *dest32 = (uint32_t*)dest, *base32 = (uint32_t*)basep, *gs32 = (uint32_t*)gs;
+//   // diff in 4-byte steps
+//   while( of < (uint32_t)(header_->getDataSize())/4 ){
+//     if( of < (uint32_t)(diffHeader.getDataSize())/4 )
+//     {
+//       *(dest32+of)=*(base32+of) ^ *(gs32+of); // do the xor
+//       ++of;
+//     }
+//     else
+//     {
+//       *(dest32+of)=*(gs32+of); // same as 0 ^ *(gs32+of)
+//       ++of;
+//     }
+//   }
+//   for( unsigned int of2 = 0; of2 < header_->getDataSize()%4; ++of2 )
+//   {
+//     if( of*4+of2 < diffHeader.getDataSize() )
+//     {
+//       *(dest+4*of+of2)=*(basep+4*of+of2) ^ *(gs+4*of+of2); // do the xor
+//     }
+//     else
+//     {
+//       *(dest+4*of+of2)=*(gs+4*of+of2); // same as 0 ^ *(gs32+of)
+//     }
+//   }
+// 
+//   Gamestate *g = new Gamestate(ndata, getClientID());
+//   *(g->header_) = *header_;
+//   g->header_->setDiffed( true );
+//   g->header_->setBaseID( base->getID() );
+//   g->flags_=flags_;
+//   g->packetDirection_ = packetDirection_;
+//   return g;
+// }
+
+
+void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
+{
+  uint64_t* gd = (uint64_t*)data;
+  uint64_t* bd = (uint64_t*)basedata;
+  uint64_t* nd = (uint64_t*)newdata;
+  
+  unsigned int i;
+  for( i=0; i<datalength/8; i++ )
+  {
+    if( i<baselength/8 )
+      *(nd+i) = *(gd+i) ^ *(bd+i);  // xor the data
+    else
+      *(nd+i) = *(gd+i); // just copy over the data
+  }
+  unsigned int j;
+  // now process the rest (when datalength isn't a multiple of 4)
+  for( j = 8*(datalength/8); j<datalength; j++ )
+  {
+    if( j<baselength )
+      *(newdata+j) = *(data+j) ^ *(basedata+j); // xor
+    else
+      *(newdata+j) = *(data+j); // just copy
+  }
+  assert(j==datalength);
+}
+
+Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
+  assert(data_);
+  std::list<obj>::iterator it;
+
+  // allocate memory for new data
+  uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()];
+  // create a gamestate out of it
+  Gamestate *gs = new Gamestate(gdata);
+  uint8_t *newdata = gdata + GamestateHeader::getSize();
+  uint8_t *origdata = GAMESTATE_START(data_);
+
+  //copy the GamestateHeader
+  assert(gs->header_);
+  *(gs->header_) = *header_;
+
+  uint32_t objectOffset;
+  unsigned int objectsize, destsize=0;
+  // TODO: Why is this variable not used?
+  //Synchronisable *object;
+
+  //call TrafficControl
+  TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), dataVector_ );
+
+  //copy in the zeros
+//   std::list<obj>::iterator itt;
+//   COUT(0) << "myvector contains:";
+//   for ( itt=dataVector_.begin() ; itt!=dataVector_.end(); itt++ )
+//     COUT(0) << " " << (*itt).objID;
+//   COUT(0) << endl;
+  for(it=dataVector_.begin(); it!=dataVector_.end();){
+    SynchronisableHeader oldobjectheader(origdata);
+    SynchronisableHeader newobjectheader(newdata);
+    if ( (*it).objSize == 0 )
+    {
+      ++it;
+      continue;
+    }
+    objectsize = oldobjectheader.getDataSize();
+    objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader
+    if ( (*it).objID == oldobjectheader.getObjectID() ){
+      memcpy(newdata, origdata, objectsize);
+      assert(newobjectheader.isDataAvailable()==true);
+      ++it;
+    }else{
+      newobjectheader = oldobjectheader;
+      newobjectheader.setDataAvailable(false);
+      memset(newdata+objectOffset, 0, objectsize-objectOffset);
+    }
+    newdata += objectsize;
+    origdata += objectsize;
+    destsize += objectsize;
+  }
+#ifndef NDEBUG
+  uint32_t origsize = destsize;
+  while ( origsize < header_->getDataSize() )
+  {
+    SynchronisableHeader oldobjectheader(origdata);
+    objectsize = oldobjectheader.getDataSize();
+    origdata += objectsize;
+    origsize += objectsize;
+  }
+  assert(origsize==header_->getDataSize());
+  assert(destsize!=0);
+#endif
+  gs->header_->setDataSize( destsize );
+  return gs;
+}
+
+
+/*Gamestate *Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base);assert(data_);
+  assert(header_->isDiffed());
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t of=0; // pointers offset
+  uint32_t dest_length=0;
+  dest_length=header_->getDataSize();
+  if(dest_length==0)
+    return NULL;
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  while(of < base->header_->getDataSize() && of < header_->getDataSize()){
+    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
+    ++of;
+  }
+  if(base->header_->getDataSize()!=header_->getDataSize()){
+    uint8_t n=0;
+    if(base->header_->getDataSize() < header_->getDataSize()){
+      while(of < dest_length){
+        *(dest+of)=n^*(gs+of);
+        of++;
+      }
+    }
+  }
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}*/
+
+uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
+{
+  uint32_t size=0;
+    // get the start of the Synchronisable list
+  ObjectList<Synchronisable>::iterator it;
+    // get total size of gamestate
+  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
+    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
+  return size;
+}
+
+} //namespace packet
+} //namespace orxonox
Index: code/trunk/src/libraries/network/packet/Gamestate.h
===================================================================
--- code/trunk/src/libraries/network/packet/Gamestate.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Gamestate.h	(revision 5781)
@@ -0,0 +1,138 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _Gamestate_H__
+#define _Gamestate_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include <list>
+
+#include "util/CRC32.h"
+#include "network/TrafficControl.h"
+#include "Packet.h"
+
+namespace orxonox {
+
+namespace packet {
+
+class _NetworkExport GamestateHeader{
+  public:
+    GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
+    GamestateHeader(uint8_t *data, GamestateHeader* h)
+    { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }
+    static inline uint32_t getSize()
+    { return 21; }
+
+    inline int32_t getID() const
+    { assert(data_); return *(int32_t*)(data_+4); }
+    inline void setID(int32_t id)
+    { assert(data_); *(int32_t*)(data_+4) = id; }
+
+    inline int32_t getBaseID() const
+    { assert(data_); return *(int32_t*)(data_+8); }
+    inline void setBaseID(int32_t id)
+    { assert(data_); *(int32_t*)(data_+8) = id; }
+
+    inline uint32_t getDataSize() const
+    { assert(data_); return *(uint32_t*)(data_+12); }
+    inline void setDataSize(uint32_t size)
+    { assert(data_); *(uint32_t*)(data_+12) = size; }
+
+    inline uint32_t getCompSize() const
+    { assert(data_); return *(uint32_t*)(data_+16); }
+    inline void setCompSize(uint32_t size)
+    { assert(data_); *(uint32_t*)(data_+16) = size; }
+
+    inline bool isDiffed() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
+    inline void setDiffed(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
+
+    inline bool isComplete() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
+    inline void setComplete(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
+
+    inline bool isCompressed() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
+    inline void setCompressed(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
+
+    inline void operator=(GamestateHeader& h)
+    { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
+  private:
+    uint8_t *data_;
+
+};
+
+/**
+	@author Oliver Scheuss
+*/
+class _NetworkExport Gamestate: public Packet{
+  public:
+    Gamestate();
+    Gamestate(uint8_t *data, unsigned int clientID);
+    Gamestate(uint8_t *data);
+    Gamestate(const Gamestate& g);
+
+    ~Gamestate();
+
+    bool collectData(int id, uint8_t mode=0x0);
+    bool spreadData( uint8_t mode=0x0);
+    inline int32_t getID() const { return header_->getID(); }
+    inline bool isDiffed() const { return header_->isDiffed(); }
+    inline bool isCompressed() const { return header_->isCompressed(); }
+    inline int32_t getBaseID() const { return header_->getBaseID(); }
+    Gamestate *diff(Gamestate *base);
+    Gamestate *undiff(Gamestate *base);
+    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
+    bool compressData();
+    bool decompressData();
+    bool operator ==(packet::Gamestate gs);
+
+    // Packet functions
+  private:
+    void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
+    virtual uint32_t getSize() const;
+    virtual inline bool process();
+
+  private:
+    uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
+    std::list<obj> dataVector_;
+    GamestateHeader* header_;
+};
+
+}
+
+}
+
+#endif /* _Gamestate_H__ */
Index: code/trunk/src/libraries/network/packet/Packet.cc
===================================================================
--- code/trunk/src/libraries/network/packet/Packet.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Packet.cc	(revision 5781)
@@ -0,0 +1,245 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "Packet.h"
+
+#include <cassert>
+#include <cstring>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include <boost/static_assert.hpp>
+
+#include "util/Debug.h"
+#include "Acknowledgement.h"
+#include "Chat.h"
+#include "ClassID.h"
+#include "DeleteObjects.h"
+#include "FunctionCalls.h"
+#include "FunctionIDs.h"
+#include "Gamestate.h"
+#include "Welcome.h"
+#include "network/Host.h"
+#include "network/ClientInformation.h"
+
+namespace orxonox{
+
+namespace packet{
+
+// Make sure we assume the right values
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Reliable)   == static_cast<int>(ENET_PACKET_FLAG_RELIABLE));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Unsequence) == static_cast<int>(ENET_PACKET_FLAG_UNSEQUENCED));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::NoAllocate) == static_cast<int>(ENET_PACKET_FLAG_NO_ALLOCATE));
+
+#define PACKET_FLAG_DEFAULT PacketFlag::NoAllocate
+#define _PACKETID           0
+
+std::map<size_t, Packet *> Packet::packetMap_;
+
+Packet::Packet(){
+  flags_ = PACKET_FLAG_DEFAULT;
+  packetDirection_ = Direction::Outgoing;
+  clientID_=0;
+  data_=0;
+  enetPacket_=0;
+  bDataENetAllocated_ = false;
+}
+
+void blub(ENetPacket *packet){
+  COUT(4) << "blubb" << std::endl;
+}
+
+Packet::Packet(uint8_t *data, unsigned int clientID){
+  flags_ = PACKET_FLAG_DEFAULT;
+  packetDirection_ = Direction::Incoming;
+  clientID_=clientID;
+  data_=data;
+  enetPacket_=0;
+  bDataENetAllocated_ = false;
+}
+
+
+Packet::Packet(const Packet &p){
+  enetPacket_=p.enetPacket_;
+  flags_=p.flags_;
+  packetDirection_ = p.packetDirection_;
+  clientID_ = p.clientID_;
+  if(p.data_){
+    data_ = new uint8_t[p.getSize()];
+    memcpy(data_, p.data_, p.getSize());
+  }else
+    data_=0;
+  bDataENetAllocated_ = p.bDataENetAllocated_;
+}
+
+/**
+@brief
+    Destroys a packet completely.
+    
+    That also means destroying the ENetPacket if one exists. There 
+*/
+Packet::~Packet(){
+  // Deallocate data_ memory if necessary.
+  if (this->bDataENetAllocated_){
+    // In this case ENet allocated data_ and will destroy it.
+  }
+  else if (this->data_) {
+    // This destructor was probably called as a consequence of ENet executing our callback.
+    // It simply serves us to be able to deallocate the packet content (data_) ourselves since
+    // we have created it in the first place.
+    delete[] this->data_;
+  }
+
+  // Destroy the ENetPacket if necessary.
+  // Note: For the case ENet used the callback to destroy the packet, we have already set
+  // enetPacket_ to NULL to avoid destroying it again.
+  if (this->enetPacket_){
+    // enetPacket_->data gets destroyed too by ENet if it was allocated by it.
+    enet_packet_destroy(enetPacket_);
+  }
+}
+
+bool Packet::send(){
+  if(packetDirection_ != Direction::Outgoing && packetDirection_ != Direction::Bidirectional ){
+    assert(0);
+    return false;
+  }
+  if(!enetPacket_){
+    if(!data_){
+      assert(0);
+      return false;
+    }
+    // We deliver ENet the data address so that it doesn't memcpy everything again.
+    // --> We have to delete data_ ourselves!
+    enetPacket_ = enet_packet_create(getData(), getSize(), getFlags());
+    enetPacket_->freeCallback = &Packet::deletePacket;
+    // Add the packet to a global list so we can access it again once enet calls our
+    // deletePacket method. We can of course only give a one argument function to the ENet C library.
+    {
+      // Assures we don't create a packet and destroy it right after in another thread
+      // without having a reference in the packetMap_
+      packetMap_[reinterpret_cast<size_t>(enetPacket_)] = this;
+    }
+  }
+#ifndef NDEBUG
+  switch( *(Type::Value *)(data_ + _PACKETID) )
+  {
+    case Type::Acknowledgement:
+    case Type::Chat:
+    case Type::ClassID:
+    case Type::Gamestate:
+    case Type::Welcome:
+    case Type::DeleteObjects:
+    case Type::FunctionIDs:
+    case Type::FunctionCalls:
+      break;
+    default:
+      assert(0); //there was some error, if this is the case
+      break;
+  }
+#endif
+//  ENetPacket *temp = enetPacket_;
+//  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
+  if(!Host::addPacket( enetPacket_, clientID_))
+    enet_packet_destroy(this->enetPacket_); // if we could not add the packet to the enet queue delete it manually
+  return true;
+}
+
+Packet *Packet::createPacket(ENetPacket *packet, ENetPeer *peer){
+  uint8_t *data = packet->data;
+  assert(ClientInformation::findClient(&peer->address)->getID() != static_cast<unsigned int>(-2) || !Host::isServer());
+  unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
+  Packet *p = 0;
+  COUT(6) << "packet type: " << *(Type::Value *)&data[_PACKETID] << std::endl;
+  switch( *(Type::Value *)(data + _PACKETID) )
+  {
+    case Type::Acknowledgement:
+      COUT(5) << "ack" << std::endl;
+      p = new Acknowledgement( data, clientID );
+      break;
+    case Type::Chat:
+      COUT(5) << "chat" << std::endl;
+      p = new Chat( data, clientID );
+      break;
+    case Type::ClassID:
+      COUT(5) << "classid" << std::endl;
+      p = new ClassID( data, clientID );
+      break;
+    case Type::Gamestate:
+      COUT(5) << "gamestate" << std::endl;
+      // TODO: remove brackets
+      p = new Gamestate( data, clientID );
+      break;
+    case Type::Welcome:
+      COUT(5) << "welcome" << std::endl;
+      p = new Welcome( data, clientID );
+      break;
+    case Type::DeleteObjects:
+      COUT(5) << "deleteobjects" << std::endl;
+      p = new DeleteObjects( data, clientID );
+      break;
+    case Type::FunctionCalls:
+      COUT(5) << "functionCalls" << std::endl;
+      p = new FunctionCalls( data, clientID );
+      break;
+    case Type::FunctionIDs:
+      COUT(5) << "functionIDs" << std::endl;
+      p = new FunctionIDs( data, clientID );
+      break;
+    default:
+      assert(0); //TODO: repair this
+      break;
+  }
+
+  // Data was created by ENet
+  p->bDataENetAllocated_ = true;
+  p->enetPacket_ = packet;
+
+  return p;
+}
+
+/**
+@brief
+    ENet calls this method whenever it wants to destroy a packet that contains
+    data we allocated ourselves.
+*/
+void Packet::deletePacket(ENetPacket *enetPacket){
+  // Get our Packet from a gloabal map with all Packets created in the send() method of Packet.
+  std::map<size_t, Packet*>::iterator it = packetMap_.find(reinterpret_cast<size_t>(enetPacket));
+  assert(it != packetMap_.end());
+  // Make sure we don't delete it again in the destructor
+  it->second->enetPacket_ = 0;
+  delete it->second;
+  packetMap_.erase(it);
+  COUT(6) << "PacketMap size: " << packetMap_.size() << std::endl;
+}
+
+} // namespace packet
+
+} // namespace orxonox
+
Index: code/trunk/src/libraries/network/packet/Packet.h
===================================================================
--- code/trunk/src/libraries/network/packet/Packet.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Packet.h	(revision 5781)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef _NETWORK_Packet_H__
+#define _NETWORK_Packet_H__
+
+#include "network/NetworkPrereqs.h"
+#include <map>
+
+namespace orxonox {
+
+namespace packet{
+
+namespace Direction{
+  enum Value{
+    Incoming,
+    Outgoing,
+    Bidirectional
+  };
+}
+namespace Type{
+  enum Value{
+    Acknowledgement,
+    Chat,
+    ClassID,
+    DeleteObjects,
+    FunctionIDs,
+    FunctionCalls,
+    Gamestate,
+    Welcome
+  };
+}
+
+/**
+	@author Oliver Scheuss <scheusso [at] ee.ethz.ch>
+*/
+class _NetworkExport Packet{
+  public:
+    Packet(const Packet &p);
+    virtual ~Packet();
+    static Packet *createPacket(ENetPacket *packet, ENetPeer *peer);
+    static void deletePacket(ENetPacket *packet);
+
+    virtual unsigned char *getData(){ return data_; };
+    virtual unsigned int getSize() const =0;
+    virtual bool process()=0;
+    inline uint32_t getFlags()
+      { return flags_; }
+    inline int getClientID()
+      { return clientID_; }
+    inline void setClientID( int id )
+      { clientID_ = id; }
+
+    bool send();
+  protected:
+    Packet();
+    Packet(uint8_t *data, unsigned int clientID);
+//    Packet(ENetPacket *packet, ENetPeer *peer);
+    inline bool isDataENetAllocated() const
+      { return bDataENetAllocated_; }
+
+    uint32_t flags_;
+    unsigned int clientID_;
+    Direction::Value packetDirection_;
+    /** Pointer to the data. Be careful when deleting it because it might
+        point to a location that was allocated by ENet.
+        See bDataENetAllocated_ */
+    uint8_t *data_;
+    /** Tells whether data_ was allocated by ENet or ourselves.
+        data_ might no correlate with enetPacket_->data. */
+    bool bDataENetAllocated_;
+  private:
+    static std::map<size_t, Packet *> packetMap_;
+    ENetPacket *enetPacket_;
+};
+
+} //namespace packet
+
+} //namespace orxonox
+
+#endif /* _NETWORK_Packet_H__ */
Index: code/trunk/src/libraries/network/packet/Welcome.cc
===================================================================
--- code/trunk/src/libraries/network/packet/Welcome.cc	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Welcome.cc	(revision 5781)
@@ -0,0 +1,88 @@
+
+
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Welcome.h"
+
+#include <cassert>
+#include "util/Debug.h"
+#include "network/Host.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox {
+namespace packet {
+
+#define PACKET_FLAGS_CLASSID  PacketFlag::Reliable
+#define _PACKETID             0
+#define _CLIENTID             _PACKETID + sizeof(Type::Value)
+#define _ENDIANTEST           _CLIENTID + sizeof(uint32_t)
+
+  Welcome::Welcome( uint32_t clientID, uint32_t shipID )
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_CLASSID;
+  assert(getSize());
+  data_=new uint8_t[ getSize() ];
+  assert(data_);
+  *(packet::Type::Value *)(data_ + _PACKETID ) = packet::Type::Welcome;
+  *(uint32_t *)(data_ + _CLIENTID ) = static_cast<uint32_t>(clientID);
+  *(uint32_t *)(data_ + _ENDIANTEST ) = 0xFEDC4321;
+}
+
+Welcome::Welcome( uint8_t* data, uint32_t clientID )
+  : Packet(data, clientID)
+{
+}
+
+Welcome::~Welcome()
+{
+}
+
+uint8_t *Welcome::getData(){
+  return data_;
+}
+
+unsigned int Welcome::getSize() const{
+  return sizeof(packet::Type::Value) + 2*sizeof(uint32_t);
+}
+
+bool Welcome::process(){
+  uint32_t clientID;
+  clientID = *(uint32_t *)(data_ + _CLIENTID );
+  assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321);
+  Host::setClientID(clientID);
+  COUT(3) << "Welcome set clientId: " << clientID << endl;
+  Synchronisable::setClient(true);
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: code/trunk/src/libraries/network/packet/Welcome.h
===================================================================
--- code/trunk/src/libraries/network/packet/Welcome.h	(revision 5781)
+++ code/trunk/src/libraries/network/packet/Welcome.h	(revision 5781)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef _NETWORK_Welcome_H__
+#define _NETWORK_Welcome_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+/**
+	@author
+*/
+class _NetworkExport Welcome : public Packet
+{
+public:
+  Welcome( uint32_t clientID, uint32_t shipID );
+  Welcome( uint8_t* data, uint32_t clientID );
+  virtual ~Welcome();
+
+  uint8_t *getData();
+  inline unsigned int getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _NETWORK_Welcome_H__ */
Index: code/trunk/src/libraries/network/synchronisable/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/network/synchronisable/CMakeLists.txt	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/CMakeLists.txt	(revision 5781)
@@ -0,0 +1,13 @@
+ADD_SOURCE_FILES(NETWORK_SRC_FILES
+  NetworkCallbackManager.cc
+  Synchronisable.cc
+  SynchronisableSpecialisations.cc
+  SynchronisableVariable.cc
+)
+
+ADD_SOURCE_FILES(NETWORK_HDR_FILES
+  NetworkCallback.h
+  NetworkCallbackManager.h
+  Synchronisable.h
+  SynchronisableVariable.h
+)
Index: code/trunk/src/libraries/network/synchronisable/NetworkCallback.h
===================================================================
--- code/trunk/src/libraries/network/synchronisable/NetworkCallback.h	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/NetworkCallback.h	(revision 5781)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _NetworkCallback_H__
+#define _NetworkCallback_H__
+
+#include "network/NetworkPrereqs.h"
+#include "NetworkCallbackManager.h"
+
+namespace orxonox{
+  
+  class _NetworkExport NetworkCallbackBase
+  {
+    public:
+      virtual void call() = 0;
+      NetworkCallbackBase(){ NetworkCallbackManager::registerCallback( this ); }
+      virtual ~NetworkCallbackBase() {}
+  };
+
+  template <class T>
+  class NetworkCallback: public NetworkCallbackBase
+  {
+    public:
+      NetworkCallback(T* object, void (T::*function) (void)) : object_(object), function_(function) {}
+	  virtual ~NetworkCallback() {}
+      virtual void call()
+        { (this->object_->*function_)(); }
+
+    private:
+      T* object_;
+      void (T::*function_) (void);
+  };
+
+}
+
+
+#endif /* _NetworkCallback_H__ */
Index: code/trunk/src/libraries/network/synchronisable/NetworkCallbackManager.cc
===================================================================
--- code/trunk/src/libraries/network/synchronisable/NetworkCallbackManager.cc	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/NetworkCallbackManager.cc	(revision 5781)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+ 
+#include "NetworkCallbackManager.h"
+#include "NetworkCallback.h"
+
+namespace orxonox{
+  
+  std::set<NetworkCallbackBase*> NetworkCallbackManager::callbackSet_;
+  std::queue<NetworkCallbackBase*> NetworkCallbackManager::triggeredCallbacks_;
+  
+  void NetworkCallbackManager::registerCallback(NetworkCallbackBase *cb)
+  { 
+    callbackSet_.insert(cb); 
+  }
+  void NetworkCallbackManager::deleteCallback(NetworkCallbackBase *cb)
+  {
+    std::set<NetworkCallbackBase*>::iterator it = callbackSet_.find(cb);
+    if (it != callbackSet_.end())
+    {
+      callbackSet_.erase(it);
+      delete cb;
+    }
+  }
+  
+  void NetworkCallbackManager::triggerCallback(NetworkCallbackBase *cb)
+  {
+    if (triggeredCallbacks_.empty() || triggeredCallbacks_.front() != cb)
+      triggeredCallbacks_.push(cb);
+  }
+
+  void NetworkCallbackManager::callCallbacks()
+  {
+    while( triggeredCallbacks_.empty()==false )
+    {
+      //make sure callback hasn't been deleted before
+      if ( callbackSet_.find(triggeredCallbacks_.front()) != callbackSet_.end() )
+        triggeredCallbacks_.front()->call();
+      triggeredCallbacks_.pop();
+    }
+  }
+}
Index: code/trunk/src/libraries/network/synchronisable/NetworkCallbackManager.h
===================================================================
--- code/trunk/src/libraries/network/synchronisable/NetworkCallbackManager.h	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/NetworkCallbackManager.h	(revision 5781)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _NetworkCallbackManager_H__
+#define _NetworkCallbackManager_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <set>
+#include <queue>
+
+namespace orxonox{
+  
+  class _NetworkExport NetworkCallbackManager{
+    public:
+      static void registerCallback(NetworkCallbackBase *cb);
+      static void deleteCallback(NetworkCallbackBase *cb);
+      static void triggerCallback(NetworkCallbackBase *cb);
+      static void callCallbacks();
+    private:
+      static std::set<NetworkCallbackBase*> callbackSet_;
+      static std::queue<NetworkCallbackBase*> triggeredCallbacks_;
+  };
+  
+
+}
+
+
+#endif /* _NetworkCallbackManager_H__ */
Index: code/trunk/src/libraries/network/synchronisable/Synchronisable.cc
===================================================================
--- code/trunk/src/libraries/network/synchronisable/Synchronisable.cc	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/Synchronisable.cc	(revision 5781)
@@ -0,0 +1,391 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Dumeni Manatschal, (C) 2007
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "Synchronisable.h"
+
+#include <cstdlib>
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/BaseObject.h"
+#include "network/Host.h"
+
+namespace orxonox
+{
+
+  std::map<uint32_t, Synchronisable *> Synchronisable::objectMap_;
+  std::queue<uint32_t> Synchronisable::deletedObjects_;
+
+  uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
+
+  /**
+  * Constructor:
+  * Initializes all Variables and sets the right objectID
+  */
+  Synchronisable::Synchronisable(BaseObject* creator){
+    RegisterRootObject(Synchronisable);
+    static uint32_t idCounter=0;
+    objectMode_=0x1; // by default do not send data to server
+    if ( GameMode::isMaster() || ( Host::running() && Host::isServer() ) )
+    {
+      this->objectID = idCounter++; //this is only needed when running a server
+    //add synchronisable to the objectMap
+      objectMap_[this->objectID] = this;
+    }
+    else
+    {
+      objectID=OBJECTID_UNKNOWN;
+      this->setObjectMode(0x0);   //make sure this object doesn't get synchronized
+    }
+    classID = static_cast<uint32_t>(-1);
+    
+    // set dataSize to 0
+    this->dataSize_ = 0;
+    // set standard priority
+    this->setPriority( Priority::Normal );
+
+    // get creator id
+    this->creatorID = OBJECTID_UNKNOWN;
+
+    searchcreatorID:
+    if (creator)
+    {
+        Synchronisable* synchronisable_creator = orxonox_cast<Synchronisable*>(creator);
+        if (synchronisable_creator && synchronisable_creator->objectMode_)
+        {
+            this->creatorID = synchronisable_creator->getObjectID();
+        }
+        else if (creator != creator->getCreator())
+        {
+            creator = creator->getCreator();
+            goto searchcreatorID;
+        }
+    }
+  }
+
+  /**
+   * Destructor:
+   * Delete all callback objects and remove objectID from the objectMap_
+   */
+  Synchronisable::~Synchronisable(){
+    // delete callback function objects
+    if(!Identifier::isCreatingHierarchy()){
+      // remove object from the static objectMap
+      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
+        deletedObjects_.push(objectID);
+    }
+    // delete all Synchronisable Variables from syncList ( which are also in stringList )
+    for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
+      delete (*it);
+    syncList.clear();
+    stringList.clear();
+    std::map<uint32_t, Synchronisable*>::iterator it;
+    it = objectMap_.find(objectID);
+    if (it != objectMap_.end())
+      objectMap_.erase(it);
+
+  }
+
+
+  /**
+   * This function sets the internal mode for synchronisation
+   * @param b true if this object is located on a client or on a server
+   */
+  void Synchronisable::setClient(bool b){
+    if(b) // client
+      state_=0x2;
+    else  // server
+      state_=0x1;
+  }
+
+  /**
+   * This function fabricated a new synchrnisable (and children of it), sets calls updateData and create
+   * After calling this function the mem pointer will be increased by the size of the needed data
+   * @param mem pointer to where the appropriate data is located
+   * @param mode defines the mode, how the data should be loaded
+   * @return pointer to the newly created synchronisable
+   */
+  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
+  {
+    SynchronisableHeader header(mem);
+
+    if(!header.isDataAvailable())
+    {
+      mem += header.getDataSize();
+      return 0;
+    }
+
+    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
+
+    Identifier* id = ClassByID(header.getClassID());
+    if (!id)
+    {
+        for(int i = 0; i<160; i++)
+            COUT(0) << "classid: " << i << " identifier: " << ClassByID(i) << endl;
+        COUT(0) << "Assertion failed: id" << std::endl;
+        COUT(0) << "Possible reason for this error: Client received a synchronizable object whose class has no factory." << std::endl;
+        abort();
+    }
+    assert(id);
+    BaseObject* creator = 0;
+    if (header.getCreatorID() != OBJECTID_UNKNOWN)
+    {
+      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header.getCreatorID());
+      if (!synchronisable_creator)
+      {
+        mem += header.getDataSize(); //.TODO: this suckz.... remove size from header
+        assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
+        return 0;
+      }
+      else
+        creator = orxonox_cast<BaseObject*>(synchronisable_creator);
+    }
+    assert(getSynchronisable(header.getObjectID())==0);   //make sure no object with this id exists
+    BaseObject *bo = id->fabricate(creator);
+    assert(bo);
+    Synchronisable *no = orxonox_cast<Synchronisable*>(bo);
+    assert(no);
+    no->objectID=header.getObjectID();
+    no->creatorID=header.getCreatorID(); //TODO: remove this
+    no->classID=header.getClassID();
+    COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
+          // update data and create object/entity...
+    assert( Synchronisable::objectMap_.find(header.getObjectID()) == Synchronisable::objectMap_.end() );
+    Synchronisable::objectMap_[header.getObjectID()] = no;
+    bool b = no->updateData(mem, mode, true);
+    assert(b);
+    if (b)
+    {
+//        b = no->create();
+        assert(b);
+    }
+    return no;
+  }
+
+
+  /**
+   * Finds and deletes the Synchronisable with the appropriate objectID
+   * @param objectID objectID of the Synchronisable
+   * @return true/false
+   */
+  bool Synchronisable::deleteObject(uint32_t objectID){
+    if(!getSynchronisable(objectID))
+      return false;
+    assert(getSynchronisable(objectID)->objectID==objectID);
+    Synchronisable *s = getSynchronisable(objectID);
+    if(s)
+      delete s;
+    else
+      return false;
+    return true;
+  }
+
+  /**
+   * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable
+   * @param objectID objectID of the Synchronisable
+   * @return pointer to the Synchronisable with the objectID
+   */
+  Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID){
+    std::map<uint32_t, Synchronisable*>::iterator it1;
+    it1 = objectMap_.find(objectID);
+    if (it1 != objectMap_.end())
+      return it1->second;
+
+//     ObjectList<Synchronisable>::iterator it;
+//     for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+//       if( it->getObjectID()==objectID ){
+//         objectMap_[objectID] = *it;
+//         return *it;
+//       }
+//     }
+    // if the objects not in the map it should'nt exist at all anymore
+    return NULL;
+  }
+
+
+  /**
+   * This function takes all SynchronisableVariables out of the Synchronisable and saves them together with the size, objectID and classID to the given memory
+   * takes a pointer to already allocated memory (must have at least getSize bytes length)
+   * structure of the bitstream:
+   * |totalsize,objectID,classID,var1,var2,string1_length,string1,var3,...|
+   * length of varx: size saved int syncvarlist
+   * @param mem pointer to allocated memory with enough size
+   * @param id gamestateid of the gamestate to be saved (important for priorities)
+   * @param mode defines the direction in which the data will be send/received
+   *             0x1: server->client
+   *             0x2: client->server (not recommended)
+   *             0x3: bidirectional
+   * @return true: if !doSync or if everything was successfully saved
+   */
+  uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
+    if(mode==0x0)
+      mode=state_;
+    //if this tick is we dont synchronise, then abort now
+    if(!doSync(id, mode))
+      return 0;
+    uint32_t tempsize = 0;
+#ifndef NDEBUG
+    if (this->classID==0)
+      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
+#endif
+
+    if (this->classID == static_cast<uint32_t>(-1))
+        this->classID = this->getIdentifier()->getNetworkID();
+
+    assert(ClassByID(this->classID));
+    assert(this->classID==this->getIdentifier()->getNetworkID());
+    std::vector<SynchronisableVariableBase*>::iterator i;
+
+    // start copy header
+    SynchronisableHeader header(mem);
+    mem += SynchronisableHeader::getSize();
+    // end copy header
+
+
+    COUT(5) << "Synchronisable getting data from objectID: " << objectID << " classID: " << classID << std::endl;
+    // copy to location
+    for(i=syncList.begin(); i!=syncList.end(); ++i){
+      tempsize += (*i)->getData( mem, mode );
+      //tempsize += (*i)->getSize( mode );
+    }
+    
+    tempsize += SynchronisableHeader::getSize();
+    header.setObjectID( this->objectID );
+    header.setCreatorID( this->creatorID );
+    header.setClassID( this->classID );
+    header.setDataAvailable( true );
+    header.setDataSize( tempsize );
+    
+#ifndef NDEBUG
+    uint32_t size;
+    size=getSize(id, mode);
+    assert(tempsize==size);
+#endif
+    return tempsize;
+  }
+
+
+  /**
+   * This function takes a bytestream and loads the data into the registered variables
+   * @param mem pointer to the bytestream
+   * @param mode same as in getData
+   * @return true/false
+   */
+  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
+    if(mode==0x0)
+      mode=state_;
+    std::vector<SynchronisableVariableBase *>::iterator i;
+    if(syncList.empty()){
+      assert(0);
+      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
+      return false;
+    }
+
+    uint8_t* data=mem;
+    // start extract header
+    SynchronisableHeader syncHeader(mem);
+    assert(syncHeader.getObjectID()==this->objectID);
+    assert(syncHeader.getCreatorID()==this->creatorID);
+    assert(syncHeader.getClassID()==this->classID);
+    if(syncHeader.isDataAvailable()==false){
+      mem += syncHeader.getDataSize();
+      return true;
+    }
+
+    mem += SynchronisableHeader::getSize();
+    // stop extract header
+
+    //COUT(5) << "Synchronisable: objectID " << syncHeader.getObjectID() << ", classID " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
+    for(i=syncList.begin(); i!=syncList.end(); i++)
+    {
+      assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream
+      (*i)->putData( mem, mode, forceCallback );
+    }
+    assert(mem == data+syncHeader.getDataSize());
+    return true;
+  }
+
+  /**
+  * This function returns the total amount of bytes needed by getData to save the whole content of the variables
+  * @param id id of the gamestate
+  * @param mode same as getData
+  * @return amount of bytes
+  */
+  uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
+    int tsize=SynchronisableHeader::getSize();
+    if (mode==0x0)
+      mode=state_;
+    if (!doSync(id, mode))
+      return 0;
+    assert( mode==state_ );
+    tsize += this->dataSize_;
+    std::vector<SynchronisableVariableBase*>::iterator i;
+    for(i=stringList.begin(); i!=stringList.end(); ++i){
+      tsize += (*i)->getSize( mode );
+    }
+    return tsize;
+  }
+
+  /**
+   * This function determines, wheter the object should be saved to the bytestream (according to its syncmode/direction)
+   * @param id gamestate id
+   * @return true/false
+   */
+  bool Synchronisable::doSync(int32_t id, uint8_t mode){
+    if(mode==0x0)
+      mode=state_;
+    return ( (objectMode_&mode)!=0 && (!syncList.empty() ) );
+  }
+
+  /**
+   * This function looks at the header located in the bytestream and checks wheter objectID and classID match with the Synchronisables ones
+   * @param mem pointer to the bytestream
+   */
+  bool Synchronisable::isMyData(uint8_t* mem)
+  {
+    SynchronisableHeader header(mem);
+    assert(header.getObjectID()==this->objectID);
+    return header.isDataAvailable();
+  }
+
+  /**
+   * This function sets the synchronisation mode of the object
+   * If set to 0x0 variables will not be synchronised at all
+   * If set to 0x1 variables will only be synchronised to the client
+   * If set to 0x2 variables will only be synchronised to the server
+   * If set to 0x3 variables will be synchronised bidirectionally (only if set so in registerVar)
+   * @param mode same as in registerVar
+   */
+  void Synchronisable::setObjectMode(uint8_t mode){
+    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
+    objectMode_=mode;
+  }
+
+
+}
Index: code/trunk/src/libraries/network/synchronisable/Synchronisable.h
===================================================================
--- code/trunk/src/libraries/network/synchronisable/Synchronisable.h	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/Synchronisable.h	(revision 5781)
@@ -0,0 +1,216 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Synchronisable_H__
+#define _Synchronisable_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include <vector>
+#include <map>
+#include <queue>
+
+#include "util/mbool.h"
+#include "core/OrxonoxClass.h"
+#include "SynchronisableVariable.h"
+#include "NetworkCallback.h"
+
+
+namespace orxonox
+{
+
+  namespace ObjectDirection{
+    enum Value{
+      ToClient=0x1,
+      ToServer=0x2,
+      Bidirectional=0x3
+    };
+  }
+
+  namespace Priority{
+    enum Value{
+      VeryHigh    = -100,
+      High        = -15,
+      Normal      = 0,
+      Low         = 15,
+      VeryLow     = 100
+    };
+  }
+
+  /**
+   * @brief: stores information about a Synchronisable 
+   * 
+   * This class stores the information about a Synchronisable (objectID, classID, creatorID, dataSize)
+   * in an emulated bitset.
+   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
+   * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
+   * Byte 5 to 8: objectID
+   * Byte 9 to 12: classID
+   * Byte 13 to 16: creatorID
+   */
+  class _NetworkExport SynchronisableHeader{
+    private:
+      uint8_t *data_;
+    public:
+      SynchronisableHeader(uint8_t* data)
+        { data_ = data; }
+      inline static uint32_t getSize()
+        { return 16; }
+      inline uint32_t getDataSize() const
+        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
+      inline void setDataSize(uint32_t size)
+        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+      inline bool isDataAvailable() const
+        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+      inline void setDataAvailable( bool b)
+        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+      inline uint32_t getObjectID() const
+        { return *(uint32_t*)(data_+4); }
+      inline void setObjectID(uint32_t objectID)
+        { *(uint32_t*)(data_+4) = objectID; }
+      inline uint32_t getClassID() const
+        { return *(uint32_t*)(data_+8); }
+      inline void setClassID(uint32_t classID)
+        { *(uint32_t*)(data_+8) = classID; }
+      inline uint32_t getCreatorID() const
+        { return *(uint32_t*)(data_+12); }
+      inline void setCreatorID(uint32_t creatorID)
+        { *(uint32_t*)(data_+12) = creatorID; }
+      inline void operator=(SynchronisableHeader& h)
+        { memcpy(data_, h.data_, getSize()); }
+  };
+
+
+  /**
+  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
+  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
+  public:
+    friend class packet::Gamestate;
+    virtual ~Synchronisable();
+
+    static void setClient(bool b);
+
+    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
+    static bool deleteObject(uint32_t objectID);
+    static Synchronisable *getSynchronisable(uint32_t objectID);
+    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
+    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
+
+    inline uint32_t getObjectID() const {return objectID;}
+    inline unsigned int getCreatorID() const {return creatorID;}
+    inline uint32_t getClassID() const {return classID;}
+    inline unsigned int getPriority() const { return objectFrequency_;}
+
+  protected:
+    Synchronisable(BaseObject* creator);
+    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
+    //template <class T> void unregisterVariable(T& var);
+    void setObjectMode(uint8_t mode);
+    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
+
+
+  private:
+    uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
+    uint32_t getSize(int32_t id, uint8_t mode=0x0);
+    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
+    bool isMyData(uint8_t* mem);
+    bool doSync(int32_t id, uint8_t mode=0x0);
+
+    uint32_t objectID;
+    uint32_t creatorID;
+    uint32_t classID;
+
+    std::vector<SynchronisableVariableBase*> syncList;
+    std::vector<SynchronisableVariableBase*> stringList;
+    uint32_t dataSize_; //size of all variables except strings
+    static uint8_t state_; // detemines wheter we are server (default) or client
+    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
+    unsigned int objectFrequency_;
+    int objectMode_;
+    static std::map<uint32_t, Synchronisable *> objectMap_;
+    static std::queue<uint32_t> deletedObjects_;
+  };
+
+  // ================= Specialisation declarations
+  
+//   template <> _NetworkExport void Synchronisable::registerVariable( const std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  template <> _NetworkExport void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional);
+  
+  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    if (bidirectional)
+    {
+      syncList.push_back(new SynchronisableVariableBidirectional<const T>(variable, mode, cb));
+      this->dataSize_ += syncList.back()->getSize(state_);
+    }
+    else
+    {
+      syncList.push_back(new SynchronisableVariable<const T>(variable, mode, cb));
+      if ( this->state_ == mode )
+        this->dataSize_ += syncList.back()->getSize(state_);
+    }
+  }
+  
+
+
+//   template <class T> void Synchronisable::unregisterVariable(T& var){
+//     std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin();
+//     while(it!=syncList.end()){
+//       if( ((*it)->getReference()) == &var ){
+//         delete (*it);
+//         syncList.erase(it);
+//         return;
+//       }
+//       else
+//         it++;
+//     }
+//     bool unregistered_nonexistent_variable = false;
+//     assert(unregistered_nonexistent_variable); //if we reach this point something went wrong:
+//     // the variable has not been registered before
+//   }
+
+  
+}
+
+#endif /* _Synchronisable_H__ */
Index: code/trunk/src/libraries/network/synchronisable/SynchronisableSpecialisations.cc
===================================================================
--- code/trunk/src/libraries/network/synchronisable/SynchronisableSpecialisations.cc	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/SynchronisableSpecialisations.cc	(revision 5781)
@@ -0,0 +1,111 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Dumeni Manatschal, (C) 2007
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include <string>
+#include "util/Math.h"
+#include "Synchronisable.h"
+#include "SynchronisableVariable.h"
+
+// ================ template spezialisation
+  
+  
+namespace orxonox{
+  
+  template <> void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    SynchronisableVariableBase* sv;
+    if (bidirectional)
+      sv = new SynchronisableVariableBidirectional<const std::string>(variable, mode, cb);
+    else
+      sv = new SynchronisableVariable<const std::string>(variable, mode, cb);
+    syncList.push_back(sv);
+    stringList.push_back(sv);
+  }
+  
+  template <> void Synchronisable::registerVariable( const ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.r, mode, cb, bidirectional);
+    registerVariable(variable.g, mode, cb, bidirectional);
+    registerVariable(variable.b, mode, cb, bidirectional);
+    registerVariable(variable.a, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( ColourValue& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    return Synchronisable::registerVariable( (const ColourValue&)variable, mode, cb, bidirectional);
+  }
+
+  template <> void Synchronisable::registerVariable( const Vector2& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+  }
+  
+  template <> void Synchronisable::registerVariable( const Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+    registerVariable(variable.z, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Vector3& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const Vector3&)variable, mode, cb, bidirectional);
+  }
+
+  template <> void Synchronisable::registerVariable( const Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+    registerVariable(variable.z, mode, cb, bidirectional);
+    registerVariable(variable.w, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Vector4& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const Vector4&)variable, mode, cb, bidirectional);
+  }
+  
+  template <> void Synchronisable::registerVariable( mbool& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.getMemory(), mode, cb, bidirectional);
+  }
+  
+  template <> void Synchronisable::registerVariable( const Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable(variable.x, mode, cb, bidirectional);
+    registerVariable(variable.y, mode, cb, bidirectional);
+    registerVariable(variable.z, mode, cb, bidirectional);
+    registerVariable(variable.w, mode, cb, bidirectional);
+  }
+  template <> void Synchronisable::registerVariable( Quaternion& variable, uint8_t mode, NetworkCallbackBase* cb, bool bidirectional)
+  {
+    registerVariable( (const Quaternion&)variable, mode, cb, bidirectional);
+  }
+
+  
+
+} //namespace
Index: code/trunk/src/libraries/network/synchronisable/SynchronisableVariable.cc
===================================================================
--- code/trunk/src/libraries/network/synchronisable/SynchronisableVariable.cc	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/SynchronisableVariable.cc	(revision 5781)
@@ -0,0 +1,36 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SynchronisableVariable.h"
+
+namespace orxonox{
+
+uint8_t SynchronisableVariableBase::state_ = 0;
+
+
+} //namespace
Index: code/trunk/src/libraries/network/synchronisable/SynchronisableVariable.h
===================================================================
--- code/trunk/src/libraries/network/synchronisable/SynchronisableVariable.h	(revision 5781)
+++ code/trunk/src/libraries/network/synchronisable/SynchronisableVariable.h	(revision 5781)
@@ -0,0 +1,258 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _SynchronisableVariable_H__
+#define _SynchronisableVariable_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include "util/Serialise.h"
+#include "util/TypeTraits.h"
+#include "core/GameMode.h"
+#include "network/synchronisable/NetworkCallbackManager.h"
+
+namespace orxonox{
+  
+  namespace VariableDirection{
+    enum Value{
+      ToClient=0x1,
+      ToServer=0x2
+    };
+  }
+  namespace Bidirectionality{
+    enum Value{
+      ServerMaster=0x1,
+      ClientMaster=0x2
+    };
+  }
+  
+  class _NetworkExport SynchronisableVariableBase
+  {
+    public:
+      virtual uint32_t getData(uint8_t*& mem, uint8_t mode)=0;
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false)=0;
+      virtual uint32_t getSize(uint8_t mode)=0;
+      virtual void* getReference()=0;
+      virtual uint8_t getMode()=0;
+      virtual ~SynchronisableVariableBase() {}
+    protected:
+      static uint8_t state_;
+  };
+
+  template <class T>
+  class SynchronisableVariable: public SynchronisableVariableBase
+  {
+    public:
+      SynchronisableVariable(T& variable, uint8_t syncDirection=VariableDirection::ToClient, NetworkCallbackBase *cb=0);
+      virtual ~SynchronisableVariable();
+
+      virtual inline uint8_t getMode(){ return mode_; }
+      virtual inline uint32_t getData(uint8_t*& mem, uint8_t mode);
+      virtual inline void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+      virtual inline void* getReference(){ return static_cast<void*>(const_cast<typename Loki::TypeTraits<T>::UnqualifiedType*>(&this->variable_)); }
+    protected:
+      
+      T& variable_;
+      uint8_t mode_;
+      NetworkCallbackBase *callback_;
+  };
+  
+  template <class T>
+  class SynchronisableVariableBidirectional: public SynchronisableVariable<T>
+  {
+    public:
+      SynchronisableVariableBidirectional(T& variable, uint8_t master=Bidirectionality::ServerMaster, NetworkCallbackBase *cb=0);
+      virtual ~SynchronisableVariableBidirectional();
+      
+      virtual inline uint8_t getMode(){ return 0x3; } //this basically is a hack ^^
+      virtual inline uint32_t getData(uint8_t*& mem, uint8_t mode);
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+    private:
+      T varBuffer_;
+      uint8_t varReference_;
+  };
+
+  // ================= Unidirectional Part ===============
+
+  template <class T> SynchronisableVariable<T>::SynchronisableVariable(T& variable, uint8_t syncDirection, NetworkCallbackBase *cb):
+      variable_( variable ), mode_( syncDirection ), callback_( cb )
+  {
+    if ( state_ == 0x0 )
+    {
+      state_ = GameMode::isMaster() ? 0x1 : 0x2;  // set the appropriate mode here
+    }
+  }
+  
+  template <class T> SynchronisableVariable<T>::~SynchronisableVariable()
+  {
+    if (this->callback_ != 0)
+    {
+      NetworkCallbackManager::deleteCallback(this->callback_); //safe call for deletion
+      // this is neccessary because for example for a Vector3 all 3 components of the vector use the same callback
+    }
+  }
+
+  template <class T> inline uint32_t SynchronisableVariable<T>::getData(uint8_t*& mem, uint8_t mode)
+  {
+    if ( mode == this->mode_ )
+    {
+      saveAndIncrease( this->variable_, mem );
+      return returnSize( this->variable_ );
+    }
+    else
+      return 0;
+  }
+
+  template <class T> void SynchronisableVariable<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
+  {
+    assert ( mode == 0x1 || mode == 0x2 );
+    bool callback = false;
+    if ( mode == this->mode_ ) //don't do anything
+      return;
+  // check whether we need to consider a callback
+    if ( this->callback_ != 0 )
+    {
+      if( forceCallback || !checkEquality( this->variable_, mem ) )
+        callback = true;
+    }
+  // write the data
+    loadAndIncrease( this->variable_, mem );
+  // now do a callback if neccessary
+    if ( callback )
+      NetworkCallbackManager::triggerCallback( this->callback_ );
+  }
+
+  template <class T> inline uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
+  {
+    if ( mode == this->mode_ )
+      return returnSize( this->variable_ );
+    else
+      return 0;
+  }
+
+
+
+
+// ================= Bidirectional Part ================
+
+    template <class T> SynchronisableVariableBidirectional<T>::SynchronisableVariableBidirectional(T& variable, uint8_t master, NetworkCallbackBase *cb):
+    SynchronisableVariable<T>( variable, master, cb ), varBuffer_( variable ), varReference_( 0 )
+    {
+    }
+
+    template <class T> SynchronisableVariableBidirectional<T>::~SynchronisableVariableBidirectional()
+    {
+    }
+
+    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
+    {
+      if ( this->mode_ == mode )
+      {   // we are master for this variable and have to check whether to change the varReference
+        if( this->varBuffer_ != this->variable_ )
+        {
+          this->varReference_++;
+          memcpy(static_cast<void*>(const_cast<typename Loki::TypeTraits<T>::UnqualifiedType*>(&this->varBuffer_)), &this->variable_, sizeof(this->variable_));
+        }
+      }
+  // write the reference number to the stream
+      *static_cast<uint8_t*>(mem) = varReference_;
+      mem += sizeof(this->varReference_);
+  // now write the content
+      saveAndIncrease( this->variable_, mem );
+      return SynchronisableVariableBidirectional::getSize(mode);
+    }
+
+    template <class T> void SynchronisableVariableBidirectional<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
+    {
+      bool callback = false;
+      if ( this->mode_ == mode )
+      {   //        MASTER
+        // check that the client (source of the data) has a recent version of this variable
+        if ( *static_cast<uint8_t*>(mem) != this->varReference_ )
+        { // wrong reference number, so discard the data
+//           COUT(0) << "discharding data" << endl;
+          mem += getSize( mode ); // SynchronisableVariableBidirectional::getSize returns size of variable + reference
+          return;
+        }
+        else{
+          // apply data
+          if ( checkEquality( this->variable_, mem+sizeof(varReference_) )==true )
+          {
+            mem += getSize( mode );
+            return;
+          }
+          else
+          {
+            mem += sizeof(varReference_);
+            memcpy(static_cast<void*>(const_cast<typename Loki::TypeTraits<T>::UnqualifiedType*>(&this->varBuffer_)), &this->variable_, sizeof(T));
+            if ( this->callback_ != 0 )
+              callback = true;
+          }
+        }
+      }
+      else
+      {   // we are slave for this variable
+        if (*static_cast<uint8_t*>(mem) == this->varReference_ && !forceCallback)
+        {
+          mem += getSize( mode ); //just skip the variable because nothing changed
+          return;
+        }
+        else
+        {
+          this->varReference_ = *static_cast<uint8_t*>(mem);
+          mem += sizeof(varReference_);
+          if ( checkEquality( this->variable_, mem ) == false )
+          {
+            // value changed so remark for callback
+            if ( this->callback_ != 0 )
+              callback = true;
+          }
+        }
+      }
+  // now write the data
+      loadAndIncrease(this->variable_, mem);
+  // now do a callback if neccessary
+      if ( callback )
+        NetworkCallbackManager::triggerCallback( this->callback_ );
+    }
+
+    template <class T> inline uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
+    {
+      return returnSize( this->variable_ ) + sizeof(varReference_);
+    }
+  
+
+}
+
+
+#endif /* _SynchronisableVariable_H__ */
Index: code/trunk/src/libraries/tools/BillboardSet.cc
===================================================================
--- code/trunk/src/libraries/tools/BillboardSet.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/BillboardSet.cc	(revision 5781)
@@ -0,0 +1,174 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "BillboardSet.h"
+
+#include <cassert>
+#include <string>
+#include <sstream>
+#include <OgreSceneManager.h>
+#include <OgreBillboardSet.h>
+#include <OgreBillboard.h>
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include "util/StringUtils.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    unsigned int BillboardSet::billboardSetCounter_s = 0;
+
+    BillboardSet::BillboardSet()
+    {
+        this->billboardSet_ = 0;
+    }
+
+    BillboardSet::~BillboardSet()
+    {
+        this->destroyBillboardSet();
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, int count)
+    {
+        this->setBillboardSet(scenemanager, file, Vector3::ZERO, count);
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, int count)
+    {
+        this->setBillboardSet(scenemanager, file, colour, Vector3::ZERO, count);
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const Vector3& position, int count)
+    {
+        assert(scenemanager);
+        this->destroyBillboardSet();
+
+        try
+        {
+            if (GameMode::showsGraphics())
+            {
+                this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + multi_cast<std::string>(BillboardSet::billboardSetCounter_s++), count);
+                this->billboardSet_->createBillboard(position);
+                this->billboardSet_->setMaterialName(file);
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Couln't load billboard \"" << file << "\"" << std::endl;
+            this->billboardSet_ = 0;
+        }
+
+        this->scenemanager_ = scenemanager;
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, const Vector3& position, int count)
+    {
+        assert(scenemanager);
+        this->destroyBillboardSet();
+
+        try
+        {
+            if (GameMode::showsGraphics())
+            {
+                this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + multi_cast<std::string>(BillboardSet::billboardSetCounter_s++), count);
+                this->billboardSet_->createBillboard(position, colour);
+                this->billboardSet_->setMaterialName(file);
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Couln't load billboard \"" << file << "\"" << std::endl;
+            this->billboardSet_ = 0;
+        }
+
+        this->scenemanager_ = scenemanager;
+    }
+
+    void BillboardSet::destroyBillboardSet()
+    {
+        if (this->billboardSet_ && this->scenemanager_)
+            this->scenemanager_->destroyBillboardSet(this->billboardSet_);
+        this->billboardSet_ = 0;
+    }
+
+    const std::string& BillboardSet::getName() const
+    {
+        if (this->billboardSet_)
+            return this->billboardSet_->getName();
+        else
+            return BLANKSTRING;
+    }
+
+    void BillboardSet::setVisible(bool visible)
+    {
+        if (this->billboardSet_)
+            this->billboardSet_->setVisible(visible);
+    }
+
+    bool BillboardSet::getVisible() const
+    {
+        if (this->billboardSet_)
+            return this->billboardSet_->getVisible();
+        else
+            return false;
+    }
+
+    void BillboardSet::setColour(const ColourValue& colour)
+    {
+        if (this->billboardSet_)
+        {
+            for (int i = 0; i < this->billboardSet_->getNumBillboards(); ++i)
+                this->billboardSet_->getBillboard(i)->setColour(colour);
+        }
+    }
+
+    const ColourValue& BillboardSet::getColour() const
+    {
+        if (this->billboardSet_ && this->billboardSet_->getNumBillboards() > 0)
+        {
+            return this->billboardSet_->getBillboard(0)->getColour();
+        }
+        else
+            return ColourValue::White;
+    }
+
+    void BillboardSet::setMaterial(const std::string& material)
+    {
+        if (this->billboardSet_)
+            this->billboardSet_->setMaterialName(material);
+    }
+
+    const std::string& BillboardSet::getMaterial() const
+    {
+        if (this->billboardSet_)
+            return this->billboardSet_->getMaterialName();
+        else
+            return BLANKSTRING;
+    }
+}
Index: code/trunk/src/libraries/tools/BillboardSet.h
===================================================================
--- code/trunk/src/libraries/tools/BillboardSet.h	(revision 5781)
+++ code/trunk/src/libraries/tools/BillboardSet.h	(revision 5781)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BillboardSet_H__
+#define _BillboardSet_H__
+
+#include "tools/ToolsPrereqs.h"
+#include "util/OgreForwardRefs.h"
+
+namespace orxonox
+{
+    class _ToolsExport BillboardSet
+    {
+        public:
+            BillboardSet();
+            ~BillboardSet();
+
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const Vector3& position, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, const Vector3& position, int count = 1);
+
+            inline Ogre::BillboardSet* getBillboardSet()
+                { return this->billboardSet_; }
+            inline Ogre::SceneManager* getSceneManager() const
+                { return this->scenemanager_; }
+
+            const std::string& getName() const;
+
+            void setVisible(bool visible);
+            bool getVisible() const;
+
+            void setColour(const ColourValue& colour);
+            const ColourValue& getColour() const;
+
+            void setMaterial(const std::string& material);
+            const std::string& getMaterial() const;
+
+        private:
+            void destroyBillboardSet();
+
+            Ogre::BillboardSet* billboardSet_;
+            Ogre::SceneManager* scenemanager_;
+
+            static unsigned int billboardSetCounter_s;
+    };
+}
+
+#endif /* _BillboardSet_H__ */
Index: code/trunk/src/libraries/tools/BulletConversions.h
===================================================================
--- code/trunk/src/libraries/tools/BulletConversions.h	(revision 5781)
+++ code/trunk/src/libraries/tools/BulletConversions.h	(revision 5781)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BulletConversions_H__
+#define _BulletConversions_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include <LinearMath/btQuaternion.h>
+#include <LinearMath/btVector3.h>
+
+namespace orxonox
+{
+    // Vector3 to btVector3
+    template <>
+    struct ConverterExplicit<orxonox::Vector3, btVector3>
+    {
+        FORCEINLINE static bool convert(btVector3* output, const orxonox::Vector3& input)
+        {
+            output->setX(input.x);
+            output->setY(input.y);
+            output->setZ(input.z);
+            return true;
+        }
+    };
+
+    // btVector3 to Vector3
+    template <>
+    struct ConverterExplicit<btVector3, orxonox::Vector3>
+    {
+        FORCEINLINE static bool convert(orxonox::Vector3* output, const btVector3& input)
+        {
+            output->x = input.x();
+            output->y = input.y();
+            output->z = input.z();
+            return true;
+        }
+    };
+
+    // Quaternion to btQuaternion
+    template <>
+    struct ConverterExplicit<orxonox::Quaternion, btQuaternion>
+    {
+        FORCEINLINE static bool convert(btQuaternion* output, const orxonox::Quaternion& input)
+        {
+            output->setW(input.w);
+            output->setX(input.x);
+            output->setY(input.y);
+            output->setZ(input.z);
+            return true;
+        }
+    };
+
+    // btQuaternion to Vector3
+    template <>
+    struct ConverterExplicit<btQuaternion, orxonox::Quaternion>
+    {
+        FORCEINLINE static bool convert(orxonox::Quaternion* output, const btQuaternion& input)
+        {
+            output->w = input.w();
+            output->x = input.x();
+            output->y = input.y();
+            output->z = input.z();
+            return true;
+        }
+    };
+}
+
+#endif /* _BulletConversions_H__ */
Index: code/trunk/src/libraries/tools/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/tools/CMakeLists.txt	(revision 5781)
+++ code/trunk/src/libraries/tools/CMakeLists.txt	(revision 5781)
@@ -0,0 +1,24 @@
+ADD_SOURCE_FILES(TOOLS_SRC_FILES
+  BillboardSet.cc
+  DynamicLines.cc
+  DynamicRenderable.cc
+  Mesh.cc
+  ParticleInterface.cc
+  ResourceCollection.cc
+  ResourceLocation.cc
+  Shader.cc
+  TextureGenerator.cc
+  Timer.cc
+)
+ADD_SUBDIRECTORY(interfaces)
+
+ORXONOX_ADD_LIBRARY(tools
+  FIND_HEADER_FILES
+  PCH_FILE
+    ToolsPrecompiledHeaders.h
+  DEFINE_SYMBOL
+    "TOOLS_SHARED_BUILD"
+  LINK_LIBRARIES
+    core
+  SOURCE_FILES ${TOOLS_SRC_FILES}
+)
Index: code/trunk/src/libraries/tools/DynamicLines.cc
===================================================================
--- code/trunk/src/libraries/tools/DynamicLines.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/DynamicLines.cc	(revision 5781)
@@ -0,0 +1,178 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Baxissimo, Emmeran, DWORD, EtherDrive (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DynamicLines.h"
+
+#include <cassert>
+#include <cmath>
+
+namespace Ogre
+{
+    enum
+    {
+        POSITION_BINDING,
+        TEXCOORD_BINDING
+    };
+
+    DynamicLines::DynamicLines(OperationType opType)
+    {
+        initialize(opType,false);
+        setMaterial("BaseWhiteNoLighting");
+        mDirty = true;
+    }
+
+    DynamicLines::~DynamicLines()
+    {
+    }
+
+    void DynamicLines::setOperationType(OperationType opType)
+    {
+        mRenderOp.operationType = opType;
+    }
+
+    RenderOperation::OperationType DynamicLines::getOperationType() const
+    {
+        return mRenderOp.operationType;
+    }
+
+    void DynamicLines::addPoint(const Vector3 &p)
+    {
+        mPoints.push_back(p);
+        mDirty = true;
+    }
+
+    void DynamicLines::addPoint(Real x, Real y, Real z)
+    {
+        mPoints.push_back(Vector3(x,y,z));
+        mDirty = true;
+    }
+
+    const Vector3& DynamicLines::getPoint(unsigned short index) const
+    {
+        assert(index < mPoints.size() && "Point index is out of bounds!!");
+        return mPoints[index];
+    }
+
+    unsigned short DynamicLines::getNumPoints(void) const
+    {
+        return (unsigned short)mPoints.size();
+    }
+
+    void DynamicLines::setPoint(unsigned short index, const Vector3 &value)
+    {
+        assert(index < mPoints.size() && "Point index is out of bounds!!");
+
+        mPoints[index] = value;
+        mDirty = true;
+    }
+
+    void DynamicLines::clear()
+    {
+        mPoints.clear();
+        mDirty = true;
+    }
+
+    void DynamicLines::update()
+    {
+        if (mDirty)
+            fillHardwareBuffers();
+    }
+
+    void DynamicLines::createVertexDeclaration()
+    {
+        VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
+        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
+    }
+
+    void DynamicLines::fillHardwareBuffers()
+    {
+        int size = mPoints.size();
+
+        prepareHardwareBuffers(size,0);
+
+        if (!size)
+        {
+            mBox.setExtents(Vector3::ZERO,Vector3::ZERO);
+            mDirty=false;
+            return;
+        }
+
+        Vector3 vaabMin = mPoints[0];
+        Vector3 vaabMax = mPoints[0];
+
+        HardwareVertexBufferSharedPtr vbuf =
+            mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
+
+        Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
+        for (int i = 0; i < size; i++)
+        {
+            *prPos++ = mPoints[i].x;
+            *prPos++ = mPoints[i].y;
+            *prPos++ = mPoints[i].z;
+
+            if (mPoints[i].x < vaabMin.x)
+                vaabMin.x = mPoints[i].x;
+            if (mPoints[i].y < vaabMin.y)
+                vaabMin.y = mPoints[i].y;
+            if (mPoints[i].z < vaabMin.z)
+                vaabMin.z = mPoints[i].z;
+
+            if (mPoints[i].x > vaabMax.x)
+                vaabMax.x = mPoints[i].x;
+            if (mPoints[i].y > vaabMax.y)
+                vaabMax.y = mPoints[i].y;
+            if (mPoints[i].z > vaabMax.z)
+                vaabMax.z = mPoints[i].z;
+        }
+        vbuf->unlock();
+
+        mBox.setExtents(vaabMin, vaabMax);
+
+        mDirty = false;
+    }
+
+    /*
+    void DynamicLines::getWorldTransforms(Matrix4 *xform) const
+    {
+        // return identity matrix to prevent parent transforms
+        *xform = Matrix4::IDENTITY;
+    }
+    */
+
+    /*
+    const Quaternion &DynamicLines::getWorldOrientation(void) const
+    {
+        return Quaternion::IDENTITY;
+    }
+
+    const Vector3 &DynamicLines::getWorldPosition(void) const
+    {
+        return Vector3::ZERO;
+    }
+    */
+}
Index: code/trunk/src/libraries/tools/DynamicLines.h
===================================================================
--- code/trunk/src/libraries/tools/DynamicLines.h	(revision 5781)
+++ code/trunk/src/libraries/tools/DynamicLines.h	(revision 5781)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Baxissimo, Emmeran, DWORD, EtherDrive (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DynamicLines_H__
+#define _DynamicLines_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <vector>
+#include "DynamicRenderable.h"
+
+namespace Ogre
+{
+    class _ToolsExport DynamicLines : public DynamicRenderable
+    {
+        typedef RenderOperation::OperationType OperationType;
+
+    public:
+        /// Constructor - see setOperationType() for description of argument.
+        DynamicLines(OperationType opType = RenderOperation::OT_LINE_STRIP);
+        virtual ~DynamicLines();
+
+        /// Add a point to the point list
+        void addPoint(const Vector3 &p);
+        /// Add a point to the point list
+        void addPoint(Real x, Real y, Real z);
+
+        /// Change the location of an existing point in the point list
+        void setPoint(unsigned short index, const Vector3 &value);
+
+        /// Return the location of an existing point in the point list
+        const Vector3& getPoint(unsigned short index) const;
+
+        /// Return the total number of points in the point list
+        unsigned short getNumPoints(void) const;
+
+        /// Remove all points from the point list
+        void clear();
+
+        /// Call this to update the hardware buffer after making changes.
+        void update();
+
+        /**
+        @brief
+            Set the type of operation to draw with.
+        @param opType
+            Can be one of
+                - RenderOperation::OT_LINE_STRIP
+                - RenderOperation::OT_LINE_LIST
+                - RenderOperation::OT_POINT_LIST
+                - RenderOperation::OT_TRIANGLE_LIST
+                - RenderOperation::OT_TRIANGLE_STRIP
+                - RenderOperation::OT_TRIANGLE_FAN
+            The default is OT_LINE_STRIP.
+        */
+        void setOperationType(OperationType opType);
+        OperationType getOperationType() const;
+
+    protected:
+        /// Implementation DynamicRenderable, creates a simple vertex-only decl
+        virtual void createVertexDeclaration();
+        /// Implementation DynamicRenderable, pushes point list out to hardware memory
+        virtual void fillHardwareBuffers();
+
+    private:
+        std::vector<Vector3> mPoints;
+        bool mDirty;
+    };
+}
+
+#endif /* _DynamicLines_H__ */
Index: code/trunk/src/libraries/tools/DynamicRenderable.cc
===================================================================
--- code/trunk/src/libraries/tools/DynamicRenderable.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/DynamicRenderable.cc	(revision 5781)
@@ -0,0 +1,160 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Sinbad, Baxissimo, DWORD, TheBren (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DynamicRenderable.h"
+
+#include <OgreCamera.h>
+#include <OgreHardwareBufferManager.h>
+
+namespace Ogre
+{
+    DynamicRenderable::DynamicRenderable()
+    {
+    }
+
+    DynamicRenderable::~DynamicRenderable()
+    {
+        delete mRenderOp.vertexData;
+        delete mRenderOp.indexData;
+    }
+
+    void DynamicRenderable::initialize(RenderOperation::OperationType operationType,
+           bool useIndices)
+    {
+        // Initialize render operation
+        mRenderOp.operationType = operationType;
+        mRenderOp.useIndexes = useIndices;
+        mRenderOp.vertexData = new VertexData;
+        if (mRenderOp.useIndexes)
+            mRenderOp.indexData = new IndexData;
+
+        // Reset buffer capacities
+        mVertexBufferCapacity = 0;
+        mIndexBufferCapacity = 0;
+
+        // Create vertex declaration
+        createVertexDeclaration();
+    }
+
+    void DynamicRenderable::prepareHardwareBuffers(size_t vertexCount, size_t indexCount)
+    {
+        // Prepare vertex buffer
+        size_t newVertCapacity = mVertexBufferCapacity;
+        if ((vertexCount > mVertexBufferCapacity) || (!mVertexBufferCapacity))
+        {
+            // vertexCount exceeds current capacity!
+            // It is necessary to reallocate the buffer.
+
+            // Check if this is the first call
+            if (!newVertCapacity)
+                newVertCapacity = 1;
+
+            // Make capacity the next power of two
+            while (newVertCapacity < vertexCount)
+                newVertCapacity <<= 1;
+        }
+        else if (vertexCount < mVertexBufferCapacity>>1)
+        {
+            // Make capacity the previous power of two
+            while (vertexCount < newVertCapacity>>1)
+                newVertCapacity >>= 1;
+        }
+        if (newVertCapacity != mVertexBufferCapacity)
+        {
+            mVertexBufferCapacity = newVertCapacity;
+            // Create new vertex buffer
+            HardwareVertexBufferSharedPtr vbuf =
+                HardwareBufferManager::getSingleton().createVertexBuffer(
+                mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
+                mVertexBufferCapacity,
+                HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
+
+            // Bind buffer
+            mRenderOp.vertexData->vertexBufferBinding->setBinding(0, vbuf);
+        }
+        // Update vertex count in the render operation
+        mRenderOp.vertexData->vertexCount = vertexCount;
+
+        if (mRenderOp.useIndexes)
+        {
+            OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit");
+
+            size_t newIndexCapacity = mIndexBufferCapacity;
+            // Prepare index buffer
+            if ((indexCount > newIndexCapacity) || (!newIndexCapacity))
+            {
+                // indexCount exceeds current capacity!
+                // It is necessary to reallocate the buffer.
+
+                // Check if this is the first call
+                if (!newIndexCapacity)
+                    newIndexCapacity = 1;
+
+                // Make capacity the next power of two
+                while (newIndexCapacity < indexCount)
+                    newIndexCapacity <<= 1;
+            }
+            else if (indexCount < newIndexCapacity>>1)
+            {
+                // Make capacity the previous power of two
+                while (indexCount < newIndexCapacity>>1)
+                    newIndexCapacity >>= 1;
+            }
+
+            if (newIndexCapacity != mIndexBufferCapacity)
+            {
+                mIndexBufferCapacity = newIndexCapacity;
+                // Create new index buffer
+                mRenderOp.indexData->indexBuffer =
+                    HardwareBufferManager::getSingleton().createIndexBuffer(
+                    HardwareIndexBuffer::IT_16BIT,
+                    mIndexBufferCapacity,
+                    HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
+            }
+
+            // Update index count in the render operation
+            mRenderOp.indexData->indexCount = indexCount;
+        }
+    }
+
+    Real DynamicRenderable::getBoundingRadius(void) const
+    {
+        return Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
+    }
+
+    Real DynamicRenderable::getSquaredViewDepth(const Camera* cam) const
+    {
+        Vector3 vMin, vMax, vMid, vDist;
+        vMin = mBox.getMinimum();
+        vMax = mBox.getMaximum();
+        vMid = ((vMax - vMin) * 0.5) + vMin;
+        vDist = cam->getDerivedPosition() - vMid;
+
+        return vDist.squaredLength();
+    }
+}
Index: code/trunk/src/libraries/tools/DynamicRenderable.h
===================================================================
--- code/trunk/src/libraries/tools/DynamicRenderable.h	(revision 5781)
+++ code/trunk/src/libraries/tools/DynamicRenderable.h	(revision 5781)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Sinbad, Baxissimo, DWORD, TheBren (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DynamicRenderable_H__
+#define _DynamicRenderable_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <OgreSimpleRenderable.h>
+
+namespace Ogre
+{
+    /// Abstract base class providing mechanisms for dynamically growing hardware buffers.
+    class _ToolsExport DynamicRenderable : public SimpleRenderable
+    {
+    public:
+        /// Constructor
+        DynamicRenderable();
+        /// Virtual destructor
+        virtual ~DynamicRenderable();
+
+        /**
+        @brief
+            Initializes the dynamic renderable.
+        @remarks
+            This function should only be called once. It initializes the
+            render operation, and calls the abstract function
+            createVertexDeclaration().
+        @param operationType
+            The type of render operation to perform.
+        @param useIndices
+            Specifies whether to use indices to determine the vertices to use as input.
+        */
+        void initialize(RenderOperation::OperationType operationType,
+        bool useIndices);
+
+        /// Implementation of SimpleRenderable
+        virtual Real getBoundingRadius(void) const;
+        /// Implementation of SimpleRenderable
+        virtual Real getSquaredViewDepth(const Camera* cam) const;
+
+    protected:
+        /// Maximum capacity of the currently allocated vertex buffer.
+        size_t mVertexBufferCapacity;
+        /// Maximum capacity of the currently allocated index buffer.
+        size_t mIndexBufferCapacity;
+
+        /**
+        @brief
+            Creates the vertex declaration.
+        @remarks
+            Override and set mRenderOp.vertexData->vertexDeclaration here.
+            mRenderOp.vertexData will be created for you before this method
+            is called.
+        */
+        virtual void createVertexDeclaration() = 0;
+
+        /**
+        @brief
+            Prepares the hardware buffers for the requested vertex and index counts.
+        @remarks
+            This function must be called before locking the buffers in
+            fillHardwareBuffers(). It guarantees that the hardware buffers
+            are large enough to hold at least the requested number of
+            vertices and indices (if using indices). The buffers are
+            possibly reallocated to achieve this.
+        @par
+            The vertex and index count in the render operation are set to
+            the values of vertexCount and indexCount respectively.
+        @param vertexCount
+            The number of vertices the buffer must hold.
+        @param indexCount
+            The number of indices the buffer must hold. This
+            parameter is ignored if not using indices.
+        */
+        void prepareHardwareBuffers(size_t vertexCount, size_t indexCount);
+
+        /**
+        @brief
+            Fills the hardware vertex and index buffers with data.
+        @remarks
+            This function must call prepareHardwareBuffers() before locking
+            the buffers to ensure the they are large enough for the data to
+            be written. Afterwards the vertex and index buffers (if using
+            indices) can be locked, and data can be written to them.
+        */
+        virtual void fillHardwareBuffers() = 0;
+    };
+}
+
+#endif /* _DynamicRenderable_H__ */
Index: code/trunk/src/libraries/tools/Mesh.cc
===================================================================
--- code/trunk/src/libraries/tools/Mesh.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/Mesh.cc	(revision 5781)
@@ -0,0 +1,120 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Mesh.h"
+
+#include <cassert>
+#include <sstream>
+#include <string>
+#include <OgreEntity.h>
+#include <OgreSceneManager.h>
+
+#include "util/Convert.h"
+#include "util/StringUtils.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    unsigned int Mesh::meshCounter_s = 0;
+
+    Mesh::Mesh()
+    {
+        this->entity_ = 0;
+        this->bCastShadows_ = true;
+    }
+
+    Mesh::~Mesh()
+    {
+        if (this->entity_ && this->scenemanager_)
+            this->scenemanager_->destroyEntity(this->entity_);
+    }
+
+    void Mesh::setMeshSource(Ogre::SceneManager* scenemanager, const std::string& meshsource)
+    {
+        assert(scenemanager);
+
+        this->scenemanager_ = scenemanager;
+
+        if (this->entity_)
+            this->scenemanager_->destroyEntity(this->entity_);
+
+        if (GameMode::showsGraphics())
+        {
+            try
+            {
+                this->entity_ = this->scenemanager_->createEntity("Mesh" + multi_cast<std::string>(Mesh::meshCounter_s++), meshsource);
+                this->entity_->setCastShadows(this->bCastShadows_);
+
+#if OGRE_VERSION < 0x010600
+                this->entity_->setNormaliseNormals(true);
+                /*
+                    Excerpt from Ogre forum:
+                    "Note that the above is only for the fixed function pipeline.
+                    If/when you get into shaders, you'll need to manually normalize() the normal inside the vertex or pixel shader."
+
+                    I don't know exactly what this means, but I put this here if there will be problems with shaders.
+                */
+#endif
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load mesh \"" << meshsource << "\"" << std::endl;
+                this->entity_ = 0;
+            }
+        }
+    }
+
+    void Mesh::setCastShadows(bool bCastShadows)
+    {
+        this->bCastShadows_ = bCastShadows;
+        if (this->entity_)
+            this->entity_->setCastShadows(this->bCastShadows_);
+    }
+
+    const std::string& Mesh::getName() const
+    {
+        if (this->entity_)
+            return this->entity_->getName();
+        else
+            return BLANKSTRING;
+    }
+
+    void Mesh::setVisible(bool bVisible)
+    {
+        if (this->entity_)
+            this->entity_->setVisible(bVisible);
+    }
+
+    bool Mesh::isVisible() const
+    {
+        if (this->entity_)
+            return this->entity_->getVisible();
+        else
+            return false;
+    }
+}
Index: code/trunk/src/libraries/tools/Mesh.h
===================================================================
--- code/trunk/src/libraries/tools/Mesh.h	(revision 5781)
+++ code/trunk/src/libraries/tools/Mesh.h	(revision 5781)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Mesh_H__
+#define _Mesh_H__
+
+#include "tools/ToolsPrereqs.h"
+#include "util/OgreForwardRefs.h"
+
+namespace orxonox
+{
+    class _ToolsExport Mesh
+    {
+        public:
+            Mesh();
+            ~Mesh();
+
+            void setMeshSource(Ogre::SceneManager* scenemanager, const std::string& file);
+
+            inline Ogre::Entity* getEntity()
+                { return this->entity_; }
+
+            const std::string& getName() const;
+
+            void setVisible(bool bVisible);
+            bool isVisible() const;
+
+            void setCastShadows(bool bCastShadows);
+            inline bool getCastShadows() const
+                { return this->bCastShadows_; }
+
+        private:
+            Ogre::Entity* entity_;
+            bool bCastShadows_;
+            Ogre::SceneManager* scenemanager_;
+
+            static unsigned int meshCounter_s;
+    };
+}
+
+#endif /* _Mesh_H__ */
Index: code/trunk/src/libraries/tools/ParticleInterface.cc
===================================================================
--- code/trunk/src/libraries/tools/ParticleInterface.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/ParticleInterface.cc	(revision 5781)
@@ -0,0 +1,231 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+* @file
+* @brief class to control praticle effects
+*/
+
+#include "ParticleInterface.h"
+
+#include <cassert>
+#include <string>
+#include <OgreParticleSystem.h>
+#include <OgreParticleEmitter.h>
+#include <OgreSceneManager.h>
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    unsigned int ParticleInterface::counter_s = 0;
+    ParticleInterface* ParticleInterface::currentParticleInterface_s = 0;
+
+    ParticleInterface::ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::Value detaillevel)
+    {
+        RegisterObject(ParticleInterface);
+
+        assert(scenemanager);
+
+        this->scenemanager_ = scenemanager;
+        this->particleSystem_ = 0;
+
+        this->bEnabled_ = true;
+        this->bVisible_ = true;
+        this->bAllowedByLOD_ = true;
+        this->speedFactor_ = 1.0f;
+
+        if (GameMode::showsGraphics())
+        {
+            try
+            {
+                this->particleSystem_ = this->scenemanager_->createParticleSystem("particles" + multi_cast<std::string>(ParticleInterface::counter_s++), templateName);
+                this->setSpeedFactor(1.0f);
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load particle system \"" << templateName << "\"" << std::endl;
+                this->particleSystem_ = 0;
+            }
+        }
+
+        this->setDetailLevel(static_cast<unsigned int>(detaillevel));
+    }
+
+    ParticleInterface::~ParticleInterface()
+    {
+        if (this->particleSystem_)
+        {
+            this->particleSystem_->removeAllEmitters();
+            this->scenemanager_->destroyParticleSystem(this->particleSystem_);
+        }
+    }
+
+    void ParticleInterface::setConfigValues()
+    {
+        SetConfigValue(globalDetailLevel_, 2)
+            .description("O: off, 1: low, 2: normal, 3: high").callback(this, &ParticleInterface::detailLevelChanged);
+    }
+
+    Ogre::ParticleEmitter* ParticleInterface::createNewEmitter()
+    {
+        if (this->particleSystem_ && this->particleSystem_->getNumEmitters() > 0)
+        {
+            Ogre::ParticleEmitter* newemitter = this->particleSystem_->addEmitter(this->particleSystem_->getEmitter(0)->getType());
+            this->particleSystem_->getEmitter(0)->copyParametersTo(newemitter);
+            return newemitter;
+        }
+        else
+            return 0;
+    }
+    Ogre::ParticleEmitter* ParticleInterface::getEmitter(unsigned int emitterNr) const
+    {
+        if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters()))
+            return this->particleSystem_->getEmitter(emitterNr);
+        else
+            return 0;
+    }
+    void ParticleInterface::removeEmitter(unsigned int emitterNr)
+    {
+        if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters()))
+            this->particleSystem_->removeEmitter(emitterNr);
+    }
+    void ParticleInterface::removeAllEmitters()
+    {
+        if (this->particleSystem_)
+            this->particleSystem_->removeAllEmitters();
+    }
+    unsigned int ParticleInterface::getNumEmitters() const
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->getNumEmitters();
+        else
+            return 0;
+    }
+
+    Ogre::ParticleAffector* ParticleInterface::addAffector(const std::string& name)
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->addAffector(name);
+        else
+            return 0;
+    }
+    Ogre::ParticleAffector* ParticleInterface::getAffector(unsigned int affectorNr)
+    {
+        if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors()))
+            return this->particleSystem_->getAffector(affectorNr);
+        else
+            return 0;
+    }
+    void ParticleInterface::removeAffector(unsigned int affectorNr)
+    {
+        if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors()))
+            this->particleSystem_->removeAffector(affectorNr);
+    }
+    void ParticleInterface::removeAllAffectors()
+    {
+        if (this->particleSystem_)
+            this->particleSystem_->removeAllAffectors();
+    }
+    unsigned int ParticleInterface::getNumAffectors() const
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->getNumAffectors();
+        else
+            return 0;
+    }
+
+    void ParticleInterface::setEnabled(bool enable)
+    {
+        this->bEnabled_ = enable;
+
+        if (this->particleSystem_)
+            for (unsigned int i = 0; i < this->particleSystem_->getNumEmitters(); i++)
+                this->particleSystem_->getEmitter(i)->setEnabled(this->bEnabled_ && this->bAllowedByLOD_);
+    }
+
+    void ParticleInterface::setVisible(bool visible)
+    {
+        this->bVisible_ = visible;
+
+        if (this->particleSystem_)
+            this->particleSystem_->setVisible(this->bVisible_ && this->bAllowedByLOD_);
+    }
+
+    void ParticleInterface::setDetailLevel(unsigned int level)
+    {
+        this->detaillevel_ = level;
+        if (GameMode::showsGraphics())
+            this->detailLevelChanged();
+    }
+
+    void ParticleInterface::detailLevelChanged()
+    {
+        if (this->globalDetailLevel_ >= this->detaillevel_)
+            this->bAllowedByLOD_ = true;
+        else
+            this->bAllowedByLOD_ = false;
+
+        this->updateVisibility();
+    }
+
+    void ParticleInterface::updateVisibility()
+    {
+        this->setEnabled(this->isEnabled());
+        this->setVisible(this->isVisible());
+    }
+
+    void ParticleInterface::setSpeedFactor(float factor)
+    {
+        this->speedFactor_ = factor;
+
+        if (this->particleSystem_)
+            this->particleSystem_->setSpeedFactor(factor * this->getTimeFactor());
+    }
+    void ParticleInterface::changedTimeFactor(float factor_new, float factor_old)
+    {
+        this->setSpeedFactor(this->speedFactor_);
+    }
+
+    bool ParticleInterface::getKeepParticlesInLocalSpace() const
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->getKeepParticlesInLocalSpace();
+        else
+            return false;
+    }
+    void ParticleInterface::setKeepParticlesInLocalSpace(bool keep)
+    {
+        if (this->particleSystem_)
+            this->particleSystem_->setKeepParticlesInLocalSpace(keep);
+    }
+}
Index: code/trunk/src/libraries/tools/ParticleInterface.h
===================================================================
--- code/trunk/src/libraries/tools/ParticleInterface.h	(revision 5781)
+++ code/trunk/src/libraries/tools/ParticleInterface.h	(revision 5781)
@@ -0,0 +1,110 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleInterface_H__
+#define _ParticleInterface_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/TimeFactorListener.h"
+
+#define getAllEmitters() \
+  storeThisAsCurrentParticleInterface(); \
+  for (unsigned int i = 0; i < ParticleInterface::getCurrentParticleInterface()->getNumEmitters(); ++i) \
+    ParticleInterface::getCurrentParticleInterface()->getEmitter(i)
+
+namespace orxonox
+{
+    class _ToolsExport ParticleInterface : public TimeFactorListener
+    {
+        public:
+            ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::Value detaillevel);
+            virtual ~ParticleInterface();
+            void setConfigValues();
+
+            inline Ogre::ParticleSystem* getParticleSystem()
+                { return this->particleSystem_; }
+
+            Ogre::ParticleEmitter* createNewEmitter();
+            Ogre::ParticleEmitter* getEmitter(unsigned int emitterNr) const;
+            void removeEmitter(unsigned int emitterNr);
+            void removeAllEmitters();
+            unsigned int getNumEmitters() const;
+
+            Ogre::ParticleAffector* addAffector(const std::string& name);
+            Ogre::ParticleAffector* getAffector(unsigned int affectorNr);
+            void removeAffector(unsigned int affectorNr);
+            void removeAllAffectors();
+            unsigned int getNumAffectors() const;
+
+            inline float getSpeedFactor() const
+                { return this->speedFactor_; }
+            void setSpeedFactor(float factor);
+            bool getKeepParticlesInLocalSpace() const;
+            void setKeepParticlesInLocalSpace(bool keep);
+
+            void setEnabled(bool enable);
+            inline bool isEnabled() const
+                { return this->bEnabled_; }
+
+            void setVisible(bool visible);
+            inline bool isVisible() const
+                { return this->bVisible_; }
+
+            void setDetailLevel(unsigned int level);
+
+            inline void storeThisAsCurrentParticleInterface()
+                { ParticleInterface::currentParticleInterface_s = this; }
+            inline static ParticleInterface* getCurrentParticleInterface()
+                { return ParticleInterface::currentParticleInterface_s; }
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old);
+
+        private:
+            void updateVisibility();
+            void detailLevelChanged();
+
+            Ogre::ParticleSystem*     particleSystem_;
+            Ogre::SceneManager*       scenemanager_;
+            bool                      bVisible_;
+            bool                      bEnabled_;
+            bool                      bAllowedByLOD_;
+            unsigned int              detaillevel_;       //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
+            float                     speedFactor_;
+
+            // config values
+            unsigned int              globalDetailLevel_; //!< Global maximum detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
+
+            static ParticleInterface* currentParticleInterface_s;
+            static unsigned int       counter_s;
+    };
+}
+
+#endif /* _ParticleInterface_H__ */
Index: code/trunk/src/libraries/tools/ResourceCollection.cc
===================================================================
--- code/trunk/src/libraries/tools/ResourceCollection.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/ResourceCollection.cc	(revision 5781)
@@ -0,0 +1,99 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ResourceCollection.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/Resource.h"
+#include "core/XMLPort.h"
+#include "ResourceLocation.h"
+
+namespace orxonox
+{
+    CreateFactory(ResourceCollection);
+
+    ResourceCollection::ResourceCollection(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(ResourceCollection);
+
+        // Default group is "General"
+        this->setResourceGroup(Resource::DEFAULT_GROUP);
+    }
+
+    ResourceCollection::~ResourceCollection()
+    {
+    }
+
+    void ResourceCollection::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        XMLPortParam(ResourceCollection, "resourceGroup", setResourceGroup, getResourceGroup, xmlElement, mode);
+        XMLPortObject(ResourceCollection, ResourceLocation, "", addResourceLocation, getResourceLocation, xmlElement, mode);
+    }
+
+    void ResourceCollection::setResourceGroup(const std::string& resourceGroup)
+    {
+        if (resourceGroup.empty())
+        {
+            COUT(2) << "Warning: \"\" is not a valid resource group." << std::endl;
+            return;
+        }
+        if (!resourceLocations_.empty())
+            ThrowException(InitialisationFailed, "ResourceGroup: Group change not allowed with locations already added!");
+        resourceGroup_ = resourceGroup;
+    }
+
+    void ResourceCollection::addResourceLocation(ResourceLocation* location)
+    {
+        location->load(resourceGroup_);
+        this->resourceLocations_.push_back(location);
+    }
+
+    void ResourceCollection::removeResourceLocation(ResourceLocation* location)
+    {
+        for (std::vector<ResourceLocation*>::iterator it = resourceLocations_.begin(); it != resourceLocations_.end(); )
+        {
+            if (*it == location)
+            {
+                it = resourceLocations_.erase(it);
+                location->unload(); // doesn't throw
+            }
+            else
+                ++it;
+        }
+    }
+
+    ResourceLocation* ResourceCollection::getResourceLocation(unsigned int index) const
+    {
+        if (index >= resourceLocations_.size())
+            return NULL;
+        else
+            return resourceLocations_[index];
+    }
+}
Index: code/trunk/src/libraries/tools/ResourceCollection.h
===================================================================
--- code/trunk/src/libraries/tools/ResourceCollection.h	(revision 5781)
+++ code/trunk/src/libraries/tools/ResourceCollection.h	(revision 5781)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ResourceCollection_H__
+#define _ResourceCollection_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class ResourceLocation;
+
+    class _ToolsExport ResourceCollection : public BaseObject
+    {
+    public:
+        ResourceCollection(BaseObject* creator);
+        virtual ~ResourceCollection();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setResourceGroup(const std::string& resourceGroup);
+        const std::string& getResourceGroup() const { return resourceGroup_; }
+
+        void addResourceLocation(ResourceLocation* location);
+        void removeResourceLocation(ResourceLocation* location);
+        ResourceLocation* getResourceLocation(unsigned int index) const;
+
+    private:
+        ResourceCollection(const ResourceCollection&);
+
+        std::string resourceGroup_;
+        std::vector<ResourceLocation*> resourceLocations_;
+    };
+}
+
+#endif /* _ResourceCollection_H__ */
Index: code/trunk/src/libraries/tools/ResourceLocation.cc
===================================================================
--- code/trunk/src/libraries/tools/ResourceLocation.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/ResourceLocation.cc	(revision 5781)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ResourceLocation.h"
+
+#include <OgreResourceGroupManager.h>
+#include <boost/filesystem.hpp>
+
+#include "util/Exception.h"
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLFile.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(ResourceLocation);
+
+    ResourceLocation::ResourceLocation(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(ResourceLocation);
+
+        // Default values
+        archiveType_ = "FileSystem";
+        bRecursive_  = true;
+    }
+
+    ResourceLocation::~ResourceLocation()
+    {
+    }
+
+    void ResourceLocation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        XMLPortParam(ResourceLocation, "path",        setPath,        getPath,        xmlElement, mode);
+        XMLPortParam(ResourceLocation, "archiveType", setArchiveType, getArchiveType, xmlElement, mode);
+        XMLPortParam(ResourceLocation, "recursive",   setRecursive,   getRecursive,   xmlElement, mode);
+        if (path_.empty())
+            ThrowException(AbortLoading, "ResourceLocation: No path given.");
+    }
+
+    void ResourceLocation::load(const std::string& resourceGroup)
+    {
+        if (path_.empty())
+            ThrowException(InitialisationFailed, "ResourceLocation: Trying to add one without the path being set");
+
+        // Find the path
+        boost::filesystem::path path;
+        if (boost::filesystem::exists(Core::getDataPath() / this->getPath()))
+            path = Core::getDataPath() / this->getPath();
+        else if (Core::isDevelopmentRun() && boost::filesystem::exists(Core::getExternalDataPath() / this->getPath()))
+            path = Core::getExternalDataPath() / this->getPath();
+        else
+        {
+            COUT(2) << "Warning: ResourceLocation '" << this->getPath() << "' does not seem to exist" << std::endl;
+            return;
+        }
+
+        // Add it to the Ogre paths
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
+            path.string(), this->getArchiveType(), resourceGroup, this->getRecursive());
+        resourceGroup_ = resourceGroup;
+    }
+
+    void ResourceLocation::unload()
+    {
+        // Remove from Ogre paths
+        resourceGroup_.erase();
+        try
+        {
+            Ogre::ResourceGroupManager::getSingleton().removeResourceLocation(
+                this->getPath(), this->getResourceGroup());
+        }
+        catch (...)
+        {
+            COUT(1) << "Removing of a ResourceLocation failed: " << Exception::handleMessage() << std::endl;
+        }
+    }
+}
Index: code/trunk/src/libraries/tools/ResourceLocation.h
===================================================================
--- code/trunk/src/libraries/tools/ResourceLocation.h	(revision 5781)
+++ code/trunk/src/libraries/tools/ResourceLocation.h	(revision 5781)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ResourceLocation_H__
+#define _ResourceLocation_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ToolsExport ResourceLocation : public BaseObject
+    {
+        // for load/unload
+        friend class ResourceCollection;
+
+    public:
+        ResourceLocation(BaseObject* creator);
+        virtual ~ResourceLocation();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setPath(const std::string& path) { path_ = path; }
+        const std::string& getPath() const { return path_; }
+
+        void setArchiveType(const std::string& archiveType) { archiveType_ = archiveType; }
+        const std::string& getArchiveType() const { return archiveType_; }
+
+        void setRecursive(bool bRecursive) { bRecursive_ = bRecursive; }
+        bool getRecursive() const { return bRecursive_; }
+
+        const std::string& getResourceGroup() const { return resourceGroup_; }
+
+    private:
+        ResourceLocation(const ResourceLocation&);
+
+        void load(const std::string& resourceGroup);
+        void unload();
+
+        std::string path_;
+        std::string archiveType_;
+        std::string resourceGroup_;
+        bool bRecursive_;
+    };
+}
+
+#endif /* _ResourceLocation_H__ */
Index: code/trunk/src/libraries/tools/Shader.cc
===================================================================
--- code/trunk/src/libraries/tools/Shader.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/Shader.cc	(revision 5781)
@@ -0,0 +1,332 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Shader.h"
+
+#include <OgreCompositorManager.h>
+#include <OgreCompositorInstance.h>
+#include <OgreSceneManager.h>
+#include <OgreRoot.h>
+#include <OgrePlugin.h>
+#include <OgreMaterial.h>
+#include <OgreTechnique.h>
+#include <OgrePass.h>
+#include <OgreMaterialManager.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/GraphicsManager.h"
+
+namespace orxonox
+{
+    bool Shader::bLoadedCgPlugin_s = false;
+    Shader::MaterialMap Shader::parameters_s;
+
+    Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
+    {
+        RegisterObject(Shader);
+
+        this->scenemanager_ = scenemanager;
+        this->compositorInstance_ = 0;
+        this->bVisible_ = true;
+        this->bLoadCompositor_ = GameMode::showsGraphics();
+        this->bViewportInitialized_ = false;
+        this->compositor_ = "";
+        this->oldcompositor_ = "";
+
+        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
+        {
+            Shader::bLoadedCgPlugin_s = false;
+            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
+            for (size_t i = 0; i < plugins.size(); ++i)
+            {
+                if (plugins[i]->getName() == "Cg Program Manager")
+                {
+                    Shader::bLoadedCgPlugin_s = true;
+                    break;
+                }
+            }
+        }
+
+        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
+    }
+
+    Shader::~Shader()
+    {
+
+        if (this->bLoadCompositor_ && this->compositorInstance_)
+        {
+            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
+            assert(viewport);
+            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
+        }
+
+    }
+
+    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
+    {
+        this->scenemanager_ = scenemanager;
+        this->bViewportInitialized_ = false;
+    }
+
+    void Shader::tick(float dt)
+    {
+        SUPER(Shader, tick, dt);
+
+        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
+        {
+            this->bViewportInitialized_ = true;
+            this->updateVisibility();
+        }
+    }
+
+    void Shader::changedCompositor()
+    {
+        if (this->bLoadCompositor_)
+        {
+            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
+            assert(viewport);
+            if (this->oldcompositor_ != "")
+            {
+                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
+                this->compositorInstance_ = 0;
+            }
+            if (this->compositor_ != "")
+            {
+                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
+                if (!this->compositorInstance_)
+                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
+                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
+            }
+            this->oldcompositor_ = this->compositor_;
+        }
+    }
+
+    void Shader::updateVisibility()
+    {
+        if (this->compositorInstance_ && this->scenemanager_)
+            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
+    }
+
+    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+    {
+        if (Shader::_setParameter(material, technique, pass, parameter, value))
+        {
+            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
+            {
+                this->compositorInstance_->setEnabled(false);
+                this->compositorInstance_->setEnabled(true);
+            }
+        }
+    }
+
+    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+    {
+        if (Shader::_setParameter(material, technique, pass, parameter, value))
+        {
+            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
+            {
+                this->compositorInstance_->setEnabled(false);
+                this->compositorInstance_->setEnabled(true);
+            }
+        }
+    }
+
+    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+        {
+            if (pointer->first)
+            {
+                if ((*static_cast<float*>(pointer->second)) != value)
+                {
+                    (*static_cast<float*>(pointer->second)) = value;
+                    return true;
+                }
+            }
+            else
+            {
+                if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
+                {
+                    (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+        {
+            if (pointer->first)
+            {
+                if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
+                {
+                    (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
+                    return true;
+                }
+            }
+            else
+            {
+                if ((*static_cast<int*>(pointer->second)) != value)
+                {
+                    (*static_cast<int*>(pointer->second)) = value;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+        {
+            if (pointer->first)
+                return (*static_cast<float*>(pointer->second));
+            else
+                return static_cast<float>(*static_cast<int*>(pointer->second));
+        }
+        else
+            return 0;
+    }
+
+    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+            return pointer->first;
+        else
+            return false;
+    }
+
+    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+            return (!pointer->first);
+        else
+            return false;
+    }
+
+    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
+            return 0;
+
+        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
+        if (material_iterator != Shader::parameters_s.end())
+        {
+            TechniqueVector& technique_vector = material_iterator->second;
+            if (technique < technique_vector.size())
+            {
+                PassVector& pass_vector = technique_vector[technique];
+                if (pass < pass_vector.size())
+                {
+                    ParameterMap& parameter_map = pass_vector[pass];
+                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
+
+                    if (parameter_iterator != parameter_map.end())
+                        return (&parameter_iterator->second);
+                    else
+                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
+                }
+                else
+                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
+            }
+            else
+                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
+        }
+        else
+        {
+            bool foundAtLeastOneShaderParameter = false;
+            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
+            Ogre::Material* material_pointer = 0;
+
+            while (iterator.hasMoreElements())
+            {
+                Ogre::Resource* resource = iterator.getNext().get();
+                if (resource->getName() == material)
+                    material_pointer = (Ogre::Material*)resource;
+            }
+
+            if (!material_pointer)
+            {
+                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
+                return 0;
+            }
+
+            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
+            {
+                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
+                if (!technique_pointer)
+                    continue;
+
+                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
+                {
+                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
+                    if (!pass_pointer)
+                        continue;
+
+                    if (pass_pointer->getFragmentProgramName() != "")
+                    {
+                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
+                        if (!parameter_pointer)
+                            continue;
+
+                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
+                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
+                        {
+                            void* temp = (definition_iterator->second.isFloat())
+                                            ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
+                                            : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
+                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
+
+                            TechniqueVector& technique_vector = Shader::parameters_s[material];
+                            technique_vector.resize(technique + 1);
+                            PassVector& pass_vector = technique_vector[technique];
+                            pass_vector.resize(pass + 1);
+                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
+                            foundAtLeastOneShaderParameter = true;
+                        }
+                    }
+                }
+            }
+
+            // recursive call if the material was added to the map
+            if (foundAtLeastOneShaderParameter)
+                return Shader::getParameterPointer(material, technique, pass, parameter);
+        }
+        return 0;
+    }
+}
Index: code/trunk/src/libraries/tools/Shader.h
===================================================================
--- code/trunk/src/libraries/tools/Shader.h	(revision 5781)
+++ code/trunk/src/libraries/tools/Shader.h	(revision 5781)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Shader_H__
+#define _Shader_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    class _ToolsExport Shader : public Tickable
+    {
+        typedef std::pair<bool, void*>                  ParameterPointer;
+        typedef std::map<std::string, ParameterPointer> ParameterMap;
+        typedef std::vector<ParameterMap>               PassVector;
+        typedef std::vector<PassVector>                 TechniqueVector;
+        typedef std::map<std::string, TechniqueVector>  MaterialMap;
+
+        public:
+            Shader(Ogre::SceneManager* scenemanager = 0);
+            virtual ~Shader();
+
+            virtual void tick(float dt);
+
+            inline void setVisible(bool bVisible)
+            {
+                if (this->bVisible_ != bVisible)
+                {
+                    this->bVisible_ = bVisible;
+                    this->updateVisibility();
+                }
+            }
+            inline bool isVisible() const
+                { return this->bVisible_; }
+            void updateVisibility();
+
+            inline void setCompositor(const std::string& compositor)
+            {
+                if (this->compositor_ != compositor)
+                {
+                    this->compositor_ = compositor;
+                    this->changedCompositor();
+                }
+            }
+            inline const std::string& getCompositor() const
+                { return this->compositor_; }
+            void changedCompositor();
+
+            void setSceneManager(Ogre::SceneManager* scenemanager);
+            inline Ogre::SceneManager* getSceneManager() const
+                { return this->scenemanager_; }
+
+            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
+            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+
+            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
+            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+            static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            static bool  getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            static bool  getParameterIsInt  (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+
+        private:
+            Ogre::SceneManager* scenemanager_;
+            Ogre::CompositorInstance* compositorInstance_;
+            bool bVisible_;
+            bool bLoadCompositor_;
+            bool bViewportInitialized_;
+            std::string compositor_;
+            std::string oldcompositor_;
+
+            static MaterialMap parameters_s;
+            static bool bLoadedCgPlugin_s;
+    };
+}
+
+#endif /* _Shader_H__ */
Index: code/trunk/src/libraries/tools/TextureGenerator.cc
===================================================================
--- code/trunk/src/libraries/tools/TextureGenerator.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/TextureGenerator.cc	(revision 5781)
@@ -0,0 +1,87 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the TextureGenerator.
+*/
+
+#include "TextureGenerator.h"
+
+#include <OgreMaterialManager.h>
+#include <OgreTechnique.h>
+#include "util/Convert.h"
+#include "util/Math.h"
+
+namespace std
+{
+    template <>
+    inline bool less<orxonox::ColourValue>::operator()(const orxonox::ColourValue& __x, const orxonox::ColourValue& __y) const
+    {
+        if (__x.r == __y.r)
+        {
+            if (__x.g == __y.g)
+            {
+                if (__x.b == __y.b)
+                {
+                    return __x.a < __y.a;
+                }
+                return __x.b < __y.b;
+            }
+            return __x.g < __y.g;
+        }
+        return __x.r < __y.r;
+    }
+}
+
+namespace orxonox
+{
+    std::map<std::string, std::map<ColourValue, std::string> > TextureGenerator::materials_s;
+    unsigned int TextureGenerator::materialCount_s = 0;
+
+    /*static*/ const std::string& TextureGenerator::getMaterialName(const std::string& textureName, const ColourValue& colour)
+    {
+        std::map<ColourValue, std::string>& colourMap = materials_s[textureName];
+        std::map<ColourValue, std::string>::const_iterator it = colourMap.find(colour);
+
+        if (it == colourMap.end())
+        {
+            std::string materialName = textureName + "_Material_" + multi_cast<std::string>(materialCount_s++);
+            Ogre::MaterialPtr material = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().create(materialName, "General"));
+            material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
+            Ogre::TextureUnitState* textureUnitState = material->getTechnique(0)->getPass(0)->createTextureUnitState();
+            textureUnitState->setTextureName(textureName);
+            textureUnitState->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour);
+            return (colourMap[colour] = materialName);
+        }
+        else
+        {
+            return (*it).second;
+        }
+    }
+}
Index: code/trunk/src/libraries/tools/TextureGenerator.h
===================================================================
--- code/trunk/src/libraries/tools/TextureGenerator.h	(revision 5781)
+++ code/trunk/src/libraries/tools/TextureGenerator.h	(revision 5781)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+/**
+    @file
+    @brief
+*/
+
+#ifndef _TextureGenerator_H__
+#define _TextureGenerator_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <map>
+#include <string>
+#include "util/UtilPrereqs.h"
+
+namespace orxonox
+{
+    class _ToolsExport TextureGenerator
+    {
+    public:
+        static const std::string& getMaterialName(const std::string& textureName, const ColourValue& colour);
+
+    private:
+        TextureGenerator();
+        TextureGenerator(const TextureGenerator&);
+        ~TextureGenerator();
+
+        static std::map<std::string, std::map<ColourValue, std::string> > materials_s;
+        static unsigned int materialCount_s;
+    };
+}
+
+#endif /* _TextureGenerator_H__ */
Index: code/trunk/src/libraries/tools/Timer.cc
===================================================================
--- code/trunk/src/libraries/tools/Timer.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/Timer.cc	(revision 5781)
@@ -0,0 +1,160 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Timer.h"
+
+#include <set>
+
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/CommandExecutor.h"
+#include "core/Clock.h"
+#include "core/Functor.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcutExtern(delay);
+    SetConsoleCommandShortcutExtern(killdelays);
+
+    static std::set<StaticTimer*> delaytimerset;
+
+    /**
+        @brief Calls a console command after 'delay' seconds.
+        @param delay The delay in seconds
+        @param command The console command
+    */
+    void delay(float delay, const std::string& command)
+    {
+        StaticTimer *delaytimer = new StaticTimer();
+        delaytimerset.insert(delaytimer);
+
+        ExecutorStatic* delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
+        delayexecutor->setDefaultValues(delaytimer, command);
+        delaytimer->setTimer(delay, false, delayexecutor);
+    }
+
+    /**
+        @brief Executes the command.
+        @param timer The timer to destroy after the command-execution
+        @param command The command to execute
+    */
+    void executeDelayedCommand(StaticTimer* timer, const std::string& command)
+    {
+        CommandExecutor::execute(command);
+        delete timer;
+        delaytimerset.erase(timer);
+    }
+
+    /**
+        @brief Kills all delayed commands.
+    */
+    void killdelays()
+    {
+        for (std::set<StaticTimer*>::iterator it = delaytimerset.begin(); it != delaytimerset.end(); ++it)
+            delete (*it);
+
+        delaytimerset.clear();
+    }
+
+    /**
+        @brief Constructor: Sets the default-values.
+    */
+    TimerBase::TimerBase()
+    {
+        this->executor_ = 0;
+        this->interval_ = 0;
+        this->bLoop_ = false;
+        this->bActive_ = false;
+        this->bKillAfterCall_ = false;
+
+        this->time_ = 0;
+
+        RegisterObject(TimerBase);
+    }
+
+    /**
+        @brief Deletes the executor.
+    */
+    TimerBase::~TimerBase()
+    {
+        this->deleteExecutor();
+    }
+
+    /**
+        @brief Executes the executor.
+    */
+    void TimerBase::run() const
+    {
+        bool temp = this->bKillAfterCall_; // to avoid errors with bKillAfterCall_=false and an exutors which destroy the timer
+
+        (*this->executor_)();
+
+        if (temp)
+            delete this;
+    }
+
+    /**
+        @brief Deletes the executor.
+    */
+    void TimerBase::deleteExecutor()
+    {
+      if (this->executor_)
+          delete this->executor_;
+    }
+
+    /**
+        @brief Updates the timer before the frames are rendered.
+    */
+    void TimerBase::tick(const Clock& time)
+    {
+        if (this->bActive_)
+        {
+            // If active: Decrease the timer by the duration of the last frame
+            this->time_ -= static_cast<long long>(time.getDeltaTimeMicroseconds() * this->getTimeFactor());
+
+            if (this->time_ <= 0)
+            {
+                // It's time to call the function
+                if (this->bLoop_ && !this->bKillAfterCall_)
+                {
+                    this->time_ += this->interval_; // Q: Why '+=' and not '='? A: Think about it. It's more accurate like that. Seriously.
+                    while (this->time_ <= 0)
+                    {
+                        // The interval was shorter than one tick, so execute the function more than once
+                        this->run();
+                        this->time_ += this->interval_;
+                    }
+                }
+                else
+                    this->stopTimer(); // Stop the timer if we don't want to loop
+
+                this->run();
+            }
+        }
+    }
+}
Index: code/trunk/src/libraries/tools/Timer.h
===================================================================
--- code/trunk/src/libraries/tools/Timer.h	(revision 5781)
+++ code/trunk/src/libraries/tools/Timer.h	(revision 5781)
@@ -0,0 +1,212 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/*!
+    @file
+    @brief Definition and Implementation of the Timer class.
+
+    The Timer is a callback-object, calling a given function after a given time-interval.
+
+    Usage:
+    header.h:
+        class ClassName
+        {
+            public:
+                ClassName();
+                void functionName();
+                Timer<ClassName> myTimer;
+        };
+
+    source.cc:
+        include "core/Executor.h"
+
+        ClassName::ClassName()
+        {
+            myTimer.setTimer(interval_in_seconds, bLoop, this, createExecutor(createFunctor(&ClassName::functionName)));
+        }
+
+        void ClassName::functionName()
+        {
+            whateveryouwant();
+            something(else);
+        }
+*/
+
+#ifndef _Timer_H__
+#define _Timer_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "core/Executor.h"
+#include "core/OrxonoxClass.h"
+#include "tools/interfaces/TimeFactorListener.h"
+
+namespace orxonox
+{
+    class StaticTimer;
+    void delay(float delay, const std::string& command);
+    void killdelays();
+    void executeDelayedCommand(StaticTimer* timer, const std::string& command);
+
+    //! TimerBase is the parent of the Timer class.
+    class _ToolsExport TimerBase : public TimeFactorListener
+    {
+        public:
+            ~TimerBase();
+
+            void run() const;
+            void deleteExecutor();
+
+            /** @brief Starts the Timer: Function-call after 'interval' seconds. */
+            inline void startTimer()
+                { this->bActive_ = true; this->time_ = this->interval_; }
+            /** @brief Stops the Timer. */
+            inline void stopTimer()
+                { this->bActive_ = false; this->time_ = this->interval_; }
+            /** @brief Pauses the Timer - it will continue with the actual state if you unpause it. */
+            inline void pauseTimer()
+                { this->bActive_ = false; }
+            /** @brief Unpauses the Timer - continues with the given state. */
+            inline void unpauseTimer()
+                { this->bActive_ = true; }
+            /** @brief Returns true if the Timer is active (= not stoped, not paused). @return True = Time is active */
+            inline bool isActive() const
+                { return this->bActive_; }
+            /** @brief Returns the remaining time until the Timer calls the function. @return The remaining time */
+            inline float getRemainingTime() const
+                { return static_cast<float>(this->time_ / 1000000.0f); }
+            /** @brief Gives the Timer some extra time. @param time The amount of extra time in seconds */
+            inline void addTime(float time)
+                { if (time > 0.0f) this->time_ += static_cast<long long>(time * 1000000.0f); }
+            /** @brief Decreases the remaining time of the Timer. @param time The amount of time to remove */
+            inline void removeTime(float time)
+                { if (time > 0.0f) this->time_ -= static_cast<long long>(time * 1000000.0f); }
+            /** @brief Sets the interval of the Timer. @param interval The interval */
+            inline void setInterval(float interval)
+                { this->interval_ = static_cast<long long>(interval * 1000000.0f); }
+            /** @brief Sets bLoop to a given value. @param bLoop True = loop */
+            inline void setLoop(bool bLoop)
+                { this->bLoop_ = bLoop; }
+
+            void tick(const Clock& time);
+
+        protected:
+            TimerBase();
+
+            Executor* executor_;  //!< The executor of the function that should be called when the time expires
+
+            long long interval_;  //!< The time-interval in micro seconds
+            bool bLoop_;          //!< If true, the function gets called every 'interval' seconds
+            bool bActive_;        //!< If true, the Timer ticks and calls the function if the time's up
+            bool bKillAfterCall_; //!< If true the timer gets deleted after it called the function
+
+            long long time_;      //!< Internal variable, counting the time till the next function-call
+    };
+
+    //! The Timer is a callback-object, calling a given function after a given time-interval.
+    template <class T = BaseObject>
+    class Timer : public TimerBase
+    {
+        public:
+            Timer() {}
+
+            /**
+                @brief Constructor: Initializes the Timer with given values.
+                @param interval The timer-interval in seconds
+                @param bLoop If true, the function gets called every 'interval' seconds
+                @param object The object owning the timer and the function
+                @param exeuctor A executor of the function to call
+            */
+            Timer(float interval, bool bLoop, T* object, ExecutorMember<T>* exeuctor, bool bKillAfterCall = false)
+            {
+                this->setTimer(interval, bLoop, object, exeuctor, bKillAfterCall);
+            }
+
+            /**
+                @brief Initializes the Timer with given values.
+                @param interval The timer-interval in seconds
+                @param bLoop If true, the function gets called every 'interval' seconds
+                @param object The object owning the timer and the function
+                @param exeuctor A executor of the function to call
+            */
+            void setTimer(float interval, bool bLoop, T* object, ExecutorMember<T>* executor, bool bKillAfterCall = false)
+            {
+                this->deleteExecutor();
+
+                this->setInterval(interval);
+                this->bLoop_ = bLoop;
+                executor->setObject(object);
+                this->executor_ = static_cast<Executor*>(executor);
+                this->bActive_ = true;
+
+                this->time_ = this->interval_;
+                this->bKillAfterCall_ = bKillAfterCall;
+            }
+    };
+
+    //! The StaticTimer is a callback-object, calling a static function after a given time-interval.
+    class _ToolsExport StaticTimer : public TimerBase
+    {
+        public:
+            StaticTimer() {}
+
+            /**
+                @brief Constructor: Initializes the Timer with given values.
+                @param interval The timer-interval in seconds
+                @param bLoop If true, the function gets called every 'interval' seconds
+                @param exeuctor A executor of the function to call
+            */
+            StaticTimer(float interval, bool bLoop, ExecutorStatic* executor, bool bKillAfterCall = false)
+            {
+                this->setTimer(interval, bLoop, executor, bKillAfterCall);
+            }
+
+            /**
+                @brief Initializes the Timer with given values.
+                @param interval The timer-interval in seconds
+                @param bLoop If true, the function gets called every 'interval' seconds
+                @param object The object owning the timer and the function
+                @param executor A executor of the function to call
+            */
+            void setTimer(float interval, bool bLoop, ExecutorStatic* executor, bool bKillAfterCall = false)
+            {
+                this->deleteExecutor();
+
+                this->setInterval(interval);
+                this->bLoop_ = bLoop;
+                this->executor_ = executor;
+                this->bActive_ = true;
+
+                this->time_ = this->interval_;
+                this->bKillAfterCall_ = bKillAfterCall;
+            }
+    };
+
+}
+
+#endif /* _Timer_H__ */
Index: code/trunk/src/libraries/tools/ToolsPrecompiledHeaders.h
===================================================================
--- code/trunk/src/libraries/tools/ToolsPrecompiledHeaders.h	(revision 5781)
+++ code/trunk/src/libraries/tools/ToolsPrecompiledHeaders.h	(revision 5781)
@@ -0,0 +1,70 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the tools library
+@details
+    Updated: 19. September 2009
+    Total Files: 11
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <cassert>  // 11
+#include <cstring>  // 11
+#include <fstream>  // 11
+#include <iostream> // 11
+#include <map>      // 11
+#include <set>      // 11
+#include <sstream>  // 11
+#include <string>   // 11
+#include <vector>   // 11
+#include <cmath>    // 10
+#include <deque>    // 10
+#include <list>     // 10
+#include <queue>    // 10
+
+#include <OgreMath.h>        // 10
+#include <OgreVector2.h>     // 10
+#include <OgreVector3.h>     // 10
+#include <OgreVector4.h>     // 10
+#include <OgreQuaternion.h>  // 10
+#include <OgreColourValue.h> // 10
+
+#include "util/Debug.h"      // 9
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: code/trunk/src/libraries/tools/ToolsPrereqs.h
===================================================================
--- code/trunk/src/libraries/tools/ToolsPrereqs.h	(revision 5781)
+++ code/trunk/src/libraries/tools/ToolsPrereqs.h	(revision 5781)
@@ -0,0 +1,91 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+  @file
+  @brief Contains all the necessary forward declarations for all classes and structs.
+*/
+
+#ifndef _ToolsPrereqs_H__
+#define _ToolsPrereqs_H__
+
+#include "OrxonoxConfig.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef TOOLS_SHARED_BUILD
+#    define _ToolsExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _ToolsExport
+#    else
+#      define _ToolsExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _ToolsExport  __attribute__ ((visibility("default")))
+#else
+#  define _ToolsExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    namespace LODParticle
+    {
+        enum Value
+        {
+            Off = 0,
+            Low = 1,
+            Normal = 2,
+            High = 3
+        };
+    }
+
+    class BillboardSet;
+    class Mesh;
+    class ParticleInterface;
+    class Shader;
+    template <class T>
+    class Timer;
+    class StaticTimer;
+}
+
+namespace Ogre
+{
+    // OGRE Wiki adapted code
+    class DynamicLines;
+    class DynamicRenderable;
+}
+
+#endif /* _ToolsPrereqs_H__ */
Index: code/trunk/src/libraries/tools/interfaces/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/tools/interfaces/CMakeLists.txt	(revision 5781)
+++ code/trunk/src/libraries/tools/interfaces/CMakeLists.txt	(revision 5781)
@@ -0,0 +1,3 @@
+ADD_SOURCE_FILES(TOOLS_SRC_FILES
+  ToolsInterfaceCompilation.cc
+)
Index: code/trunk/src/libraries/tools/interfaces/Tickable.h
===================================================================
--- code/trunk/src/libraries/tools/interfaces/Tickable.h	(revision 5781)
+++ code/trunk/src/libraries/tools/interfaces/Tickable.h	(revision 5781)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/*!
+    @file
+    @brief Declaration of the Tickable interface.
+
+    The Tickable interface provides a tick(dt) function, that gets called every frame.
+    float dt is the time since the last frame in seconds.
+
+    Attention:
+    Classes derived from a Tickable that want to have a tick(dt) function on their part, MUST call the
+    parent::tick(dt) function explicitly in their implementation of tick(dt) because it's a virtual function.
+*/
+
+#ifndef _Tickable_H__
+#define _Tickable_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "core/OrxonoxClass.h"
+#include "core/Super.h"
+
+namespace orxonox
+{
+    //! The Tickable interface provides a tick(dt) function, that gets called every frame.
+    class _ToolsExport Tickable : virtual public OrxonoxClass
+    {
+        public:
+            /**
+                @brief Gets called every frame.
+                @param dt The time since the last frame in seconds
+            */
+            virtual void tick(float dt) { }
+
+        protected:
+            Tickable();
+    };
+
+    SUPER_FUNCTION(1, Tickable, tick, true);
+}
+
+#endif /* _Tickable_H__ */
Index: code/trunk/src/libraries/tools/interfaces/TimeFactorListener.h
===================================================================
--- code/trunk/src/libraries/tools/interfaces/TimeFactorListener.h	(revision 5781)
+++ code/trunk/src/libraries/tools/interfaces/TimeFactorListener.h	(revision 5781)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TimeFactorListener_H__
+#define _TimeFactorListener_H__
+
+#include "tools/ToolsPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _ToolsExport TimeFactorListener : virtual public OrxonoxClass
+    {
+        friend class GSRoot;
+
+        public:
+            TimeFactorListener();
+            virtual ~TimeFactorListener() {}
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old) {}
+            inline float getTimeFactor() const
+                { return TimeFactorListener::timefactor_s; }
+
+        private:
+            static float timefactor_s;
+    };
+}
+
+#endif /* _TimeFactorListener_H__ */
Index: code/trunk/src/libraries/tools/interfaces/ToolsInterfaceCompilation.cc
===================================================================
--- code/trunk/src/libraries/tools/interfaces/ToolsInterfaceCompilation.cc	(revision 5781)
+++ code/trunk/src/libraries/tools/interfaces/ToolsInterfaceCompilation.cc	(revision 5781)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compiles all the interfaces in the tools library with mostly just a constructor.
+*/
+
+#include "Tickable.h"
+#include "TimeFactorListener.h"
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    //----------------------------
+    // TimeFactorListener
+    //----------------------------
+    float TimeFactorListener::timefactor_s = 1.0f;
+
+    TimeFactorListener::TimeFactorListener()
+    {
+        RegisterRootObject(TimeFactorListener);
+    }
+
+    //----------------------------
+    // Tickable
+    //----------------------------
+    /**
+        @brief Constructor: Registers the object in the Tickable-list
+    */
+    Tickable::Tickable()
+    {
+        RegisterRootObject(Tickable);
+    }
+}
Index: code/trunk/src/libraries/util/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/util/CMakeLists.txt	(revision 5774)
+++ code/trunk/src/libraries/util/CMakeLists.txt	(revision 5781)
@@ -19,4 +19,5 @@
 
 SET_SOURCE_FILES(UTIL_SRC_FILES
+  Clipboard.cc
   CRC32.cc
   Exception.cc
Index: code/trunk/src/libraries/util/Clipboard.cc
===================================================================
--- code/trunk/src/libraries/util/Clipboard.cc	(revision 5781)
+++ code/trunk/src/libraries/util/Clipboard.cc	(revision 5781)
@@ -0,0 +1,142 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ *   Windows version inspired by "Copy Text To Clipboard" by Laszlo Szathmary, 2007
+ *      http://www.loria.fr/~szathmar/off/projects/C/CopyTextToClipboard/index.php
+ */
+
+/**
+    @file
+    @brief OS-specific implementations of the clipboard functions.
+*/
+
+#include "Clipboard.h"
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+
+/////////////
+// Windows //
+/////////////
+
+#ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#undef min
+#undef max
+#include "Debug.h"
+
+namespace orxonox
+{
+
+    /**
+        @brief Puts text into the windows-clipboard
+        @param text The text
+        @return True if the action was successful
+    */
+    bool toClipboard(const std::string& text)
+    {
+        try
+        {
+            if (OpenClipboard(0))
+            {
+                EmptyClipboard();
+                HGLOBAL clipbuffer = GlobalAlloc(GMEM_DDESHARE, text.size() + 1);
+                char* buffer = static_cast<char*>(GlobalLock(clipbuffer));
+                strcpy(buffer, text.c_str());
+                GlobalUnlock(clipbuffer);
+                SetClipboardData(CF_TEXT, clipbuffer);
+                CloseClipboard();
+
+                return true;
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Unable to copy the following text to the clipboard:" << std::endl;
+            COUT(1) << "       \"" << text << "\"" << std::endl;
+        }
+        return false;
+    }
+
+    /**
+        @brief Gets text from the windows-clipboard if there is any text.
+        @return The retrieved text
+    */
+    std::string fromClipboard()
+    {
+        try
+        {
+            if (OpenClipboard(0))
+            {
+                HANDLE hData = GetClipboardData(CF_TEXT);
+                std::string output = static_cast<char*>(GlobalLock(hData));
+                GlobalUnlock(hData);
+                CloseClipboard();
+
+                return output;
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Unable to retrieve text from the clipboard." << std::endl;
+        }
+        return "";
+    }
+}
+
+#else /* ORXONOX_PLATFORM_WINDOWS */
+
+/////////////
+// Default //
+/////////////
+
+namespace orxonox
+{
+    static std::string clipboard = ""; //!< Keeps the text of our internal clipboard
+
+    /**
+        @brief Default implementation if there is no OS-specific implementation or no clipboard. Copies the text into an internal clipboard.
+        @param text The text
+        @return True
+    */
+    bool toClipboard(const std::string& text)
+    {
+        clipboard = text;
+        return true;
+    }
+
+    /**
+        @brief Default implementation if there is no OS-specific implementation or no clipboard. Gets the text from the internal clipboard.
+        @return The text
+    */
+    std::string fromClipboard()
+    {
+        return clipboard;
+    }
+}
+
+#endif /* ORXONOX_PLATFORM_WINDOWS */
Index: code/trunk/src/libraries/util/Clipboard.h
===================================================================
--- code/trunk/src/libraries/util/Clipboard.h	(revision 5781)
+++ code/trunk/src/libraries/util/Clipboard.h	(revision 5781)
@@ -0,0 +1,54 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Some functions to exchange text between the OS clipboard and Orxonox.
+
+    Use fromClipboard() to get text from the clipboard (if there is any text) and
+    toClipboard(text) to put text into the clipboard.
+
+    Those functions can only work properly if there's an OS-specific implementation.
+    If an OS isn't supported, the clipboard only works within Orxonox, but exchange
+    with other programs isn't possible.
+*/
+
+#ifndef _Clipboard_H__
+#define _Clipboard_H__
+
+#include "UtilPrereqs.h"
+#include <string>
+
+namespace orxonox
+{
+    _UtilExport bool toClipboard(const std::string& text);
+    _UtilExport std::string fromClipboard();
+}
+
+#endif /* _Clipboard_H__ */
+
Index: code/trunk/src/libraries/util/Exception.cc
===================================================================
--- code/trunk/src/libraries/util/Exception.cc	(revision 5774)
+++ code/trunk/src/libraries/util/Exception.cc	(revision 5781)
@@ -34,4 +34,5 @@
 
 #include "Exception.h"
+#include <CEGUIExceptions.h>
 
 namespace orxonox
@@ -105,4 +106,13 @@
             return ex.what();
         }
+        catch (const CEGUI::Exception& ex)
+        {
+#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
+            return GeneralException(ex.getMessage().c_str()).getDescription();
+#else
+            return GeneralException(ex.getMessage().c_str(), ex.getLine(),
+                ex.getFileName().c_str(), ex.getName().c_str()).getDescription();
+#endif
+        }
         catch (...)
         {
Index: code/trunk/src/libraries/util/OgreForwardRefs.h
===================================================================
--- code/trunk/src/libraries/util/OgreForwardRefs.h	(revision 5781)
+++ code/trunk/src/libraries/util/OgreForwardRefs.h	(revision 5781)
@@ -0,0 +1,227 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _OgreForwardRefs_H__
+#define _OgreForwardRefs_H__
+
+#include "UtilPrereqs.h"
+
+namespace Ogre
+{
+    class Angle;
+    class Animation;
+    class AnimationState;
+    class AnimationStateSet;
+    class AnimationTrack;
+    class Archive;
+    class ArchiveFactory;
+    class ArchiveManager;
+    class AutoParamDataSource;
+    class AxisAlignedBox;
+    class AxisAlignedBoxSceneQuery;
+    class Billboard;
+    class BillboardChain;
+    class BillboardSet;
+    class Bone;
+    class Camera;
+    class Codec;
+    class ColourValue;
+    class ConfigDialog;
+    template <typename T> class Controller;
+    template <typename T> class ControllerFunction;
+    class ControllerManager;
+    template <typename T> class ControllerValue;
+    class Degree;
+    class DynLib;
+    class DynLibManager;
+    class EdgeData;
+    class EdgeListBuilder;
+    class Entity;
+    class ErrorDialog;
+    class ExternalTextureSourceManager;
+    class Factory;
+    class Font;
+    class FontPtr;
+    class FontManager;
+    struct FrameEvent;
+    class FrameListener;
+    class Frustum;
+    class GpuProgram;
+    class GpuProgramPtr;
+    class GpuProgramManager;
+	class GpuProgramUsage;
+    class HardwareIndexBuffer;
+    class HardwareOcclusionQuery;
+    class HardwareVertexBuffer;
+	class HardwarePixelBuffer;
+    class HardwarePixelBufferSharedPtr;
+	class HighLevelGpuProgram;
+    class HighLevelGpuProgramPtr;
+	class HighLevelGpuProgramManager;
+	class HighLevelGpuProgramFactory;
+    class IndexData;
+    class IntersectionSceneQuery;
+    class IntersectionSceneQueryListener;
+    class Image;
+    class KeyFrame;
+    class Light;
+    class Log;
+    class LogManager;
+	class ManualResourceLoader;
+	class ManualObject;
+    class Material;
+    class MaterialPtr;
+    class MaterialManager;
+    class MaterialScriptCompiler;
+    class Math;
+    class Matrix3;
+    class Matrix4;
+    class MemoryManager;
+    class Mesh;
+    class MeshPtr;
+    class MeshSerializer;
+    class MeshSerializerImpl;
+    class MeshManager;
+    class MovableObject;
+    class MovablePlane;
+    class Node;
+	class NodeAnimationTrack;
+	class NodeKeyFrame;
+	class NumericAnimationTrack;
+	class NumericKeyFrame;
+    class Overlay;
+    class OverlayContainer;
+    class OverlayElement;
+    class OverlayElementFactory;
+    class OverlayManager;
+    class Particle;
+    class ParticleAffector;
+    class ParticleAffectorFactory;
+    class ParticleEmitter;
+    class ParticleEmitterFactory;
+    class ParticleSystem;
+    class ParticleSystemManager;
+    class ParticleSystemRenderer;
+    class ParticleSystemRendererFactory;
+    class ParticleVisualData;
+    class Pass;
+    class PatchMesh;
+    class PixelBox;
+    class Plane;
+    class PlaneBoundedVolume;
+	class Plugin;
+    class Pose;
+    class ProgressiveMesh;
+    class Profile;
+	class Profiler;
+    class Quaternion;
+	class Radian;
+    class Ray;
+    class RaySceneQuery;
+    class RaySceneQueryListener;
+    class Renderable;
+    class RenderPriorityGroup;
+    class RenderQueue;
+    class RenderQueueGroup;
+	class RenderQueueInvocation;
+	class RenderQueueInvocationSequence;
+    class RenderQueueListener;
+    class RenderSystem;
+    class RenderSystemCapabilities;
+    class RenderTarget;
+    class RenderTargetListener;
+    class RenderTexture;
+	class MultiRenderTarget;
+    class RenderWindow;
+    class RenderOperation;
+    class Resource;
+	class ResourceBackgroundQueue;
+	class ResourceGroupManager;
+    class ResourceManager;
+    class RibbonTrail;
+	class Root;
+    class SceneManager;
+    class SceneManagerEnumerator;
+    class SceneNode;
+    class SceneQuery;
+    class SceneQueryListener;
+	class ScriptLoader;
+    class Serializer;
+    class ShadowCaster;
+    class ShadowRenderable;
+	class ShadowTextureManager;
+    class SimpleRenderable;
+    class SimpleSpline;
+    class Skeleton;
+    class SkeletonPtr;
+    class SkeletonInstance;
+    class SkeletonManager;
+    class Sphere;
+    class SphereSceneQuery;
+	class StaticGeometry;
+    class StringConverter;
+    class StringInterface;
+    class SubEntity;
+    class SubMesh;
+	class TagPoint;
+    class Technique;
+	class TempBlendedBufferInfo;
+	class ExternalTextureSource;
+    class TextureUnitState;
+    class Texture;
+    class TexturePtr;
+	class TextureFont;
+    class TextureManager;
+    class TransformKeyFrame;
+	class Timer;
+    class UserDefinedObject;
+    class Vector2;
+    class Vector3;
+    class Vector4;
+    class Viewport;
+	class VertexAnimationTrack;
+    class VertexBufferBinding;
+    class VertexData;
+    class VertexDeclaration;
+	class VertexMorphKeyFrame;
+    class WireBoundingBox;
+    class Compositor;
+    class CompositorManager;
+    class CompositorChain;
+    class CompositorInstance;
+    class CompositionTechnique;
+    class CompositionPass;
+    class CompositionTargetPass;
+
+    // Originally not in OgrePrerequisites.h
+    class BorderPanelOverlayElement;
+    class PanelOverlayElement;
+    class TextAreaOverlayElement;
+}
+
+#endif /* _OgreForwardRefs_H__ */
Index: code/trunk/src/libraries/util/UTFStringConversions.h
===================================================================
--- code/trunk/src/libraries/util/UTFStringConversions.h	(revision 5781)
+++ code/trunk/src/libraries/util/UTFStringConversions.h	(revision 5781)
@@ -0,0 +1,61 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ */
+
+/**
+@file
+@brief
+    std::sring to Ogre::UTFString conversion functions
+*/
+
+#ifndef _UTFStringConversions_H__
+#define _UTFStringConversions_H__
+
+#include "UtilPrereqs.h"
+#include <OgreUTFString.h>
+
+namespace orxonox
+{
+    template <>
+    struct ConverterExplicit<std::string, Ogre::UTFString>
+    {
+        //! Converts an std::string into an Ogre::UTFString
+        inline static bool convert(Ogre::UTFString* output, const std::string& input)
+        {
+            Ogre::UTFString::code_point cp;
+            for (unsigned int i = 0; i < input.size(); ++i)
+            {
+              cp = input[i];
+              cp &= 0xFF;
+              output->append(1, cp);
+            }
+            return true;
+        }
+    };
+}
+
+#endif /* _UTFStringConversions_H__ */
