Index: /code/branches/consolecommands2/src/libraries/core/ConsoleCommand.cc
===================================================================
--- /code/branches/consolecommands2/src/libraries/core/ConsoleCommand.cc	(revision 6451)
+++ /code/branches/consolecommands2/src/libraries/core/ConsoleCommand.cc	(revision 6452)
@@ -28,4 +28,5 @@
 
 #include "ConsoleCommand.h"
+#include <cassert>
 
 namespace orxonox
@@ -71,2 +72,190 @@
     }
 }
+
+#include "BaseObject.h" // remove this
+
+namespace orxonox
+{
+    _SetConsoleCommand("BaseObject", "setName", &BaseObject::setName, (BaseObject*)0);
+    _ConsoleCommand::_ConsoleCommandManipulator test = _ModifyConsoleCommand("BaseObject", "setName").setFunction(&BaseObject::setActive);
+
+    _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, Functor* functor, State::Enum state) : Executor(functor, name), functionHeader_(functor->getHeaderIndentifier())
+    {
+        this->state_ = state;
+        _ConsoleCommand::registerCommand(group, name, this);
+    }
+
+    _ConsoleCommand& _ConsoleCommand::addShortcut()
+    {
+        _ConsoleCommand::registerCommand("", this->getName(), this);
+        return *this;
+    }
+
+    _ConsoleCommand& _ConsoleCommand::addShortcut(const std::string&  name)
+    {
+        _ConsoleCommand::registerCommand("", name, this);
+        return *this;
+    }
+
+    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group)
+    {
+        _ConsoleCommand::registerCommand(group, this->getName(), this);
+        return *this;
+    }
+
+    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group, const std::string&  name)
+    {
+        _ConsoleCommand::registerCommand(group, name, this);
+        return *this;
+    }
+
+    void _ConsoleCommand::setActive(bool bActive)
+    {
+        if (bActive)
+        {
+            if (this->state_ == State::Inactive)
+                this->state_ = State::Active;
+            else if (this->state_ == State::UninitializedInactive)
+                this->state_ = State::UninitializedActive;
+        }
+        else
+        {
+            if (this->state_ == State::Active)
+                this->state_ = State::Inactive;
+            else if (this->state_ == State::UninitializedActive)
+                this->state_ = State::UninitializedInactive;
+        }
+    }
+
+    void _ConsoleCommand::setInitialized(bool bInitialized)
+    {
+        if (bInitialized)
+        {
+            if (this->state_ == State::UninitializedActive)
+                this->state_ = State::Active;
+            else if (this->state_ == State::UninitializedInactive)
+                this->state_ = State::Inactive;
+        }
+        else
+        {
+            if (this->state_ == State::Active)
+                this->state_ = State::UninitializedActive;
+            else if (this->state_ == State::Inactive)
+                this->state_ = State::UninitializedInactive;
+        }
+    }
+
+    void _ConsoleCommand::setFunctor(Functor* functor, _ConsoleCommand::ObjectPointer::Enum mode)
+    {
+        if (!functor)
+        {
+            this->setInitialized(false);
+            return;
+        }
+
+        if (!this->functionHeaderMatches(functor))
+        {
+            COUT(1) << "Error: Couldn't assign new function to console command with name \"" << this->getName() << "\", headers don't match." << std::endl;
+            return;
+        }
+
+        switch (mode)
+        {
+            default:
+            case _ConsoleCommand::ObjectPointer::Null:
+            {
+                this->functor_ = functor;
+            }
+            break;
+
+            case _ConsoleCommand::ObjectPointer::RawCopy:
+            {
+                void* object = (this->functor_) ? this->functor_->getRawObjectPointer() : 0;
+
+                this->functor_ = functor;
+
+                if (!this->functor_->getBaseObject())
+                    this->functor_->setRawObjectPointer(object);
+            }
+            break;
+
+            case _ConsoleCommand::ObjectPointer::CastViaBaseObject:
+            {
+                BaseObject* object = (this->functor_) ? this->functor_->getBaseObject() : 0;
+
+                this->functor_ = functor;
+
+                if (!this->functor_->getBaseObject())
+                    this->functor_->setBaseObject(object);
+            }
+            break;
+        }
+    }
+
+    bool _ConsoleCommand::functionHeaderMatches(Functor* functor) const
+    {
+        if (!this->functor_)
+        {
+            assert(false);
+            return false;
+        }
+        return (functor->getHeaderIdentifier() == this->functor_->getHeaderIdentifier());
+    }
+
+    void _ConsoleCommand::setObject(void* object)
+    {
+        if (this->functor_)
+            this->functor_->setRawObjectPointer(object);
+    }
+
+    void _ConsoleCommand::setObject(BaseObject* object)
+    {
+        if (this->functor_)
+            this->functor_->setBaseObject(object);
+    }
+
+    /* static */ const _ConsoleCommand* _ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError)
+    {
+        std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommandMap().find(group);
+        if (it_group != _ConsoleCommand::getCommandMap().end())
+        {
+            std::map<std::string, _ConsoleCommand*>::const_iterator it_name = it_group->second.find(name);
+            if (it_name != it_group->second.end())
+            {
+                return it_name->second;
+            }
+        }
+        if (bPrintError)
+        {
+            if (group == "")
+                COUT(0) << "Error: Couldn't find console command with shortcut \"" << name << "\"" << std::endl;
+            else
+                COUT(0) << "Error: Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << std::endl;
+        }
+        return 0;
+    }
+
+    /* static */ std::map<std::string, std::map<std::string, _ConsoleCommand*> >& _ConsoleCommand::getCommandMap()
+    {
+        static std::map<std::string, std::map<std::string, _ConsoleCommand*> > commandMap;
+        return commandMap;
+    }
+
+    /* static */ void _ConsoleCommand::registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command)
+    {
+        if (name == "")
+            return;
+
+        if (_ConsoleCommand::getCommand(group, name) != 0)
+        {
+            if (group == "")
+                COUT(2) << "Warning: A console command with shortcut name \"" << name << "\" already exists." << std::endl;
+            else
+                COUT(2) << "Warning: A console command with group \"" << group << "\" and name \"" << name << "\" already exists." << std::endl;
+        }
+        else
+        {
+            _ConsoleCommand::getCommandMap()[group][name] = command;
+        }
+    }
+}
Index: /code/branches/consolecommands2/src/libraries/core/ConsoleCommand.h
===================================================================
--- /code/branches/consolecommands2/src/libraries/core/ConsoleCommand.h	(revision 6451)
+++ /code/branches/consolecommands2/src/libraries/core/ConsoleCommand.h	(revision 6452)
@@ -34,4 +34,5 @@
 #include <boost/preprocessor/cat.hpp>
 
