Index: /code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.cc
===================================================================
--- /code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.cc	(revision 7213)
+++ /code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.cc	(revision 7214)
@@ -30,4 +30,5 @@
 #include <cassert>
 
+#include "util/Convert.h"
 #include "core/Language.h"
 
@@ -124,14 +125,24 @@
     _ConsoleCommand::_ConsoleCommandManipulator test(_ModifyConsoleCommand("BaseObject", "setName").setFunction(&BaseObject::setActive));
 
-    _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, const FunctorPtr& functor, bool bInitialized) : Executor(functor, name), functionHeader_(functor->getHeaderIdentifier())
+    _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized)
     {
         this->bActive_ = true;
-        this->bInitialized_ = bInitialized;
+        this->baseName_ = name;
+        this->baseExecutor_ = executor;
+
+        if (bInitialized)
+            this->executor_ = executor;
+
         _ConsoleCommand::registerCommand(group, name, this);
     }
 
+    _ConsoleCommand::~_ConsoleCommand()
+    {
+        _ConsoleCommand::unregisterCommand(this);
+    }
+
     _ConsoleCommand& _ConsoleCommand::addShortcut()
     {
-        _ConsoleCommand::registerCommand("", this->getName(), this);
+        _ConsoleCommand::registerCommand("", this->baseName_, this);
         return *this;
     }
@@ -145,5 +156,5 @@
     _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group)
     {
-        _ConsoleCommand::registerCommand(group, this->getName(), this);
+        _ConsoleCommand::registerCommand(group, this->baseName_, this);
         return *this;
     }
@@ -155,77 +166,156 @@
     }
 
