Index: code/trunk/test/CMakeLists.txt
===================================================================
--- code/trunk/test/CMakeLists.txt	(revision 10712)
+++ code/trunk/test/CMakeLists.txt	(revision 11012)
@@ -67,2 +67,3 @@
 ADD_SUBDIRECTORY(util)
 ADD_SUBDIRECTORY(core)
+ADD_SUBDIRECTORY(core_plugin)
Index: code/trunk/test/core_plugin/CMakeLists.txt
===================================================================
--- code/trunk/test/core_plugin/CMakeLists.txt	(revision 11012)
+++ code/trunk/test/core_plugin/CMakeLists.txt	(revision 11012)
@@ -0,0 +1,33 @@
+# Test-executable that loads and unloads the plugin at runtime an tests if it correctly (un-)registers static instances
+ORXONOX_ADD_EXECUTABLE(
+    core_plugin_test
+    EXCLUDE_FROM_ALL
+    NO_INSTALL
+  LINK_LIBRARIES
+    core
+    gmock_orxonox
+  SOURCE_FILES
+    ${GMOCK_MAIN}
+    PluginTest.cc
+)
+
+# A plugin that statically registers some instances
+ORXONOX_ADD_LIBRARY(
+  testplugin
+    PLUGIN
+    EXCLUDE_FROM_ALL
+    NO_INSTALL
+  LINK_LIBRARIES
+    core
+  SOURCE_FILES
+    Testclass.cc
+    Testcommandlineargument.cc
+    Testconsolecommand.cc
+    Testsingleton.cc
+)
+
+# let the test-executable depend on the plugin to ensure that the plugin always gets built before the test runs
+ADD_DEPENDENCIES(core_plugin_test testplugin)
+
+ADD_DEPENDENCIES(all_tests core_plugin_test)
+ADD_TEST(core_plugin_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/core_plugin_test --gtest_output=xml)
Index: code/trunk/test/core_plugin/PluginTest.cc
===================================================================
--- code/trunk/test/core_plugin/PluginTest.cc	(revision 11012)
+++ code/trunk/test/core_plugin/PluginTest.cc	(revision 11012)
@@ -0,0 +1,272 @@
+#include <gtest/gtest.h>
+#include <vector>
+
+#include "util/Exception.h"
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include "core/module/PluginReference.h"
+#include "core/commandline/CommandLineParser.h"
+#include "core/command/ConsoleCommand.h"
+#include "core/command/ConsoleCommandManager.h"
+
+#include "Testclass.h"
+#include "Testsingleton.h"
+
+namespace orxonox
+{
+    namespace
+    {
+        // Fixture
+        class PluginTest : public ::testing::Test
+        {
+            public:
+                static void SetUpTestCase()
+                {
+                    new Core("--noIOConsole");
+                }
+
+                static void TearDownTestCase()
+                {
+                    delete &Core::getInstance();
+                }
+        };
+    }
+
+    PluginReference* loadPlugin()
+    {
+        return new PluginReference("testplugin");
+    }
+
+    TEST_F(PluginTest, CanLoadPlugin)
+    {
+        PluginReference* plugin = loadPlugin();
+        delete plugin;
+    }
+
+
+    ///////////////////////////////////////////
+    /////////////// Identifier ////////////////
+    ///////////////////////////////////////////
+
+    Identifier* getIdentifier()
+    {
+        return ClassByString("Testclass");
+    }
+
+    TEST_F(PluginTest, LoadsIdentifier)
+    {
+        EXPECT_TRUE(getIdentifier() == NULL);
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getIdentifier() != NULL);
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, UnloadsIdentifier)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getIdentifier() != NULL);
+        delete plugin;
+        EXPECT_TRUE(getIdentifier() == NULL);
+    }
+
+    TEST_F(PluginTest, ReloadsIdentifier)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getIdentifier() != NULL);
+        delete plugin;
+        EXPECT_TRUE(getIdentifier() == NULL);
+        plugin = loadPlugin();
+        EXPECT_TRUE(getIdentifier() != NULL);
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, CanCreateObjectFromIdentifier)
+    {
+        PluginReference* plugin = loadPlugin();
+
+        Identifier* identifier = getIdentifier();
+        ASSERT_TRUE(identifier != NULL);
+
+        Identifiable* object = identifier->fabricate(NULL);
+        ASSERT_TRUE(object != NULL);
+
+        Testclass* testclass = orxonox_cast<Testclass*>(object);
+        ASSERT_TRUE(testclass != NULL);
+
+        EXPECT_EQ(666, testclass->getValue());
+
+        delete plugin;
+    }
+
+
+    ///////////////////////////////////////////
+    //////////////// Singleton ////////////////
+    ///////////////////////////////////////////
+
+    // Cannot directly use Testsingleton::getInstance() because we don't link the test to the plugin.
+    // Also cannot directly use ObjectList<Testsingleton> because the Identifier is not known before the plugin is loaded.
+    Testsingleton* getSingleton()
+    {
+        std::vector<Testsingleton*> singletons;
+
+        for (ObjectList<Listable>::iterator it = ObjectList<Listable>::begin(); it; ++it)
+        {
+            Testsingleton* singleton = dynamic_cast<Testsingleton*>(*it);
+            if (singleton)
+                singletons.push_back(singleton);
+        }
+
+        switch (singletons.size())
+        {
+            case 0:
+                return NULL;
+            case 1:
+                return singletons[0];
+            default:
+                throw std::exception(); // unexpected number of singletons found
+        }
+    }
+
+    TEST_F(PluginTest, LoadsSingleton)
+    {
+        EXPECT_TRUE(getSingleton() == NULL);
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getSingleton() != NULL);
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, UnloadsSingleton)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getSingleton() != NULL);
+        delete plugin;
+        EXPECT_TRUE(getSingleton() == NULL);
+    }
+
+    TEST_F(PluginTest, ReloadsSingleton)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getSingleton() != NULL);
+        delete plugin;
+        EXPECT_TRUE(getSingleton() == NULL);
+        plugin = loadPlugin();
+        EXPECT_TRUE(getSingleton() != NULL);
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, CanCallFunctionOnSingleton)
+    {
+        PluginReference* plugin = loadPlugin();
+
+        Testsingleton* singleton = getSingleton();
+        ASSERT_TRUE(singleton != NULL);
+
+        EXPECT_EQ(999, singleton->getValue());
+
+        delete plugin;
+    }
+
+
+    ///////////////////////////////////////////
+    ////////// Command Line Argument //////////
+    ///////////////////////////////////////////
+
+    bool hasCommandLineArgument()
+    {
+        try
+        {
+            CommandLineParser::getValue("testvalue");
+            return true;
+        }
+        catch (const ArgumentException&)
+        {
+            return false;
+        }
+    }
+
+    TEST_F(PluginTest, LoadsCommandLineArgument)
+    {
+        EXPECT_FALSE(hasCommandLineArgument());
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(hasCommandLineArgument());
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, UnloadsCommandLineArgument)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(hasCommandLineArgument());
+        delete plugin;
+        EXPECT_FALSE(hasCommandLineArgument());
+    }
+
+    TEST_F(PluginTest, ReloadsCommandLineArgument)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(hasCommandLineArgument());
+        delete plugin;
+        EXPECT_FALSE(hasCommandLineArgument());
+        plugin = loadPlugin();
+        EXPECT_TRUE(hasCommandLineArgument());
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, CommandLineArgumentHasCorrectValue)
+    {
+        PluginReference* plugin = loadPlugin();
+
+        ASSERT_TRUE(hasCommandLineArgument());
+        EXPECT_EQ(333, CommandLineParser::getValue("testvalue").get<int>());
+
+        delete plugin;
+    }
+
+
+    ///////////////////////////////////////////
+    ///////////// Console Command /////////////
+    ///////////////////////////////////////////
+
+    ConsoleCommand* getConsoleCommand()
+    {
+        return ConsoleCommandManager::getInstance().getCommand("testcommand");
+    }
+
+    TEST_F(PluginTest, LoadsConsoleCommand)
+    {
+        EXPECT_TRUE(getConsoleCommand() == NULL);
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getConsoleCommand() != NULL);
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, UnloadsConsoleCommand)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getConsoleCommand() != NULL);
+        delete plugin;
+        EXPECT_TRUE(getConsoleCommand() == NULL);
+    }
+
+    TEST_F(PluginTest, ReloadsConsoleCommand)
+    {
+        PluginReference* plugin = loadPlugin();
+        EXPECT_TRUE(getConsoleCommand() != NULL);
+        delete plugin;
+        EXPECT_TRUE(getConsoleCommand() == NULL);
+        plugin = loadPlugin();
+        EXPECT_TRUE(getConsoleCommand() != NULL);
+        delete plugin;
+    }
+
+    TEST_F(PluginTest, CanCallConsoleCommand)
+    {
+        PluginReference* plugin = loadPlugin();
+
+        ConsoleCommand* command = getConsoleCommand();
+        ASSERT_TRUE(command != NULL);
+
+        EXPECT_EQ(999, (*command->getExecutor())(333, 666).get<int>());
+
+        delete plugin;
+    }
+}
Index: code/trunk/test/core_plugin/Testclass.cc
===================================================================
--- code/trunk/test/core_plugin/Testclass.cc	(revision 11012)
+++ code/trunk/test/core_plugin/Testclass.cc	(revision 11012)
@@ -0,0 +1,20 @@
+#include "Testclass.h"
+#include "core/CoreIncludes.h"
+#include "core/config/ConfigValueIncludes.h"
+
+namespace orxonox
+{
+    RegisterClassNoArgs(Testclass);
+
+    Testclass::Testclass()
+    {
+        RegisterObject(Testclass);
+
+        this->setConfigValues();
+    }
+
+    void Testclass::setConfigValues()
+    {
+        SetConfigValue(value_, 666);
+    }
+}
Index: code/trunk/test/core_plugin/Testclass.h
===================================================================
--- code/trunk/test/core_plugin/Testclass.h	(revision 11012)
+++ code/trunk/test/core_plugin/Testclass.h	(revision 11012)
@@ -0,0 +1,22 @@
+#ifndef _Testclass_H__
+#define _Testclass_H__
+
+#include "core/class/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class Testclass : public OrxonoxClass
+    {
+        public:
+            Testclass();
+            void setConfigValues();
+
+            int getValue() const
+                { return this->value_; }
+
+        private:
+            int value_;
+    };
+}
+
+#endif /* _Testclass_H__ */
Index: code/trunk/test/core_plugin/Testcommandlineargument.cc
===================================================================
--- code/trunk/test/core_plugin/Testcommandlineargument.cc	(revision 11012)
+++ code/trunk/test/core_plugin/Testcommandlineargument.cc	(revision 11012)
@@ -0,0 +1,6 @@
+#include "core/commandline/CommandLineIncludes.h"
+
+namespace orxonox
+{
+    SetCommandLineArgument(testvalue, 333);
+}
Index: code/trunk/test/core_plugin/Testconsolecommand.cc
===================================================================
--- code/trunk/test/core_plugin/Testconsolecommand.cc	(revision 11012)
+++ code/trunk/test/core_plugin/Testconsolecommand.cc	(revision 11012)
@@ -0,0 +1,11 @@
+#include "core/command/ConsoleCommandIncludes.h"
+
+namespace orxonox
+{
+    int testcommand(int a, int b)
+    {
+        return a + b;
+    }
+
+    SetConsoleCommand("testcommand", &testcommand);
+}
Index: code/trunk/test/core_plugin/Testsingleton.cc
===================================================================
--- code/trunk/test/core_plugin/Testsingleton.cc	(revision 11012)
+++ code/trunk/test/core_plugin/Testsingleton.cc	(revision 11012)
@@ -0,0 +1,17 @@
+#include "Testsingleton.h"
+#include "core/CoreIncludes.h"
+#include "core/singleton/ScopedSingletonIncludes.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(Testsingleton, ScopeID::ROOT, false);
+
+    RegisterAbstractClass(Testsingleton).inheritsFrom<Listable>();
+
+    Testsingleton::Testsingleton()
+    {
+        RegisterObject(Testsingleton);
+
+        this->value_ = 999;
+    }
+}
Index: code/trunk/test/core_plugin/Testsingleton.h
===================================================================
--- code/trunk/test/core_plugin/Testsingleton.h	(revision 11012)
+++ code/trunk/test/core_plugin/Testsingleton.h	(revision 11012)
@@ -0,0 +1,26 @@
+#ifndef _Testsingleton_H__
+#define _Testsingleton_H__
+
+#include "util/Singleton.h"
+#include "core/object/Listable.h"
+
+namespace orxonox
+{
+    class Testsingleton : public Singleton<Testsingleton>, public Listable
+    {
+        friend class Singleton<Testsingleton>;
+
+        public:
+            Testsingleton();
+
+            int getValue() const
+                { return this->value_; }
+
+        private:
+            int value_;
+
+            static Testsingleton* singletonPtr_s;
+    };
+}
+
+#endif /* _Testsingleton_H__ */