+#include "util/VA_NARGS.h"
 #include "ArgumentCompletionFunctions.h"
 #include "CommandExecutor.h"
@@ -155,3 +156,159 @@
 }
 
+
+#define _SetConsoleCommand(...) \
+    BOOST_PP_CAT(_SetConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__)
+#define _SetConsoleCommand2(name, functionpointer) \
+    _SetConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))
+#define _SetConsoleCommand3(group, name, functionpointer) \
+    _SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
+#define _SetConsoleCommand4(group, name, functionpointer, object) \
+    _SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
+
+#define _SetConsoleCommandGeneric(group, name, functor) \
+    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, functor))
+
+
+#define _DeclareConsoleCommand(...) \
+    BOOST_PP_CAT(_DeclareConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__)
+#define _DeclareConsoleCommand2(name, functionpointer) \
+    _DeclareConsoleCommandGeneric("", name, functionpointer)
+#define _DeclareConsoleCommand3(group, name, functionpointer) \
+    _DeclareConsoleCommandGeneric(group, name, functionpointer)
+
+#define _DeclareConsoleCommandGeneric(group, name, functionpointer) \
+    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, orxonox::createFunctor(functionpointer), orxonox::_ConsoleCommand::State::UninitializedActive))
+
+
+#define _ModifyConsoleCommand(...) \
+    orxonox::_ConsoleCommand::getCommand(__VA_ARGS__, true)->getManipulator()
+
+
+namespace orxonox
+{
+    class _CoreExport _ConsoleCommand : protected Executor
+    {
+        friend struct _ConsoleCommandManipulator;
+
+        public:
+            struct State
+            {
+                enum Enum
+                {
+                    UninitializedActive,
+                    UninitializedInactive,
+                    Active,
+                    Inactive
+                };
+            };
+
+            struct ObjectPointer
+            {
+                enum Enum
+                {
+                    Null,
+                    RawCopy,
+                    CastViaBaseObject
+                };
+            };
+
+            struct _ConsoleCommandManipulator
+            {
+                public:
+                    _ConsoleCommandManipulator(const _ConsoleCommand* command) : command_(const_cast<_ConsoleCommand*>(command)) {}
+
+                    template <class F>
+                    inline _ConsoleCommandManipulator& setFunction(F function, _ConsoleCommand::ObjectPointer::Enum mode = _ConsoleCommand::ObjectPointer::Null)
+                        { if (this->command_) { this->command_->setFunctor(createFunctor(function), mode); } return *this; }
+                    template <class F, class O>
+                    inline _ConsoleCommandManipulator& setFunction(F function, O* object)
+                        { if (this->command_) { this->command_->setFunctor(createFunctor(function, object)); } return *this; }
+                    inline _ConsoleCommandManipulator& setFunction(Functor* functor)
+                        { if (this->command_) { this->command_->setFunctor(functor); } return *this; }
+                    inline _ConsoleCommandManipulator& setFunction(const _ConsoleCommand* command)
+                        { if (this->command_) { this->command_->setFunctor(command->functor_); } return *this; }
+                    inline _ConsoleCommandManipulator& setFunction(const _ConsoleCommandManipulator& manipulator)
+                        { if (this->command_) { this->command_->setFunctor(manipulator.command_->functor_); } return *this; }
+
+                    template <class F>
+                    inline _ConsoleCommandManipulator& pushFunction(F function, _ConsoleCommand::ObjectPointer::Enum mode = _ConsoleCommand::ObjectPointer::Null)
+                        { if (this->command_) { this->command_->pushFunctor(createFunctor(function), mode); } return *this; }
+                    template <class F, class O>
+                    inline _ConsoleCommandManipulator& pushFunction(F function, O* object)
+                        { if (this->command_) { this->command_->pushFunctor(createFunctor(function, object)); } return *this; }
+                    inline _ConsoleCommandManipulator& pushFunction(Functor* functor)
+                        { if (this->command_) { this->command_->pushFunctor(functor); } return *this; }
+                    inline _ConsoleCommandManipulator& pushFunction(const _ConsoleCommand* command)
+                        { if (this->command_) { this->command_->pushFunctor(command->functor_); } return *this; }
+                    inline _ConsoleCommandManipulator& pushFunction(const _ConsoleCommandManipulator& manipulator)
+                        { if (this->command_) { this->command_->pushFunctor(manipulator.command_->functor_); } return *this; }
+
+                    inline _ConsoleCommandManipulator& popFunction()
+                        { if (this->command_) { this->command_->popFunctor(); } return *this; }
+
+                    inline _ConsoleCommandManipulator& setObject(void* object)
+                        { if (this->command_) { this->command_->setObject(object); } return *this; }
+                    inline _ConsoleCommandManipulator& setObject(BaseObject* object)
+                        { if (this->command_) { this->command_->setObject(object); } return *this; }
+
+                    inline _ConsoleCommandManipulator& setActive(bool bActive)
+                        { if (this->command_) { this->command_->setActive(bActive); } return *this; }
+
+                private:
+                    _ConsoleCommand* command_;
+            };
+
+        public:
+            _ConsoleCommand(const std::string& group, const std::string& name, Functor* functor, State::Enum state = State::Active);
+
+            _ConsoleCommand& addShortcut();
+            _ConsoleCommand& addShortcut(const std::string&  name);
+            _ConsoleCommand& addGroup(const std::string& group);
+            _ConsoleCommand& addGroup(const std::string& group, const std::string&  name);
+
+            void setActive(bool bActive);
+            inline State::Enum getState() const
+                { return this->state_; }
+            inline bool isActive() const
+                { return (this->state_ == State::Active); }
+
+            static inline const std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommands()
+                { return _ConsoleCommand::getCommandMap(); }
+
+            static inline const _ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false)
+                { return _ConsoleCommand::getCommand("", name, bPrintError); }
+            static const _ConsoleCommand* getCommand(const std::string& group, const std::string& name, bool bPrintError = false);
+
+            inline _ConsoleCommandManipulator getManipulator() const
+                { return this; }
+
+        private:
+            static std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommandMap();
+            static void registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command);
+
+            void setInitialized(bool bInitialized);
+
+            void setFunctor(Functor* functor, _ConsoleCommand::ObjectPointer::Enum mode = _ConsoleCommand::ObjectPointer::Null);
+            void pushFunctor(Functor* functor, _ConsoleCommand::ObjectPointer::Enum mode = _ConsoleCommand::ObjectPointer::Null);
+            void popFunctor();
+            bool functionHeaderMatches(Functor* functor) const;
+
+            void setObject(void* object);
+            void setObject(BaseObject* object);
+
+            State::Enum state_;
+            const std::type_info& functionHeader_;
+    };
+
+    inline _ConsoleCommand* _createConsoleCommand(const std::string& name, Functor* functor, _ConsoleCommand::State::Enum state = _ConsoleCommand::State::Active)
+    {
+        return new _ConsoleCommand("", name, functor, state);
+    }
+
+    inline _ConsoleCommand* _createConsoleCommand(const std::string& group, const std::string& name, Functor* functor, _ConsoleCommand::State::Enum state = _ConsoleCommand::State::Active)
+    {
+        return new _ConsoleCommand(group, name, functor, state);
+    }
+}
+
 #endif /* _ConsoleCommand_H__ */