-    bool _ConsoleCommand::setFunctor(const FunctorPtr& functor, bool bForce)
-    {
-        if (!functor)
-        {
-            this->bInitialized_ = false;
-            return true;
-        }
-
-        if (!bForce && !this->functionHeaderMatches(functor))
-        {
-            COUT(1) << "Error: Couldn't assign new function to console command with name \"" << this->getName() << "\", headers don't match." << std::endl;
+    bool _ConsoleCommand::isActive() const
+    {
+        return (this->bActive_ && this->executor_ && this->executor_->getFunctor());
+    }
+
+    bool _ConsoleCommand::headersMatch(const FunctorPtr& functor)
+    {
+        unsigned int minparams = std::min(this->baseExecutor_->getParamCount(), functor->getParamCount());
+
+        if (this->baseExecutor_->getFunctor()->getHeaderIdentifier(minparams) != functor->getHeaderIdentifier(minparams))
             return false;
-        }
-
-        this->functor_ = functor;
-        this->bInitialized_ = true;
-        return true;
-    }
-
-    void _ConsoleCommand::pushFunctor(const FunctorPtr& functor, bool bForce)
-    {
-        const FunctorPtr& oldfunctor = this->getFunctor();
-
-        if (this->setFunctor(functor, bForce));
-            this->functorStack_.push(oldfunctor);
-    }
-
-    void _ConsoleCommand::popFunctor()
-    {
-        FunctorPtr newfunctor;
-        if (!this->functorStack_.empty())
-        {
-            newfunctor = this->functorStack_.top();
-            this->functorStack_.pop();
-        }
-        this->setFunctor(newfunctor);
+        else if (functor->getParamCount() <= this->baseExecutor_->getParamCount())
+            return true;
+        else if (!this->executor_)
+            return false;
+        else
+        {
+            for (unsigned int i = this->baseExecutor_->getParamCount(); i < functor->getParamCount(); ++i)
+                if (!this->executor_->defaultValueSet(i))
+                    return false;
+
+            return true;
+        }
+    }
+
+    bool _ConsoleCommand::headersMatch(const ExecutorPtr& executor)
+    {
+        unsigned int minparams = std::min(this->baseExecutor_->getParamCount(), executor->getParamCount());
+
+        if (this->baseExecutor_->getFunctor()->getHeaderIdentifier(minparams) != executor->getFunctor()->getHeaderIdentifier(minparams))
+            return false;
+        else if (executor->getParamCount() <= this->baseExecutor_->getParamCount())
+            return true;
+        else
+        {
+            for (unsigned int i = this->baseExecutor_->getParamCount(); i < executor->getParamCount(); ++i)
+                if (!executor->defaultValueSet(i))
+                    return false;
+
+            return true;
+        }
+    }
+
+    bool _ConsoleCommand::setFunction(const ExecutorPtr& executor, bool bForce)
+    {
+        if (!executor || !executor->getFunctor() || bForce || this->headersMatch(executor))
+        {
+            this->executor_ = executor;
+            return true;
+        }
+        else
+        {
+            COUT(1) << "Error: Couldn't assign new executor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
+            return false;
+        }
+    }
+
+    bool _ConsoleCommand::setFunction(const FunctorPtr& functor, bool bForce)
+    {
+        if (!functor || bForce || this->headersMatch(functor))
+        {
+            if (this->executor_)
+                this->executor_->setFunctor(functor);
+            else
+                this->executor_ = createExecutor(functor);
+
+            return true;
+        }
+        else
+        {
+            COUT(1) << "Error: Couldn't assign new functor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
+            return false;
+        }
+    }
+
+    void _ConsoleCommand::pushFunction(const ExecutorPtr& executor, bool bForce)
+    {
+        Command command;
+        command.executor_ = this->getExecutor();
+        if (command.executor_)
+            command.functor_ = this->getFunctor();
+
+        if (this->setFunction(executor, bForce))
+            this->commandStack_.push(command);
+    }
+
+    void _ConsoleCommand::pushFunction(const FunctorPtr& functor, bool bForce)
+    {
+        Command command;
+        command.executor_ = this->getExecutor();
+        if (command.executor_)
+            command.functor_ = this->getFunctor();
+
+        if (this->setFunction(functor, bForce))
+            this->commandStack_.push(command);
+    }
+
+    void _ConsoleCommand::pushFunction()
+    {
+        if (this->executor_)
+            this->pushFunction(new Executor(*this->executor_.get()));
+        else
+            COUT(1) << "Error: Couldn't push copy of executor in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
+    }
+
+    void _ConsoleCommand::popFunction()
+    {
+        Command command;
+        if (!this->commandStack_.empty())
+        {
+            command = this->commandStack_.top();
+            this->commandStack_.pop();
+        }
+
+        this->executor_ = command.executor_;
+        if (command.executor_)
+            this->executor_->setFunctor(command.functor_);
+    }
+
+    const ExecutorPtr& _ConsoleCommand::getExecutor() const
+    {
+        return this->executor_;
     }
 
     const FunctorPtr& _ConsoleCommand::getFunctor() const
     {
-//        if (this->bInitialized_) // FIXME
-            return this->functor_;
-//        else
-//            return 0;
-    }
-
-    bool _ConsoleCommand::functionHeaderMatches(const FunctorPtr& functor) const
-    {
-        if (!this->functor_)
-        {
-            assert(false);
-            return true;
-        }
-        return (functor->getHeaderIdentifier() == this->functionHeader_);
-    }
-
-    void _ConsoleCommand::setObject(void* object)
-    {
-        if (this->functor_)
-            this->functor_->setRawObjectPointer(object);
+        return this->executor_->getFunctor();
+    }
+
+    bool _ConsoleCommand::setObject(void* object)
+    {
+        if (this->executor_)
+        {
+            if (this->executor_->getFunctor())
+            {
+                this->executor_->getFunctor()->setRawObjectPointer(object);
+                return true;
+            }
+            else if (object)
+                COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no functor set." << std::endl;
+        }
         else if (object)
-            COUT(1) << "Error: Can't set object in console command \"" << this->getName() << "\", no functor set." << std::endl;
+            COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no executor set." << std::endl;
+
+        return false;
     }
 
     void _ConsoleCommand::pushObject(void* object)
     {
-        if (this->functor_)
-        {
-            this->objectStack_.push(this->getObject());
-            this->setObject(object);
-        }
-        else
-            COUT(1) << "Error: Can't set object in console command \"" << this->getName() << "\", no functor set." << std::endl;
+        void* oldobject = this->getObject();
+        if (this->setObject(object))
+            this->objectStack_.push(oldobject);
     }
 
@@ -243,6 +333,6 @@
     void* _ConsoleCommand::getObject() const
     {
-        if (this->functor_)
-            return this->functor_->getRawObjectPointer();
+        if (this->executor_ && this->executor_->getFunctor())
+            return this->executor_->getFunctor()->getRawObjectPointer();
         else
             return 0;
@@ -284,7 +374,7 @@
         {
             if (group == "")
-                COUT(2) << "Warning: A console command with shortcut name \"" << name << "\" already exists." << std::endl;
+                COUT(2) << "Warning: A console command with shortcut \"" << name << "\" already exists." << std::endl;
             else
-                COUT(2) << "Warning: A console command with group \"" << group << "\" and name \"" << name << "\" already exists." << std::endl;
+                COUT(2) << "Warning: A console command with name \"" << name << "\" already exists in group \"" << group << "\"." << std::endl;
         }
         else
@@ -293,3 +383,22 @@
         }
     }