Index: /code/branches/consolecommands2/src/libraries/core/Functor.h
===================================================================
--- /code/branches/consolecommands2/src/libraries/core/Functor.h	(revision 6451)
+++ /code/branches/consolecommands2/src/libraries/core/Functor.h	(revision 6452)
@@ -31,8 +31,12 @@
 #define _Functor_H__
 
+#include <typeinfo>
+
 #include "CorePrereqs.h"
 
+#include "util/Convert.h"
 #include "util/Debug.h"
 #include "util/MultiType.h"
+#include "BaseObject.h"
 
 namespace orxonox
@@ -112,4 +116,13 @@
             virtual void evaluateParam(unsigned int index, MultiType& param) const = 0;
 
+            virtual void setBaseObject(BaseObject* object) {}
+            virtual void setBaseObject(const BaseObject* object) {}
+            virtual BaseObject* getBaseObject() const { return 0; }
+
+            virtual void setRawObjectPointer(void* object) {}
+            virtual void* getRawObjectPointer() const { return 0; }
+
+            virtual const std::type_info& getHeaderIdentifier() const = 0;
+
         protected:
             unsigned int numParams_;
@@ -182,4 +195,38 @@
             }
 
+            void setBaseObject(BaseObject* object)
+            {
+                this->bConstObject_ = false;
+                this->object_ = dynamic_cast<T*>(object);
+            }
+
+            void setBaseObject(const BaseObject* object)
+            {
+                this->bConstObject_ = true;
+                this->constObject_ = dynamic_cast<const T*>(object);
+            }
+
+            BaseObject* getBaseObject() const
+            {
+                if (this->bConstObject_)
+                    return const_cast<BaseObject*>(upcast<const BaseObject*>(this->constObject_));
+                else
+                    return upcast<BaseObject*>(this->object_);
+            }
+
+            void setRawObjectPointer(void* object)
+            {
+                this->bConstObject_ = false;
+                this->object_ = (T*)object;
+            }
+
+            void* getRawObjectPointer() const
+            {
+                if (this->bConstObject_)
+                    return (void*)this->constObject_;
+                else
+                    return (void*)this->object_;
+            }
+
         private:
             const T* constObject_;