+
+    /* static */ void _ConsoleCommand::unregisterCommand(_ConsoleCommand* command)
+    {
+        for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::iterator it_group = _ConsoleCommand::getCommandMap().begin(); it_group != _ConsoleCommand::getCommandMap().end(); )
+        {
+            for (std::map<std::string, _ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )
+            {
+                if (it_name->second == command)
+                    it_group->second.erase(it_name++);
+                else
+                    ++it_name;
+            }
+
+            if (it_group->second.empty())
+                _ConsoleCommand::getCommandMap().erase(it_group++);
+            else
+                ++it_group;
+        }
+    }
 }
Index: /code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.h
===================================================================
--- /code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.h	(revision 7213)
+++ /code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.h	(revision 7214)
@@ -176,5 +176,5 @@
 
 #define _SetConsoleCommandGeneric(group, name, functor) \
-    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, functor))
+    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::_createConsoleCommand(group, name, orxonox::createExecutor(functor)))
 
 
@@ -182,10 +182,12 @@
     BOOST_PP_CAT(_DeclareConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__)
 #define _DeclareConsoleCommand2(name, functionpointer) \
-    _DeclareConsoleCommandGeneric("", name, functionpointer)
+    _DeclareConsoleCommandGeneric("", name, orxonox::createFunctor(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), false))
+    _DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
+#define _DeclareConsoleCommand4(group, name, functionpointer, object) \
+    _DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
+
+#define _DeclareConsoleCommandGeneric(group, name, functor) \
+    orxonox::_ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = orxonox::_createConsoleCommand(group, name, orxonox::createExecutor(functor), false)
 
 
@@ -196,7 +198,13 @@
 namespace orxonox
 {
-    class _CoreExport _ConsoleCommand : protected Executor
+    class _CoreExport _ConsoleCommand
     {
         friend struct _ConsoleCommandManipulator;
+
+        struct Command
+        {
+            ExecutorPtr executor_;
+            FunctorPtr functor_;
+        };
 
         public:
@@ -208,22 +216,51 @@
                     template <class F>
                     inline _ConsoleCommandManipulator& setFunction(F function, bool bForce = false)
-                        { if (this->command_) { this->command_->setFunctor(createFunctor(function), bForce); } return *this; }
+                        {
+                            if (this->command_)
+                            {
+                                if (this->command_->getExecutor() && this->command_->getFunctor() && this->command_->getFunctor()->getFullIdentifier() == typeid(F))
+                                {
+                                    FunctorPointer<F>* functor = static_cast<FunctorPointer<F>*>(this->command_->getFunctor().get());
+                                    functor->setFunction(function);
+                                    return *this;
+                                }
+                                this->command_->setFunction(createFunctor(function), bForce);
+                            }
+                            return *this;
+                        }
                     template <class F, class O>
                     inline _ConsoleCommandManipulator& setFunction(F function, O* object, bool bForce = false)
-                        { if (this->command_) { this->command_->setFunctor(createFunctor(function, object), bForce); } return *this; }
+                        {
+                            if (this->command_)
+                            {
+                                if (this->command_->getExecutor() && this->command_->getFunctor() && this->command_->getFunctor()->getFullIdentifier() == typeid(F))
+                                {
+                                    FunctorPointer<F, O>* functor = static_cast<FunctorPointer<F, O>*>(this->command_->getFunctor().get());
+                                    functor->setFunction(function);
+                                    functor->setObject(object);
+                                    return *this;
+                                }
+                                this->command_->setFunction(createFunctor(function, object), bForce);
+                            }
+                            return *this;
+                        }
                     inline _ConsoleCommandManipulator& setFunction(const FunctorPtr& functor, bool bForce = false)
-                        { if (this->command_) { this->command_->setFunctor(functor, bForce); } return *this; }
+                        { if (this->command_) { this->command_->setFunction(functor, bForce); } return *this; }
+                    inline _ConsoleCommandManipulator& setFunction(const ExecutorPtr& executor, bool bForce = false)
+                        { if (this->command_) { this->command_->setFunction(executor, bForce); } return *this; }
 
                     template <class F>
                     inline _ConsoleCommandManipulator& pushFunction(F function, bool bForce = false)
-                        { if (this->command_) { this->command_->pushFunctor(createFunctor(function), bForce); } return *this; }
+                        { if (this->command_) { this->command_->pushFunction(createFunctor(function), bForce); } return *this; }
                     template <class F, class O>
                     inline _ConsoleCommandManipulator& pushFunction(F function, O* object, bool bForce = false)
-                        { if (this->command_) { this->command_->pushFunctor(createFunctor(function, object), bForce); } return *this; }
+                        { if (this->command_) { this->command_->pushFunction(createFunctor(function, object), bForce); } return *this; }
                     inline _ConsoleCommandManipulator& pushFunction(const FunctorPtr& functor, bool bForce = false)
-                        { if (this->command_) { this->command_->pushFunctor(functor, bForce); } return *this; }
+                        { if (this->command_) { this->command_->pushFunction(functor, bForce); } return *this; }
+                    inline _ConsoleCommandManipulator& pushFunction(const ExecutorPtr& executor, bool bForce = false)
+                        { if (this->command_) { this->command_->pushFunction(executor, bForce); } return *this; }
 
                     inline _ConsoleCommandManipulator& popFunction()
-                        { if (this->command_) { this->command_->popFunctor(); } return *this; }
+                        { if (this->command_) { this->command_->popFunction(); } return *this; }
 
                     inline _ConsoleCommandManipulator& setObject(void* object)
@@ -239,4 +276,13 @@
                     inline _ConsoleCommandManipulator& setActive(bool bActive)
                         { if (this->command_) { this->command_->setActive(bActive); } return *this; }
+                    inline _ConsoleCommandManipulator& activate()
+                        { return this->setActive(true); }
+                    inline _ConsoleCommandManipulator& deactivate()
+                        { return this->setActive(false); }
+
+                    inline bool isActive() const
+                        { return this->command_ ? this->command_->isActive() : false; }
+                    inline bool exists() const
+                        { return (this->command_ != 0); }
 
                 private:
@@ -245,5 +291,6 @@
 
         public:
-            _ConsoleCommand(const std::string& group, const std::string& name, const FunctorPtr& functor, bool bInitialized = true);
+            _ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true);
+            ~_ConsoleCommand();
 
             _ConsoleCommand& addShortcut();
@@ -254,6 +301,9 @@
             inline void setActive(bool bActive)
                 { this->bActive_ = bActive; }
-            inline bool isActive() const
-                { return (this->bActive_ && this->bInitialized_); }
+            inline void activate()
+                { this->setActive(true); }
+            inline void deactivate()
+                { this->setActive(false); }
+            bool isActive() const;
 
             inline _ConsoleCommandManipulator getManipulator() const
@@ -270,13 +320,19 @@
             static std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommandMap();
             static void registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command);