@@ -187,4 +234,16 @@
             bool bConstObject_;
     };
+
+
+
+    template <int r, class R, class P1, class P2, class P3, class P4, class P5>
+    struct FunctorHeaderIdentifier {};
+
+
+
+    inline Functor* createFunctor(Functor* functor)
+    {
+        return functor;
+    }
 
 
@@ -294,4 +353,18 @@
 
 
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams) FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES##numparams(returnvalue)
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES0(returnvalue) <returnvalue, FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), void, void, void, void, void>
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES1(returnvalue) <returnvalue, FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, void, void, void, void>
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES2(returnvalue) <returnvalue, FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, void, void, void>
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES3(returnvalue) <returnvalue, FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, P3, void, void>
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES4(returnvalue) <returnvalue, FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, P3, P4, void>
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES5(returnvalue) <returnvalue, FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, P3, P4, P5>
+
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue) FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE##returnvalue
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE0 void
+#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE1 R
+
+
+
 #define FUNCTOR_EVALUATE_PARAM(numparams) FUNCTOR_EVALUATE_PARAM##numparams
 #define FUNCTOR_EVALUATE_PARAM0
@@ -320,5 +393,4 @@
 
 
-
 #define CREATE_STATIC_FUNCTOR(returnvalue, numparams) \
     FUNCTOR_TEMPLATE(0, returnvalue, numparams, 0) \
@@ -342,7 +414,12 @@
             } \
     \
-            virtual void evaluateParam(unsigned int index, MultiType& param) const \
+            void evaluateParam(unsigned int index, MultiType& param) const \
             { \
                 FUNCTOR_EVALUATE_PARAM(numparams); \
+            } \
+    \
+            const std::type_info& getHeaderIdentifier() const \
+            { \
+                return typeid(FunctorHeaderIdentifier FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams)); \
             } \
     \
@@ -386,7 +463,12 @@
             } \
     \