-
-            bool setFunctor(const FunctorPtr& functor, bool bForce = false);
-            void pushFunctor(const FunctorPtr& functor, bool bForce = false);
-            void popFunctor();
+            static void unregisterCommand(_ConsoleCommand* command);
+
+            bool headersMatch(const FunctorPtr& functor);
+            bool headersMatch(const ExecutorPtr& executor);
+
+            bool setFunction(const ExecutorPtr& executor, bool bForce = false);
+            bool setFunction(const FunctorPtr& functor, bool bForce = false);
+            void pushFunction(const ExecutorPtr& executor, bool bForce = false);
+            void pushFunction(const FunctorPtr& functor, bool bForce = false);
+            void pushFunction();
+            void popFunction();
+            const ExecutorPtr& getExecutor() const;
             const FunctorPtr& getFunctor() const;
 
-            bool functionHeaderMatches(const FunctorPtr& functor) const;
-
-            void setObject(void* object);
+            bool setObject(void* object);
             void pushObject(void* object);
             void popObject();
@@ -284,18 +340,21 @@
 
             bool bActive_;
-            bool bInitialized_;
-            const std::type_info& functionHeader_;
-            std::stack<FunctorPtr> functorStack_;
+//            const std::type_info& functionHeader_;
+            std::string baseName_;
+            ExecutorPtr baseExecutor_;
+
+            ExecutorPtr executor_;
+            std::stack<Command> commandStack_;
             std::stack<void*> objectStack_;
     };
 