-            virtual void evaluateParam(unsigned int index, MultiType& param) const \
+            void evaluateParam(unsigned int index, MultiType& param) const \
             { \
                 FUNCTOR_EVALUATE_PARAM(numparams); \
+            } \
+    \
+            const std::type_info& getHeaderIdentifier() const \
+            { \
+                return typeid(FunctorHeaderIdentifier FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams)); \
             } \
     \
@@ -418,7 +500,12 @@
             } \
     \
-            virtual void evaluateParam(unsigned int index, MultiType& param) const \
+            void evaluateParam(unsigned int index, MultiType& param) const \
             { \
                 FUNCTOR_EVALUATE_PARAM(numparams); \
+            } \
+    \
+            const std::type_info& getHeaderIdentifier() const \
+            { \
+                return typeid(FunctorHeaderIdentifier FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams)); \
             } \
     \
@@ -457,4 +544,5 @@
         return functor; \
     }
+
 
 
Index: /code/branches/consolecommands2/src/libraries/core/LuaState.h
===================================================================
--- /code/branches/consolecommands2/src/libraries/core/LuaState.h	(revision 6451)
+++ /code/branches/consolecommands2/src/libraries/core/LuaState.h	(revision 6452)
@@ -54,4 +54,5 @@
             void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null);
             void evaluateParam(unsigned int index, MultiType& param) const {}
+            const std::type_info& getHeaderIdentifier() const { return typeid(this); }
 
         private:
Index: /code/branches/consolecommands2/src/libraries/util/Convert.h
===================================================================
--- /code/branches/consolecommands2/src/libraries/util/Convert.h	(revision 6451)
+++ /code/branches/consolecommands2/src/libraries/util/Convert.h	(revision 6452)
@@ -115,4 +115,32 @@
         }
     };
+
+    ////////////
+    // upcast //
+    ////////////
+    namespace detail
+    {
+        // perform a static cast if ToType is a base of FromType
+        template<class ToType, class FromType>
+        FORCEINLINE ToType upcast(FromType input, detail::Int2Type<true>)
+        {
+            return static_cast<ToType>(input);
+        }
+
+        // return zero if ToType is not a base of FromType
+        template<class ToType, class FromType>
+        FORCEINLINE ToType upcast(FromType input, detail::Int2Type<false>)
+        {
+            return 0;
+        }
+    }
+
+    // performs an upcast if ToType is a base of FromType, returns zero otherwise
+    template <class ToType, class FromType>
+    FORCEINLINE ToType upcast(FromType input)
+    {
+        enum { probe = ImplicitConversion<FromType, ToType>::exists };
+        return detail::upcast<ToType, FromType>(input, detail::Int2Type<probe>());
+    }
 }
 
Index: /code/branches/consolecommands2/src/libraries/util/VA_NARGS.h
===================================================================
--- /code/branches/consolecommands2/src/libraries/util/VA_NARGS.h	(revision 6452)
+++ /code/branches/consolecommands2/src/libraries/util/VA_NARGS.h	(revision 6452)
@@ -0,0 +1,59 @@
+/*
+ *   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 ORXONOX_VA_NARGS macro which returns the number of arguments passed to a variadic macro.
+*/
+
+/**
+    @brief Returns the number of arguments passed to a variadic macro. Important: The number of arguments must be greater than zero (ORXONOX_VA_NARGS() returns 1).
+*/
+#define ORXONOX_VA_NARGS(...) \
+    ORXONOX_VA_NARGS_CONCAT(__VA_ARGS__, ORXONOX_VA_NARGS_NUMBERS)
+
+
+// some helper macros //
+
+#define ORXONOX_VA_NARGS_CONCAT(...) \
+    ORXONOX_VA_NARGS_INTERN(__VA_ARGS__)
+
+#define ORXONOX_VA_NARGS_INTERN( \
+    arg1,  arg2,  arg3,  arg4,  arg5,  arg6,  arg7,  arg8,  arg9,  arg10, \
+    arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, \
+    arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, \
+    arg31, arg32, arg33, arg34, arg35, arg36, arg37, arg38, arg39, arg40, \
+    arg41, arg42, arg43, arg44, arg45, arg46, arg47, arg48, arg49, arg50, \
+    arg51, arg52, arg53, arg54, arg55, arg56, arg57, arg58, arg59, arg60, \
+    arg61, arg62, arg63, argn, ...) argn
+
+#define ORXONOX_VA_NARGS_NUMBERS \
+    63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \
+    47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, \
+    31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \
+    15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0