-    inline _ConsoleCommand* _createConsoleCommand(const std::string& name, const FunctorPtr& functor, bool bInitialized = true)
-    {
-        return new _ConsoleCommand("", name, functor, bInitialized);
+    inline _ConsoleCommand* _createConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
+    {
+        return new _ConsoleCommand("", name, executor, bInitialized);
     }
 
-    inline _ConsoleCommand* _createConsoleCommand(const std::string& group, const std::string& name, const FunctorPtr& functor, bool bInitialized = true)
-    {
-        return new _ConsoleCommand(group, name, functor, bInitialized);
+    inline _ConsoleCommand* _createConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
+    {
+        return new _ConsoleCommand(group, name, executor, bInitialized);
     }
 }
Index: /code/branches/consolecommands3/src/libraries/core/command/Executor.h
===================================================================
--- /code/branches/consolecommands3/src/libraries/core/command/Executor.h	(revision 7213)
+++ /code/branches/consolecommands3/src/libraries/core/command/Executor.h	(revision 7214)
@@ -63,6 +63,14 @@
             bool evaluate(const std::string& params, MultiType param[5], const std::string& delimiter = " ") const;
 
+            inline void setFunctor(const FunctorPtr& functor)
+                { this->functor_ = functor; }
             inline const FunctorPtr& getFunctor() const
                 { return this->functor_; }
+
+            inline void setName(const std::string& name)
+                { this->name_ = name; }
+            inline const std::string& getName() const
+                { return this->name_; }
+
             inline unsigned int getParamCount() const
                 { return this->functor_->getParamCount(); }
@@ -75,9 +83,4 @@
             inline std::string getTypenameReturnvalue() const
                 { return this->functor_->getTypenameReturnvalue(); }
-
-            inline void setName(const std::string& name)
-                { this->name_ = name; }
-            inline const std::string& getName() const
-                { return this->name_; }
 
             void setDefaultValues(const MultiType& param1);
Index: /code/branches/consolecommands3/src/libraries/core/command/Functor.h
===================================================================
--- /code/branches/consolecommands3/src/libraries/core/command/Functor.h	(revision 7213)
+++ /code/branches/consolecommands3/src/libraries/core/command/Functor.h	(revision 7214)
@@ -111,4 +111,5 @@
             virtual const std::type_info& getFullIdentifier() const = 0;
             virtual const std::type_info& getHeaderIdentifier() const = 0;
+            virtual const std::type_info& getHeaderIdentifier(unsigned int params) const = 0;
     };
 
@@ -294,9 +295,9 @@
                 switch (param)
                 {
-                    case 0: return typeToString<P1>();
-                    case 1: return typeToString<P2>();
-                    case 2: return typeToString<P3>();
-                    case 3: return typeToString<P4>();
-                    case 4: return typeToString<P5>();
+                    case 0:  return typeToString<P1>();
+                    case 1:  return typeToString<P2>();
+                    case 2:  return typeToString<P3>();
+                    case 3:  return typeToString<P4>();
+                    case 4:  return typeToString<P5>();
                     default: return "";
                 }
@@ -311,4 +312,17 @@
             {
                 return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, P5>);
+            }
+
+            const std::type_info& getHeaderIdentifier(unsigned int params) const
+            {
+                switch (params)
+                {
+                    case 0:  return typeid(detail::FunctorHeaderIdentifier<R, void, void, void, void, void>);
+                    case 1:  return typeid(detail::FunctorHeaderIdentifier<R, P1, void, void, void, void>);
+                    case 2:  return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, void, void, void>);
+                    case 3:  return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, void, void>);
+                    case 4:  return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, void>);
+                    default: return typeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, P5>);
+                }
             }
     };
