Index: code/trunk/src/libraries/util/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/util/CMakeLists.txt	(revision 8729)
+++ code/trunk/src/libraries/util/CMakeLists.txt	(revision 8858)
@@ -26,5 +26,4 @@
   CRC32.cc
   ExprParser.cc
-  OutputHandler.cc
   Scope.cc
   ScopedSingletonManager.cc
@@ -42,4 +41,6 @@
 )
 
+ADD_SUBDIRECTORY(output)
+
 ORXONOX_ADD_LIBRARY(util
   FIND_HEADER_FILES
Index: code/trunk/src/libraries/util/Clipboard.cc
===================================================================
--- code/trunk/src/libraries/util/Clipboard.cc	(revision 8729)
+++ code/trunk/src/libraries/util/Clipboard.cc	(revision 8858)
@@ -48,5 +48,5 @@
 #undef min
 #undef max
-#include "Debug.h"
+#include "Output.h"
 
 namespace orxonox
@@ -76,6 +76,6 @@
         catch (...)
         {
-            COUT(1) << "Error: Unable to copy the following text to the clipboard:" << std::endl;
-            COUT(1) << "       \"" << text << '"' << std::endl;
+            orxout(user_error) << "Unable to copy the following text to the clipboard:" << endl;
+            orxout(user_error) << '"' << text << '"' << endl;
         }
         return false;
@@ -104,5 +104,5 @@
         catch (...)
         {
-            COUT(1) << "Error: Unable to retrieve text from the clipboard." << std::endl;
+            orxout(user_error) << "Unable to retrieve text from the clipboard." << endl;
         }
         return "";
Index: code/trunk/src/libraries/util/Convert.h
===================================================================
--- code/trunk/src/libraries/util/Convert.h	(revision 8729)
+++ code/trunk/src/libraries/util/Convert.h	(revision 8858)
@@ -130,5 +130,5 @@
 #include <loki/TypeManip.h>
 
-#include "Debug.h"
+#include "Output.h"
 #include "ImplicitConversion.h"
 
@@ -151,6 +151,6 @@
         ORX_FORCEINLINE static bool convert(ToType* /*output*/, const FromType& /*input*/)
         {
-            COUT(2) << "Could not convert value of type " << typeid(FromType).name()
-                    << " to type " << typeid(ToType).name() << std::endl;
+            orxout(internal_warning) << "Could not convert value of type " << typeid(FromType).name()
+                                     << " to type " << typeid(ToType).name() << endl;
             return false;
         }
Index: code/trunk/src/libraries/util/Debug.h
===================================================================
--- code/trunk/src/libraries/util/Debug.h	(revision 8729)
+++ 	(revision )
@@ -1,131 +1,0 @@
-/*
- *   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:
- *      ...
- *
- */
-
-/**
-    @defgroup COUT COUT(x) output macro
-    @ingroup Util
-*/
-
-/**
-@file
-@ingroup COUT
-@brief
-    Handles different output-levels of errors, warnings, infos, and debug information.
-
-    The COUT(level) macro acts like @c std::cout, but the output is only performed if the given
-    level is <= the soft debug level.
-
-    There are two used values in this file:
-     - The hard debug level is used during compile time. It describes the highest allowed output level.
-     - The soft debug level is used during runtime and is the maximum of the three configurable
-       output-levels for console, log file, and in game shell.
-
-    The separation between the three devices is done by the OutputHandler.
-
-    @anchor COUTlevels
-    Possible levels are:
-     - 0: Very important output
-     - 1: Errors
-     - 2: Warnings
-     - 3: Information
-     - 4: Debug information
-     - 5: More debug information
-     - 6: Crazy debug information
-
-    Example:
-    @code
-    COUT(0) << "Very important output" << std::endl;
-    COUT(1) << "Error: Something went wrong!" << std::endl;
-    COUT(2) << "Warning: There might be a problem." << std::endl;
-    COUT(3) << "Info: It's Monday" << std::endl;
-    COUT(4) << "Debug: x is 1.23456" << std::endl;
-    @endcode
-*/
-
-#ifndef _Util_Debug_H__
-#define _Util_Debug_H__
-
-#include "UtilPrereqs.h"
-#include "OutputHandler.h"
-
-namespace orxonox
-{
-    // Just for convenience
-    using std::endl;
-
-    // Adjust this to discard certain output with level > hardDebugLevel at compile time already
-#ifdef ORXONOX_RELEASE
-    const int hardDebugLevel = OutputLevel::Verbose;
-#else
-    //! Maximum level for debug output that should be even processed at run time
-    const int hardDebugLevel = OutputLevel::Ultra;
-#endif
-
-    //! This function simply returns 0 and helps to suppress the "statement has no effect" compiler warning
-    inline int debugDummyFunction()
-    {
-        return 0;
-    }
-}
-
-/**
-@brief
-    Logs text output: You can use COUT(level) exactly like @c std::cout, but you have to specify an output level as argument.
-@param level
-    The level of the following output (passed with <tt><< "text"</tt>). Lower levels are more important. See @ref COUTlevels "the description above" for a list of possible output levels.
-
-    Example:
-    @code
-    COUT(3) << "Some info" << std::endl; // Output with level 3
-    @endcode
-@note
-    <tt>(a > b ? 0 : c << "text")</tt> is equivalent to <tt>(a > b ? 0 : (c << "text")</tt>
-    where <tt>(a > b ? 0 : )</tt> stands for COUT(x). This should explain how
-    this macro magic can possibly even work ;)
-@remarks
-    The <tt>? :</tt> operator requires both possible results to have the type of
-    the first. This is achieved by the int conversion operator dummy
-    in the @ref orxonox::OutputHandler.
-*/
-#define COUT(level)                                                    \
-    /*if*/ (level > orxonox::hardDebugLevel) ?                         \
-        orxonox::debugDummyFunction()                                  \
-    /*else*/ :                                                         \
-        /*if*/ (level > orxonox::OutputHandler::getSoftDebugLevel()) ? \
-            orxonox::debugDummyFunction()                              \
-        /*else*/ :                                                     \
-            orxonox::OutputHandler::getOutStream(level)
-
-/** Logs debug output: You can use DOUT exactly like @c std::cout.
-    Use this macro to produce temporary debug output that will be removed later on.
-    The console output shall have a special colour if available.
-*/
-#define DOUT orxonox::OutputHandler::getOutStream(-1) << "+++ "
-
-#endif /* _Util_Debug_H__ */
Index: code/trunk/src/libraries/util/Exception.cc
===================================================================
--- code/trunk/src/libraries/util/Exception.cc	(revision 8729)
+++ code/trunk/src/libraries/util/Exception.cc	(revision 8858)
@@ -37,5 +37,5 @@
 #include <cstddef>
 #include <CEGUIExceptions.h>
-#include "Debug.h"
+#include "Output.h"
 
 namespace orxonox
@@ -111,6 +111,6 @@
         catch (...)
         {
-            COUT(0) << "BIG WARNING: Unknown exception type encountered."
-                    << "Rethrowing" << endl;
+            orxout(user_error) << "BIG WARNING: Unknown exception type encountered."
+                               << " Rethrowing" << endl;
             throw;
         }
Index: code/trunk/src/libraries/util/Exception.h
===================================================================
--- code/trunk/src/libraries/util/Exception.h	(revision 8729)
+++ code/trunk/src/libraries/util/Exception.h	(revision 8858)
@@ -63,5 +63,5 @@
 #include <sstream>
 #include <string>
-#include "Debug.h"
+#include "Output.h"
 
 namespace orxonox
@@ -176,6 +176,6 @@
     inline const T& exceptionThrowerHelper(const T& exception)
     {
-        // let the catcher decide whether to display the message below level 4
-        COUT(4) << exception.getFullDescription() << std::endl;
+        // let the catcher decide whether to display the message also to the user
+        orxout(internal_error) << exception.getFullDescription() << endl;
         return exception;
     }
Index: code/trunk/src/libraries/util/ExprParser.h
===================================================================
--- code/trunk/src/libraries/util/ExprParser.h	(revision 8729)
+++ code/trunk/src/libraries/util/ExprParser.h	(revision 8858)
@@ -55,10 +55,10 @@
             if (!expr.getRemains().empty())
             {
-                COUT(2) << "Warning: Expression could not be parsed to the end! Remains: '" << expr.getRemains() << '\'' << std::endl;
+                orxout(user_warning) << "Expression could not be parsed to the end! Remains: '" << expr.getRemains() << '\'' << endl;
             }
             float result = expr.getResult();
         }
         else
-            COUT(1) << "Error: Cannot calculate expression: Parse error." << std::endl;
+            orxout(user_error) << "Cannot calculate expression: Parse error." << endl;
         @endcode
         getRemains() returns the expression after what could be parsed. For instance
Index: code/trunk/src/libraries/util/MultiType.h
===================================================================
--- code/trunk/src/libraries/util/MultiType.h	(revision 8729)
+++ code/trunk/src/libraries/util/MultiType.h	(revision 8858)
@@ -78,5 +78,5 @@
     void myfunction(int value)
     {
-        COUT(0) << "doubled value is " << (2 * value) << std::endl;
+        orxout() << "doubled value is " << (2 * value) << endl;
     }
 
Index: code/trunk/src/libraries/util/OrxAssert.h
===================================================================
--- code/trunk/src/libraries/util/OrxAssert.h	(revision 8729)
+++ code/trunk/src/libraries/util/OrxAssert.h	(revision 8858)
@@ -40,5 +40,5 @@
 
 #include <cassert>
-#include "Debug.h"
+#include "Output.h"
 
 #ifndef NDEBUG
@@ -46,5 +46,5 @@
 /** Run time assertion like assert(), but with an embedded message.
 @details
-    The message will be printed as error with COUT(1). <br>
+    The message will be printed as error with orxout(user_error). <br>
     You can use the same magic here as you can with \ref ThrowException
     @code
@@ -57,8 +57,8 @@
         if (!(condition)) \
         { \
-            COUT(1) << __FILE__ << "(" << __LINE__ << "): "; \
-            COUT(1) << "Assertion failed in " << __FUNCTIONNAME__ << std::endl; \
-            COUT(1) << "Expression: " << #condition << std::endl; \
-            COUT(1) << "Message   : " << errorMessage << std::endl; \
+            orxout(user_error) << __FILE__ << "(" << __LINE__ << "): "; \
+            orxout(user_error) << "Assertion failed in " << __FUNCTIONNAME__ << endl; \
+            orxout(user_error) << "Expression: " << #condition << endl; \
+            orxout(user_error) << "Message   : " << errorMessage << endl; \
             /* Don't use the condition again to avoid double evaluation */ \
             /* Instead, stringify the expression and negate it */ \
@@ -70,5 +70,5 @@
     mode (no abort() triggered then).
 @details
-    The message will be printed as error with COUT(1). <br>
+    The message will be printed as error with orxout(user_error). <br>
     You can use the same magic here as you can with \ref ThrowException
     @code
@@ -81,8 +81,8 @@
         if (!(condition)) \
         { \
-            COUT(1) << __FILE__ << "(" << __LINE__ << "): "; \
-            COUT(1) << "Verification failed in " << __FUNCTIONNAME__ << std::endl; \
-            COUT(1) << "Expression: " << #condition << std::endl; \
-            COUT(1) << "Message   : " << errorMessage << std::endl; \
+            orxout(user_error) << __FILE__ << "(" << __LINE__ << "): "; \
+            orxout(user_error) << "Verification failed in " << __FUNCTIONNAME__ << endl; \
+            orxout(user_error) << "Expression: " << #condition << endl; \
+            orxout(user_error) << "Message   : " << errorMessage << endl; \
             /* Don't use the condition again to avoid double evaluation */ \
             /* Instead, stringify the expression and negate it */ \
@@ -100,8 +100,8 @@
         if (!(condition)) \
         { \
-            COUT(1) << __FILE__ << "(" << __LINE__ << "): "; \
-            COUT(1) << "Verification failed in " << __FUNCTIONNAME__ << std::endl; \
-            COUT(1) << "Expression: " << #condition << std::endl; \
-            COUT(1) << "Message   : " << errorMessage << std::endl; \
+            orxout(user_error) << __FILE__ << "(" << __LINE__ << "): "; \
+            orxout(user_error) << "Verification failed in " << __FUNCTIONNAME__ << endl; \
+            orxout(user_error) << "Expression: " << #condition << endl; \
+            orxout(user_error) << "Message   : " << errorMessage << endl; \
             /* No assert() in release configuration */ \
         } \
Index: code/trunk/src/libraries/util/Output.h
===================================================================
--- code/trunk/src/libraries/util/Output.h	(revision 8858)
+++ code/trunk/src/libraries/util/Output.h	(revision 8858)
@@ -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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @defgroup Output Output system
+    @ingroup Util
+*/
+
+/**
+    @file
+    @ingroup Output
+    @brief Defines the helper function orxout() and includes all necessary headers to use the output system.
+
+    The output system is used to write output to the console, the logfile, and
+    other instances of orxonox::OutputListener. Each line of output is assigned
+    a level and a context. The level defines the type and importance of a
+    message, e.g. if it's a fatal error or just some internal information.
+    The context defines to which part of the program the output belongs.
+    Levels and contexts are defined in OutputDefinitions.h
+
+    Each orxonox::OutputListener can define a mask of desired levels and
+    contexts, to receive only a part of the output. Instances of
+    orxonox::SubcontextOutputListener are even able to filter sub-contexts.
+    A derivative of orxonox::BaseWriter is able to define these levels and
+    contexts through config values.
+
+    @attention
+    A message sent to the output system MUST end with "endl" or the message
+    won't be flushed.
+
+    @code
+    orxout() << "Debug output" << endl;
+    orxout(user_info) << "Orxonox version 1.2.3" << endl;
+    orxout(internal_status, context::input) << "Loading joystick" << endl;
+    @endcode
+*/
+
+#ifndef _Output_H__
+#define _Output_H__
+
+#include "UtilPrereqs.h"
+#include "output/OutputStream.h"
+
+namespace orxonox
+{
+    // Just for convenience
+    using std::endl;
+
+    /**
+        @brief This helper function returns a reference to a commonly used
+        instance of OutputStream.
+
+        It can be used like std::cout except that it is a function. You can
+        pass level and context of the following output as function arguments.
+    */
+    inline OutputStream& orxout(OutputLevel level = level::debug_output, const OutputContextContainer& context = context::undefined())
+    {
+        static OutputStream stream;
+        stream.setOutputAttributes(level, context);
+        return stream;
+    }
+
+    /**
+        @brief Shortcut for orxout() to allow passing contexts directly as
+        functions without using "()".
+
+        @code
+        orxout(user_info, context::example) << "Hello World" << endl; // calls this function
+        orxout(user_info, context::example()) << "Hello World" << endl; // calls the other orxout function
+        @endcode
+    */
+    inline OutputStream& orxout(OutputLevel level, OutputContextFunction context)
+    {
+        return orxout(level, context());
+    }
+
+    // COUT() is deprecated, please use orxout()
+    inline __DEPRECATED__(OutputStream& COUT(int level));
+
+    /**
+        @brief Writes output to the orxonox console. This function is deprecated, please use orxout()
+        @note The output level argument is ignored since it's not supported anymore. See orxout() for the new output levels.
+        @deprecated This function is deprecated. Use orxout() instead.
+    */
+    inline OutputStream& COUT(int)
+    {
+        return orxout();
+    }
+}
+
+#endif /* _Output_H__ */
Index: code/trunk/src/libraries/util/OutputHandler.cc
===================================================================
--- code/trunk/src/libraries/util/OutputHandler.cc	(revision 8729)
+++ 	(revision )
@@ -1,356 +1,0 @@
-/*
- *   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
-    Definition of classes related to output (logging).
-*/
-
-#include "OutputHandler.h"
-
-#include <algorithm>
-#include <ctime>
-#include <cstdlib>
-#include <fstream>
-#include <iostream>
-#include <sstream>
-
-#include "Debug.h"
-
-namespace orxonox
-{
-    //! How the log file shall be named on the filesystem
-    const std::string logFileBaseName_g = "orxonox.log";
-
-    /////////////////////////
-    ///// LogFileWriter /////
-    /////////////////////////
-    /**
-    @brief
-        Writes the output to the log file.
-    @note
-        As long as the correct log path is not yet known (for pre main code), the
-        LogFileWriter will write to a temporary file in /temp (Unix) or %TEMP% (Windows).
-        As soon as you set the correct path setLogPath the content of the temporary file
-        is read and put into the new file as well.
-    */
-    class LogFileWriter : public OutputListener
-    {
-    public:
-        /**
-        @brief
-            Gets temporary log path and starts the log file
-        */
-        LogFileWriter()
-            : OutputListener("LogFile")
-        {
-            // Get path for a temporary file
-#ifdef ORXONOX_PLATFORM_WINDOWS
-            char* pTempDir = getenv("TEMP");
-            this->logFilename_ = std::string(pTempDir) + '/' + logFileBaseName_g;
-#else
-            this->logFilename_ = std::string("/tmp/") + logFileBaseName_g;
-#endif
-
-            // Get current time
-            time_t rawtime;
-            struct tm* timeinfo;
-            time(&rawtime);
-            timeinfo = localtime(&rawtime);
-
-            this->openFile();
-            if (this->logFile_.is_open())
-            {
-                this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl;
-                this->logFile_.flush();
-            }
-        }
-
-        //! Closes the log file
-        ~LogFileWriter()
-        {
-            if (this->logFile_.is_open())
-            {
-                this->logFile_ << "Closed log" << std::endl;
-                this->logFile_.close();
-            }
-        }
-
-        //! Changes the log path
-        void setLogPath(const std::string& path)
-        {
-            if (this->logFile_.is_open())
-                this->logFile_.close();
-
-            // Open the new file
-            this->logFilename_ = path + logFileBaseName_g;
-            this->openFile();
-        }
-
-        //! Erases the log file
-        void clearFile()
-        {
-            if (this->logFile_.is_open())
-            {
-                this->logFile_.close();
-                this->openFile();
-            }
-        }
-
-    private:
-        void openFile()
-        {
-            this->logFile_.open(this->logFilename_.c_str(), std::fstream::out);
-
-            if (this->logFile_.is_open())
-                this->outputStream_ = &this->logFile_;
-            else
-            {
-                COUT(2) << "Warning: Failed to open log file. File logging disabled." << std::endl;
-                this->outputStream_ = NULL;
-            }
-        }
-
-        std::ofstream logFile_;     //!< File handle for the log file
-        std::string   logFilename_; //!< Filename of the log file
-    };
-
-
-    /////////////////////////
-    ///// ConsoleWriter /////
-    /////////////////////////
-    /**
-    @brief
-        Writes the output to std::cout.
-    @note
-        This listener will usually be disable once an actual shell with console is instantiated.
-    */
-    class ConsoleWriter : public OutputListener
-    {
-    public:
-        //! Only assigns the output stream with std::cout
-        ConsoleWriter()
-            : OutputListener("Console")
-        {
-            this->outputStream_ = &std::cout;
-        }
-    };
-
-
-    ///////////////////////////
-    ///// MemoryLogWriter /////
-    ///////////////////////////
-    /**
-    @brief
-        OutputListener that writes all the output piece by piece to an array
-        associated with the corresponding output level.
-        Used as buffer until all output devices have been initialised.
-    @note
-        At some point, OutputHandler::disableMemoryLog() has to be called in
-        order to avoid large memory footprints of this class.
-    */
-    class MemoryLogWriter : public OutputListener
-    {
-    public:
-        friend class OutputHandler;
-
-        MemoryLogWriter()
-            : OutputListener("memoryLog")
-        {
-            this->outputStream_ = &this->buffer_;
-        }
-
-        //! Push the just written output to the internal array
-        void outputChanged(int level)
-        {
-            if (!this->buffer_.str().empty())
-            {
-                // Read ostringstream and store it
-                this->output_.push_back(std::make_pair(level, this->buffer_.str()));
-                // Clear content and flags
-                this->buffer_.str(std::string());
-            }
-            this->buffer_.clear();
-        }
-
-    private:
-        std::ostringstream          buffer_; //!< Stream object used to process the output
-        OutputHandler::OutputVector output_; //!< Vector containing ALL output
-    };
-
-
-    /////////////////////////
-    ///// OutputHandler /////
-    /////////////////////////
-    int OutputHandler::softDebugLevel_s = hardDebugLevel;
-
-    //! Creates the LogFileWriter and the MemoryLogWriter
-    OutputHandler::OutputHandler()
-        : outputLevel_(OutputLevel::Verbose)
-    {
-        // Note: These levels only concern startup before orxonox.ini is read.
-#ifdef ORXONOX_RELEASE
-        const OutputLevel::Value initialLevelConsole = OutputLevel::Error;
-#else
-        const OutputLevel::Value initialLevelConsole = OutputLevel::Info;
-#endif
-        // Use high log level because we rewrite the log file anyway with the
-        // correct level. But if Orxonox were to crash before that, we might be
-        // grateful to have a high debug level, esp. for releases.
-        const OutputLevel::Value intialLevelLogFile = OutputLevel::Debug;
-
-        this->logFile_ = new LogFileWriter();
-        // Use default level until we get the configValue from the Core
-        this->logFile_->softDebugLevel_ = intialLevelLogFile;
-        this->registerOutputListener(this->logFile_);
-
-        this->consoleWriter_ = new ConsoleWriter();
-        this->consoleWriter_->softDebugLevel_ = initialLevelConsole;
-        this->registerOutputListener(this->consoleWriter_);
-
-        this->memoryBuffer_ = new MemoryLogWriter();
-        // Write everything, e.g. use hardDebugLevel
-        this->memoryBuffer_->softDebugLevel_ = hardDebugLevel;
-        this->registerOutputListener(this->memoryBuffer_);
-    }
-
-    //! Destroys the LogFileWriter and the MemoryLogWriter
-    OutputHandler::~OutputHandler()
-    {
-        delete this->logFile_;
-        delete this->consoleWriter_;
-        delete this->memoryBuffer_; // Might already be NULL
-    }
-
-    OutputHandler& OutputHandler::getInstance()
-    {
-        static OutputHandler orxout;
-        return orxout;
-    }
-
-    void OutputHandler::registerOutputListener(OutputListener* listener)
-    {
-        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
-        {
-            if ((*it)->name_ == listener->name_)
-            {
-                COUT(2) << "OutputHandler, Warning: Trying to register two listeners with the same name!" << std::endl;
-                return;
-            }
-        }
-        this->listeners_.push_back(listener);
-        this->updateGlobalDebugLevel();
-    }
-
-    void OutputHandler::unregisterOutputListener(OutputListener* listener)
-    {
-        for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
-        {
-            if ((*it)->name_ == listener->name_)
-            {
-                this->listeners_.erase(it);
-                break;
-            }
-        }
-        this->updateGlobalDebugLevel();
-    }
-
-    void OutputHandler::setLogPath(const std::string& path)
-    {
-        this->logFile_->setLogPath(path);
-        this->rewriteLogFile();
-    }
-
-    void OutputHandler::rewriteLogFile()
-    {
-        logFile_->clearFile();
-
-        if (logFile_->outputStream_ == NULL)
-            return;
-
-        for (OutputVector::const_iterator it = this->getOutput().begin(); it != this->getOutput().end(); ++it)
-        {
-            if (it->first <= logFile_->softDebugLevel_)
-                (*logFile_->outputStream_) << it->second;
-        }
-        logFile_->outputStream_->flush();
-    }
-
-    void OutputHandler::disableCout()
-    {
-        this->unregisterOutputListener(this->consoleWriter_);
-    }
-
-    void OutputHandler::enableCout()
-    {
-        this->registerOutputListener(this->consoleWriter_);
-    }
-
-    void OutputHandler::disableMemoryLog()
-    {
-        this->unregisterOutputListener(this->memoryBuffer_);
-        // Only clear the buffer so we can still reference the vector
-        this->memoryBuffer_->output_.clear();
-    }
-
-    const OutputHandler::OutputVector& OutputHandler::getOutput() const
-    {
-        return this->memoryBuffer_->output_;
-    }
-
-    int OutputHandler::getSoftDebugLevel(const std::string& name) const
-    {
-        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
-        {
-            if ((*it)->name_ == name)
-                return (*it)->softDebugLevel_;
-        }
-        return -1;
-    }
-
-    void OutputHandler::setSoftDebugLevel(const std::string& name, int level)
-    {
-        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
-        {
-            if ((*it)->name_ == name)
-                (*it)->softDebugLevel_ = level;
-        }
-        this->updateGlobalDebugLevel();
-    }
-
-    void OutputHandler::updateGlobalDebugLevel()
-    {
-        int globalSoftDebugLevel = -1;
-        std::vector<OutputListener*>::const_iterator it = this->listeners_.begin();
-        for (; it != this->listeners_.end(); ++it)
-            globalSoftDebugLevel = std::max(globalSoftDebugLevel, (*it)->softDebugLevel_);
-
-        OutputHandler::softDebugLevel_s = globalSoftDebugLevel;
-    }
-}
Index: code/trunk/src/libraries/util/OutputHandler.h
===================================================================
--- code/trunk/src/libraries/util/OutputHandler.h	(revision 8729)
+++ 	(revision )
@@ -1,285 +1,0 @@
-/*
- *   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
-@ingroup Util Output
-@brief
-    Declaration of classes related to output (logging), most notably OutputHandler and OutputListener.
-*/
-
-#ifndef _OutputHandler_H__
-#define _OutputHandler_H__
-
-#include "UtilPrereqs.h"
-
-#include <ostream>
-#include <string>
-#include <vector>
-#include <utility>
-
-namespace orxonox
-{
-    /**
-    @brief
-        Denotes different levels of text output (log output)
-
-         - 0, None   : Very important output
-         - 1, Error  : Errors
-         - 2, Warning: Warnings
-         - 3, Info   : Information
-         - 4, Debug  : Debug information
-         - 5, Verbose: More debug information
-         - 6, Ultra  : Crazy debug information
-    */
-    namespace OutputLevel
-    {
-        enum Value
-        {
-            TDebug  = -1,
-            None    = 0,
-            Error   = 1,
-            Warning = 2,
-            Info    = 3,
-            Debug   = 4,
-            Verbose = 5,
-            Ultra   = 6,
-        };
-    }
-
-    // Forward declarations for classes in the source file
-    class LogFileWriter;
-    class ConsoleWriter;
-    class MemoryLogWriter;
-
-    /**
-    @brief
-        The OutputHandler acts like @c std::cout, but output isn't only shown in the console.
-
-        Output passed to the OutputHandler is distributed to all registered listeners,
-        for example the console, the logfile, or the ingame shell.
-
-        You can register your own listener for output by inheriting from OutputListener.
-        And if you need the output previously processed, iterate over it with
-        OutputHandler::getOutputVectorBegin and OutputHandler::getOutputVectorEnd.
-
-        The way to output text is to first set the desired output level with
-        @ref getOutStream "OutputHandler::getOutStream(level)" and then use
-        the "<<" operator like with @c std::cout. Alternatively you can use the COUT() macro.
-    */
-    class _UtilExport OutputHandler
-    {
-        public:
-            //! Returns a reference to the only existing instance of the OutputHandler class.
-            static OutputHandler& getInstance();
-
-            //! Sets the output level and returns a stream to be used with "<<"
-            static inline OutputHandler& getOutStream(int level)
-                { return OutputHandler::getInstance().setOutputLevel(level); }
-
-            typedef std::vector<std::pair<int, std::string> > OutputVector;
-            //! Returns all output written so far (empty if disableMemoryLog() was called)
-            const OutputVector& getOutput() const;
-
-            //! Writes to all output devices
-            static inline void log(const std::string& text)
-                { OutputHandler::getOutStream(0).output(text) << std::endl; }
-
-            //! Writes an error message to the output
-            static inline void error(const std::string& text)
-                { OutputHandler::getOutStream(1).output(text) << std::endl; }
-
-            //! Writes a warning message to the output
-            static inline void warning(const std::string& text)
-                { OutputHandler::getOutStream(2).output(text) << std::endl; }
-
-            //! Writes an informational message to the output
-            static inline void info(const std::string& text)
-                { OutputHandler::getOutStream(3).output(text) << std::endl; }
-
-            //! Writes a debug message to the output
-            static inline void debug(const std::string& text)
-                { OutputHandler::getOutStream(4).output(text) << std::endl; }
-
-            //! Registers an object that receives output via a provided std::ostream
-            void registerOutputListener(OutputListener* listener);
-            //! Unregisters an object that receives output via a provided std::ostream
-            void unregisterOutputListener(OutputListener* listener);
-
-            //! Set the log path once the program has been properly initialised
-            void setLogPath(const std::string& path);
-            /** Rewrites the log file (completely respects the current debug level).
-                Once disableMemoryLog() has been called, this function will do nothing.
-            */
-            void rewriteLogFile();
-
-            //! Disables the std::cout stream for output
-            void disableCout();
-            //! Enables the std::cout stream for output (startup behaviour)
-            void enableCout();
-            //! Stop writing to the memory buffer (call this as soon as possible to minimise memory usage)
-            void disableMemoryLog();
-
-            //! Sets the level of the incoming output and returns the OutputHandler
-            inline OutputHandler& setOutputLevel(int level)
-                { this->outputLevel_ = level; return *this; }
-
-            //! Returns the level of the incoming output
-            inline int getOutputLevel() const
-                { return this->outputLevel_; }
-
-            //! Returns the maximum debug level over all registered listeners (devices)
-            static int getSoftDebugLevel() { return softDebugLevel_s; }
-            //! Returns the soft debug level for a device by its name   @return The level or -1 if the listener was not found
-            int  getSoftDebugLevel(const std::string& name) const;
-            //! Sets the soft debug level for a listener by its name   @remarks Only works for registered listeners!
-            void setSoftDebugLevel(const std::string& name, int level);
-
-            /**
-            @brief
-                General template that copes with all output.
-                Required because operator << might be ambiguous.
-                @a output will be streamed into every listener with an appropriate debug level
-            @return
-                Returns a reference to the OutputHandler so you can use it again directly
-            */
-            template <class T>
-            OutputHandler& output(const T& output);
-
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(short val)              { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(int val)                { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(long val)               { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(float val)              { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(double val)             { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
-
-            //! Overloaded << operator, redirects the output to the listeners
-            inline OutputHandler& operator<<(std::streambuf* sb)     { return this->output(sb); }
-
-            //! Overloaded << operator, redirect the output of classes with self defined 'operator <<' to the listeners
-            template <class T>
-            inline OutputHandler& operator<<(const T& val)           { return this->output(val); }
-
-            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
-            inline OutputHandler& operator<<(std::ostream&  (*manip)(std::ostream&))  { return this->output(manip); }
-            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
-            inline OutputHandler& operator<<(std::ios&      (*manip)(std::ios&))      { return this->output(manip); }
-            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
-            inline OutputHandler& operator<<(std::ios_base& (*manip)(std::ios_base&)) { return this->output(manip); }
-
-            //! Dummy operator required by Debug.h for the ternary operator
-            inline operator int() const { return 0; }
-
-        private:
-            OutputHandler();
-            ~OutputHandler();
-            OutputHandler(const OutputHandler& rhs);      //!< Copy-constructor: Unused and undefined
-
-            /// Evaluates the maximum global log level
-            void updateGlobalDebugLevel();
-
-            std::vector<OutputListener*> listeners_;        //!< Array with all registered output listeners
-            int                          outputLevel_;      //!< The level of the incoming output
-            LogFileWriter*               logFile_;          //!< Writes output to the log file
-            ConsoleWriter*               consoleWriter_;    //!< Writes to std::cout (can be disabled)
-            MemoryLogWriter*             memoryBuffer_;     //!< Writes to memory as a buffer (can/must be stopped at some time)
-            static int                   softDebugLevel_s;  //!< Maximum of all soft debug levels. @note This is only static for faster access
-    };
-
-    /**
-    @brief
-        Interface for listening to output.
-    @remarks
-        Remember to register the listener (not done automatically!)
-    */
-    class OutputListener
-    {
-        friend class OutputHandler;
-
-    public:
-        OutputListener(const std::string& name)
-            : outputStream_(NULL)
-            , name_(name)
-            , softDebugLevel_(OutputLevel::Info)
-        {}
-        virtual ~OutputListener() {}
-
-        //! Gets called whenever output is put into the stream
-        virtual void outputChanged(int level) {}
-        //! Returns the name of this output listener
-        const std::string& getOutputListenerName() const { return this->name_; }
-
-    protected:
-        std::ostream*     outputStream_;   //!< Pointer to the associated output stream, can be NULL
-
-    private:
-        const std::string name_;           //!< Name of the listener, constant and unique!
-        int               softDebugLevel_; //!< Current soft debug level that defines what kind of output is written to the stream
-    };
-
-    template<class T>
-    inline OutputHandler& OutputHandler::output(const T& output)
-    {
-        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
-        {
-            if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL)
-            {
-                std::ostream& stream = *((*it)->outputStream_);
-                stream << output;
-                stream.flush();
-                (*it)->outputChanged(this->outputLevel_);
-            }
-        }
-
-        return *this;
-    }
-}
-
-#endif /* _OutputHandler_H__ */
Index: code/trunk/src/libraries/util/Scope.h
===================================================================
--- code/trunk/src/libraries/util/Scope.h	(revision 8729)
+++ code/trunk/src/libraries/util/Scope.h	(revision 8858)
@@ -60,5 +60,5 @@
 #include <loki/ScopeGuard.h>
 
-#include "Debug.h"
+#include "Output.h"
 
 namespace orxonox
@@ -128,4 +128,6 @@
             Scope()
             {
+                orxout(internal_status) << "creating scope... (" << scope << ")" << endl;
+
                 try
                 {
@@ -148,4 +150,6 @@
                     throw;
                 }
+
+                orxout(internal_status) << "created scope (" << scope << ")" << endl;
             }
 
@@ -153,4 +157,6 @@
             ~Scope()
             {
+                orxout(internal_status) << "destroying scope... (" << scope << ")" << endl;
+
                 ScopeManager::instanceCounts_s[scope]--;
 
@@ -162,4 +168,6 @@
                 if (ScopeManager::instanceCounts_s[scope] == 0)
                     this->deactivateListeners();
+
+                orxout(internal_status) << "destroyed scope (" << scope << ")" << endl;
             }
 
@@ -174,5 +182,5 @@
                             { (*it)->deactivated(); }
                         catch (...)
-                            { COUT(0) << "ScopeListener::deactivated() failed! This MUST NOT happen, fix it!" << std::endl; }
+                            { orxout(internal_warning) << "ScopeListener::deactivated() failed! This MUST NOT happen, fix it!" << endl; }
                         (*(it++))->bActivated_ = false;
                     }
Index: code/trunk/src/libraries/util/ScopedSingletonManager.h
===================================================================
--- code/trunk/src/libraries/util/ScopedSingletonManager.h	(revision 8729)
+++ code/trunk/src/libraries/util/ScopedSingletonManager.h	(revision 8858)
@@ -231,7 +231,7 @@
                 { singletonPtr_ = new T(); }
             catch (const InitialisationAbortedException& ex)
-                { COUT(3) << ex.getDescription() << std::endl; }
+                { orxout(internal_error) << ex.getDescription() << endl; }
             catch (...)
-                { COUT(1) << "Singleton creation failed: " << Exception::handleMessage() << std::endl; }
+                { orxout(internal_error) << "Singleton creation failed: " << Exception::handleMessage() << endl; }
         }
 
Index: code/trunk/src/libraries/util/SignalHandler.cc
===================================================================
--- code/trunk/src/libraries/util/SignalHandler.cc	(revision 8729)
+++ code/trunk/src/libraries/util/SignalHandler.cc	(revision 8858)
@@ -39,5 +39,5 @@
 #include <cstdio>
 
-#include "Debug.h"
+#include "Output.h"
 
 namespace orxonox
@@ -127,5 +127,5 @@
       if( SignalHandler::singletonPtr_s == 0 )
       {
-        COUT(0) << "Received signal " << sigName.c_str() << std::endl << "Can't write backtrace because SignalHandler is already destroyed" << std::endl;
+        orxout(user_error) << "Received signal " << sigName.c_str() << endl << "Can't write backtrace because SignalHandler is already destroyed" << endl;
         exit(EXIT_FAILURE);
       }
@@ -137,5 +137,5 @@
 
 
-      COUT(0) << "Received signal " << sigName.c_str() << std::endl << "Try to write backtrace to file orxonox_crash.log" << std::endl;
+      orxout(user_error) << "Received signal " << sigName.c_str() << endl << "Try to write backtrace to file orxonox_crash.log" << endl;
 
       
@@ -206,5 +206,5 @@
 #ifdef PR_SET_PTRACER
         if( prctl(PR_SET_PTRACER, gdbPid, 0, 0, 0) == -1 )
-          COUT(0) << "could not set proper permissions for GDB to attach to process..." << endl;
+          orxout(user_error) << "could not set proper permissions for GDB to attach to process..." << endl;
 #endif
         
@@ -213,9 +213,9 @@
 
         if( read( sigPipe[0], &someData, sizeof(someData) ) != sizeof(someData) )
-          COUT(0) << "something went wrong :(" << std::endl;
+          orxout(user_error) << "something went wrong :(" << endl;
 
         if ( someData != 0x12345678 )
         {
-          COUT(0) << "something went wrong :(" << std::endl;
+          orxout(user_error) << "something went wrong :(" << endl;
         }
 
@@ -328,5 +328,5 @@
       if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() )
       {
-        COUT(0) << "could not write " << bt.length() << " byte to " << getInstance().filename << std::endl;
+        orxout(user_error) << "could not write " << bt.length() << " byte to " << getInstance().filename << endl;
         exit(EXIT_FAILURE);
       }
@@ -364,6 +364,7 @@
 _UtilExport void __cdecl abort()
 {
-    COUT(1) << "This application has requested the Runtime to terminate it in an unusual way." << std::endl;
-    COUT(1) << "Please contact the application's support team for more information." << std::endl;
+    using namespace orxonox;
+    orxout(user_error) << "This application has requested the Runtime to terminate it in an unusual way." << endl;
+    orxout(user_error) << "Please contact the application's support team for more information." << endl;
     DebugBreak();
     exit(0x3);
@@ -373,6 +374,7 @@
 _UtilExport void __cdecl _assert(const char* expression, const char* file, int line)
 {
-    COUT(1) << "Assertion failed: " << expression << ", file " << file << ", line " << line << std::endl;
-    COUT(1) << std::endl;
+    using namespace orxonox;
+    orxout(user_error) << "Assertion failed: " << expression << ", file " << file << ", line " << line << endl;
+    orxout(user_error) << endl;
     abort();
 }
@@ -423,14 +425,14 @@
             bExecuting = true;
 
-            COUT(1) << std::endl;
+            orxout(user_error) << endl;
 
             // if the signalhandler has already been destroyed then don't do anything
             if (SignalHandler::singletonPtr_s == 0)
             {
-                COUT(1) << "Caught an unhandled exception" << std::endl << "Can't write backtrace because SignalHandler is already destroyed" << std::endl;
+                orxout(user_error) << "Caught an unhandled exception" << endl << "Can't write backtrace because SignalHandler is already destroyed" << endl;
                 exit(EXIT_FAILURE);
             }
 
-            COUT(1) << "Caught an unhandled exception" << std::endl << "Try to write backtrace to orxonox_crash.log..." << std::endl;
+            orxout(user_error) << "Caught an unhandled exception" << endl << "Try to write backtrace to orxonox_crash.log..." << endl;
 
             // write the crash log
@@ -439,27 +441,27 @@
             time_t now = time(NULL);
 
-            crashlog << "=======================================================" << std::endl;
+            crashlog << "=======================================================" << endl;
             crashlog << "= Time: " << std::string(ctime(&now));
-            crashlog << "=======================================================" << std::endl;
-            crashlog << std::endl;
+            crashlog << "=======================================================" << endl;
+            crashlog << endl;
 
             const std::string& error = SignalHandler::getExceptionType(pExceptionInfo);
 
-            crashlog << error << std::endl;
-            crashlog << std::endl;
+            crashlog << error << endl;
+            crashlog << endl;
 
             const std::string& callstack = SignalHandler::getStackTrace(pExceptionInfo);
 
-            crashlog << "Call stack:" << std::endl;
-            crashlog << callstack << std::endl;
+            crashlog << "Call stack:" << endl;
+            crashlog << callstack << endl;
 
             crashlog.close();
 
             // print the same information also to the console
-            COUT(1) << std::endl;
-            COUT(1) << error << std::endl;
-            COUT(1) << std::endl;
-            COUT(1) << "Call stack:" << std::endl;
-            COUT(1) << callstack << std::endl;
+            orxout(user_error) << endl;
+            orxout(user_error) << error << endl;
+            orxout(user_error) << endl;
+            orxout(user_error) << "Call stack:" << endl;
+            orxout(user_error) << callstack << endl;
 
             bExecuting = false;
@@ -467,5 +469,5 @@
         else
         {
-            COUT(1) << "An error occurred while writing the backtrace" << std::endl;
+            orxout(user_error) << "An error occurred while writing the backtrace" << endl;
         }
 
Index: code/trunk/src/libraries/util/Singleton.h
===================================================================
--- code/trunk/src/libraries/util/Singleton.h	(revision 8729)
+++ code/trunk/src/libraries/util/Singleton.h	(revision 8858)
@@ -100,5 +100,5 @@
     void TestSingleton::testFunction()                      // implement testFunction
     {
-        COUT(0) << "My value is " << this->testValue_ << std::endl;
+        orxout() << "My value is " << this->testValue_ << endl;
     }
 
Index: code/trunk/src/libraries/util/Sleep.cc
===================================================================
--- code/trunk/src/libraries/util/Sleep.cc	(revision 8729)
+++ code/trunk/src/libraries/util/Sleep.cc	(revision 8858)
@@ -34,5 +34,5 @@
 
 #include "Sleep.h"
-#include "Debug.h"
+#include "Output.h"
 
 #ifdef ORXONOX_PLATFORM_WINDOWS
@@ -49,5 +49,5 @@
     {
         //if (microseconds < 1000)
-        //    COUT(2) << "Warning: Windows cannot sleep less than 1ms, ignoring" << std::endl;
+        //    orxout(internal_warning) << "Windows cannot sleep less than 1ms, ignoring" << endl;
         Sleep(microseconds / 1000);
     }
Index: code/trunk/src/libraries/util/StringUtils.cc
===================================================================
--- code/trunk/src/libraries/util/StringUtils.cc	(revision 8729)
+++ code/trunk/src/libraries/util/StringUtils.cc	(revision 8858)
@@ -79,4 +79,14 @@
         for (; pos2 > 0         && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);
         return str.substr(pos1, pos2 - pos1 + 1);
+    }
+
+    /// Splits a given string by a delimiter and stores it in an output vector
+    void vectorize(const std::string& str, char delimiter, std::vector<std::string>* output)
+    {
+        for (size_t start = 0, end = 0; end != std::string::npos; start = end + 1)
+        {
+            end = str.find_first_of(delimiter, start);
+            output->push_back(str.substr(start, end - start));
+        }
     }
 
@@ -517,5 +527,5 @@
         return matrix[(rows-1)*cols + cols-1];
     }
-    
+
     /**
     @brief
Index: code/trunk/src/libraries/util/StringUtils.h
===================================================================
--- code/trunk/src/libraries/util/StringUtils.h	(revision 8729)
+++ code/trunk/src/libraries/util/StringUtils.h	(revision 8858)
@@ -43,4 +43,5 @@
 #include "UtilPrereqs.h"
 #include <string>
+#include <vector>
 
 namespace orxonox
@@ -54,4 +55,6 @@
 
     _UtilExport std::string  removeTrailingWhitespaces(const std::string& str);
+
+    _UtilExport void         vectorize(const std::string& str, char delimiter, std::vector<std::string>* output);
 
     _UtilExport size_t       getNextQuote(const std::string& str, size_t start);
@@ -88,5 +91,5 @@
 
     _UtilExport unsigned int getLevenshteinDistance(const std::string& str1, const std::string& str2);
-    
+
     _UtilExport std::string  getTimestamp(void);
 }
Index: code/trunk/src/libraries/util/SubString.cc
===================================================================
--- code/trunk/src/libraries/util/SubString.cc	(revision 8729)
+++ code/trunk/src/libraries/util/SubString.cc	(revision 8858)
@@ -45,5 +45,5 @@
 #include "SubString.h"
 #include <cstdio>
-#include "Debug.h"
+#include "Output.h"
 
 namespace orxonox
@@ -513,8 +513,8 @@
     void SubString::debug() const
     {
-        COUT(0) << "Substring-information::count=" << this->tokens_.size() << " ::";
+        orxout(debug_output) << "Substring-information::count=" << this->tokens_.size() << " ::";
         for (unsigned int i = 0; i < this->tokens_.size(); ++i)
-            COUT(0) << "s" << i << "='" << this->tokens_[i].c_str() << "'::";
-        COUT(0) << std::endl;
+            orxout(debug_output) << "s" << i << "='" << this->tokens_[i].c_str() << "'::";
+        orxout(debug_output) << endl;
     }
 }
Index: code/trunk/src/libraries/util/SubString.h
===================================================================
--- code/trunk/src/libraries/util/SubString.h	(revision 8729)
+++ code/trunk/src/libraries/util/SubString.h	(revision 8858)
@@ -59,5 +59,5 @@
 
     for (unsigned int i = 0; i < tokens.size(); ++i)
-        COUT(0) << i << ": " << tokens[i] << std::endl;
+        orxout() << i << ": " << tokens[i] << endl;
     @endcode
 
Index: code/trunk/src/libraries/util/UtilPrereqs.h
===================================================================
--- code/trunk/src/libraries/util/UtilPrereqs.h	(revision 8729)
+++ code/trunk/src/libraries/util/UtilPrereqs.h	(revision 8858)
@@ -88,6 +88,7 @@
     class ExprParser;
     class MultiType;
-    class OutputHandler;
     class OutputListener;
+    class OutputManager;
+    class OutputStream;
     template <ScopeID::Value>
     class Scope;
Index: code/trunk/src/libraries/util/output/BaseWriter.cc
===================================================================
--- code/trunk/src/libraries/util/output/BaseWriter.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/BaseWriter.cc	(revision 8858)
@@ -0,0 +1,147 @@
+/*
+ *   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 BaseWriter class.
+*/
+
+#include "BaseWriter.h"
+
+#include "OutputManager.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor: Initializes the config-values.
+    */
+    BaseWriter::BaseWriter(const std::string& name, bool bRegister) : SubcontextOutputListener(bRegister)
+    {
+        this->name_ = name;
+
+        this->configurableMaxLevel_ = level::none;
+        this->configurableAdditionalContextsMaxLevel_ = level::verbose;
+        this->configurableAdditionalContexts_.push_back("example");
+
+        this->changedConfigurableLevel();
+        this->changedConfigurableAdditionalContextsLevel();
+        this->changedConfigurableAdditionalContexts();
+    }
+
+    /**
+        @brief Destructor.
+    */
+    BaseWriter::~BaseWriter()
+    {
+    }
+
+    /**
+        @brief This function is inherited from OutputListener, each message is split into lines and sent to printLine().
+    */
+    void BaseWriter::output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
+    {
+        const std::string& prefix = OutputManager::getInstance().getDefaultPrefix(level, context);
+        std::string blanks(prefix.length(), ' ');
+
+        for (size_t i = 0; i < lines.size(); ++i)
+            this->printLine((i == 0 ? prefix : blanks) + lines[i], level);
+    }
+
+    /**
+        @brief Overwritten implementation of the function inherited from OutputListener, sets also the corresponding config-value.
+    */
+    void BaseWriter::setLevelMax(OutputLevel max)
+    {
+        this->configurableMaxLevel_ = max;
+        this->changedConfigurableLevel();
+    }
+
+    /**
+        @brief Overwritten implementation of the function inherited from OutputListener, sets also the corresponding config-value.
+    */
+    void BaseWriter::setAdditionalContextsLevelMax(OutputLevel max)
+    {
+        this->configurableAdditionalContextsMaxLevel_ = max;
+        this->changedConfigurableAdditionalContextsLevel();
+    }
+
+    /**
+        @brief Called if the config value has changed, updates the corresponding mask in OutputListener.
+    */
+    void BaseWriter::changedConfigurableLevel()
+    {
+        OutputListener::setLevelMax(static_cast<OutputLevel>(this->configurableMaxLevel_));
+    }
+
+    /**
+        @brief Called if the config value has changed, updates the corresponding mask in OutputListener.
+    */
+    void BaseWriter::changedConfigurableAdditionalContextsLevel()
+    {
+        OutputListener::setAdditionalContextsLevelMax(static_cast<OutputLevel>(this->configurableAdditionalContextsMaxLevel_));
+    }
+
+    /**
+        @brief Called if the config-vector of accepted contexts has changed, updates the masks in SubcontextOutputListener.
+    */
+    void BaseWriter::changedConfigurableAdditionalContexts()
+    {
+        OutputContextMask main_contexts = context::none;
+        std::set<const OutputContextContainer*> sub_contexts;
+
+        // iterate over all strings in the config-vector
+        for (size_t i = 0; i < this->configurableAdditionalContexts_.size(); ++i)
+        {
+            const std::string& full_name = this->configurableAdditionalContexts_[i];
+
+            // split the name into main-name and sub-name (if given; otherwise sub-name remains empty). both names are separated by ::
+            std::string name = full_name;
+            std::string subname;
+
+            size_t pos = full_name.find("::");
+            if (pos != std::string::npos)
+            {
+                name = full_name.substr(0, pos);
+                subname = full_name.substr(pos + 2);
+            }
+
+            // get the context defined by this name
+            const OutputContextContainer& context = OutputManager::getInstance().registerContext(name, subname);
+
+            // if the context is a sub-context, insert it to the set of sub-contexts. Otherwise add it's mask to the mask of main-contexts.
+            if (context.sub_id == context::no_subcontext)
+                main_contexts |= context.mask;
+            else
+                sub_contexts.insert(&context);
+        }
+
+        // pass main-contexts and sub-contexts to SubcontextOutputListener
+        this->setAdditionalContextsMask(main_contexts);
+        this->setAdditionalSubcontexts(sub_contexts);
+    }
+}
Index: code/trunk/src/libraries/util/output/BaseWriter.h
===================================================================
--- code/trunk/src/libraries/util/output/BaseWriter.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/BaseWriter.h	(revision 8858)
@@ -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:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the BaseWriter class, the base of all output writers.
+*/
+
+#ifndef _BaseWriter_H__
+#define _BaseWriter_H__
+
+#include "util/UtilPrereqs.h"
+#include "SubcontextOutputListener.h"
+
+namespace orxonox
+{
+    /**
+        @brief BaseWriter is an output listener and makes the accepted output levels and contexts configurable.
+
+        All output writers like ConsoleWriter and LogWriter are inherited from
+        this class. BaseWriter itself inherits from SubcontextOutputListener.
+        It adds helper functions to configure the accepted levels and contexts.
+
+        The levels are not fully configurable, only the "max" form is allowed
+        (which means that it's only possible to define a maximum level, not
+        the full mask).
+
+        Contexts are defined by a vector of strings, each context is defined
+        by it's name. Sub-contexts have the form \a "main-name::sub-name", i.e.
+        their name is concatenated with :: in between.
+
+        Each instance of BaseWriter needs a name to generate distinguishable
+        config values.
+
+        Received output messages are split into lines and sent line by line to
+        the virtual printLine() function. Each line has a prepended prefix
+        which describes the level and context of the output.
+    */
+    class _UtilExport BaseWriter : public SubcontextOutputListener
+    {
+        public:
+            BaseWriter(const std::string& name, bool bRegister = true);
+            virtual ~BaseWriter();
+
+            void setLevelMax(OutputLevel max);
+            void setAdditionalContextsLevelMax(OutputLevel max);
+
+            /// @brief Returns the name of this instance.
+            const std::string& getName() const
+                { return this->name_; }
+
+            /// Config value, used to define the maximum output level (independent of contexts)
+            int configurableMaxLevel_;
+            /// @brief Returns the name of the config value which defines the maximum output level (independent of contexts).
+            inline std::string getConfigurableMaxLevelName() const
+                { return this->name_ + "Level"; }
+
+            /// Config value, used to define the maximum output level of additional context
+            int configurableAdditionalContextsMaxLevel_;
+            /// @brief Returns the name of the config value which defines the maximum output level of additional context.
+            inline std::string getConfigurableAdditionalContextsMaxLevelName() const
+                { return this->name_ + "AdditionalContextsLevel"; }
+
+            /// Config vector, used to define the additional contexts (and sub-contexts)
+            std::vector<std::string> configurableAdditionalContexts_;
+            /// @brief Returns the name of the config vector which defines the additional contexts (and sub-contexts)
+            inline std::string getConfigurableAdditionalContextsName() const
+                { return this->name_ + "AdditionalContexts"; }
+
+            void changedConfigurableLevel();
+            void changedConfigurableAdditionalContextsLevel();
+            void changedConfigurableAdditionalContexts();
+
+            /// Returns the (static) name of the section wherein the config-values are defined.
+            static inline std::string getConfigurableSectionName()
+                { return "Output"; }
+
+        protected:
+            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines);
+
+        private:
+            virtual void printLine(const std::string& line, OutputLevel level) = 0; ///< Pure virtual function, gets called for each line of output together with a prefix which describes level and context of the output.
+
+            void setLevelRange(OutputLevel min, OutputLevel max);                   ///< Inherited function, overwritten as private because it is not supported by the config-value
+            void setLevelMask(OutputLevel mask);                                    ///< Inherited function, overwritten as private because it is not supported by the config-value
+
+            void setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max); ///< Inherited function, overwritten as private because it is not supported by the config-value
+            void setAdditionalContextsLevelMask(OutputLevel mask);                  ///< Inherited function, overwritten as private because it is not supported by the config-value
+
+            std::string name_; ///< The name of this instance, used to generate unique config-values
+    };
+}
+
+#endif /* _BaseWriter_H__ */
Index: code/trunk/src/libraries/util/output/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/util/output/CMakeLists.txt	(revision 8858)
+++ code/trunk/src/libraries/util/output/CMakeLists.txt	(revision 8858)
@@ -0,0 +1,12 @@
+ADD_SOURCE_FILES(UTIL_SRC_FILES
+BUILD_UNIT OutputBuildUnit.cc
+  OutputStream.cc
+  OutputManager.cc
+  OutputListener.cc
+  SubcontextOutputListener.cc
+  BaseWriter.cc
+  ConsoleWriter.cc
+  LogWriter.cc
+  MemoryWriter.cc
+END_BUILD_UNIT
+)
Index: code/trunk/src/libraries/util/output/ConsoleWriter.cc
===================================================================
--- code/trunk/src/libraries/util/output/ConsoleWriter.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/ConsoleWriter.cc	(revision 8858)
@@ -0,0 +1,107 @@
+/*
+ *   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 Implementation of the ConsoleWriter singleton.
+*/
+
+#include "ConsoleWriter.h"
+
+#include <iostream>
+
+#include "OutputManager.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor, initializes the output level.
+
+        In debug builds, it writes output up to level::internal_warning to the
+        console, in release builds only up to level::user_info.
+
+        After creation, the instance is enabled.
+    */
+    ConsoleWriter::ConsoleWriter() : BaseWriter("Console")
+    {
+#ifdef ORXONOX_RELEASE
+        this->setLevelMax(level::user_info);
+#else
+        this->setLevelMax(level::internal_warning);
+#endif
+        this->bEnabled_ = true;
+    }
+
+    /**
+        @brief Destructor.
+    */
+    ConsoleWriter::~ConsoleWriter()
+    {
+    }
+
+    /**
+        @brief Returns the only existing instance of this class.
+    */
+    /*static*/ ConsoleWriter& ConsoleWriter::getInstance()
+    {
+        static ConsoleWriter instance;
+        return instance;
+    }
+
+    /**
+        @brief Inherited function from BaseWriter, writes output to the console using std::cout.
+    */
+    void ConsoleWriter::printLine(const std::string& line, OutputLevel)
+    {
+        std::cout << line << std::endl;
+    }
+
+    /**
+        @brief Enables the instance by registering itself as listener at OutputManager.
+    */
+    void ConsoleWriter::enable()
+    {
+        if (!this->bEnabled_)
+        {
+            OutputManager::getInstance().registerListener(this);
+            this->bEnabled_ = true;
+        }
+    }
+
+    /**
+        @brief Disables the instance by unregistering itself from OutputManager.
+    */
+    void ConsoleWriter::disable()
+    {
+        if (this->bEnabled_)
+        {
+            OutputManager::getInstance().unregisterListener(this);
+            this->bEnabled_ = false;
+        }
+    }
+}
Index: code/trunk/src/libraries/util/output/ConsoleWriter.h
===================================================================
--- code/trunk/src/libraries/util/output/ConsoleWriter.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/ConsoleWriter.h	(revision 8858)
@@ -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:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the ConsoleWriter singleton which is used to write output to the console.
+*/
+
+#ifndef _ConsoleWriter_H__
+#define _ConsoleWriter_H__
+
+#include "util/UtilPrereqs.h"
+#include "BaseWriter.h"
+
+namespace orxonox
+{
+    /**
+        @brief ConsoleWriter inherits from BaseWriter and writes output to the console.
+
+        This class can be seen as an equivalent to std::cout within the output
+        system. It is implemented as a singleton for static acces.
+    */
+    class _UtilExport ConsoleWriter : public BaseWriter
+    {
+        public:
+            static ConsoleWriter& getInstance();
+
+            void enable();
+            void disable();
+
+        protected:
+            virtual void printLine(const std::string& line, OutputLevel level);
+
+        private:
+            ConsoleWriter();
+            ConsoleWriter(const ConsoleWriter&);
+            virtual ~ConsoleWriter();
+
+            bool bEnabled_; ///< If false, the instance will not write output to the console.
+    };
+}
+
+#endif /* _ConsoleWriter_H__ */
Index: code/trunk/src/libraries/util/output/LogWriter.cc
===================================================================
--- code/trunk/src/libraries/util/output/LogWriter.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/LogWriter.cc	(revision 8858)
@@ -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:
+ *      Reto Grieder
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the LogWriter singleton.
+*/
+
+#include "LogWriter.h"
+
+#include <ctime>
+#include <cstdlib>
+
+#include "OutputManager.h"
+#include "MemoryWriter.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor, initializes the desired output levels and the name and path of the log-file, and opens the log-file.
+
+        By default, LogWriter receives all output up to level::internal_info.
+        The log-file has a default name which usually doesn't change. The path
+        is initialized with a temporary directory, depending on the system,
+        and can be changed later.
+    */
+    LogWriter::LogWriter() : BaseWriter("Log")
+    {
+        this->setLevelMax(level::internal_info);
+
+        this->filename_ = "orxonox.log";
+
+        // get the path for a temporary file, depending on the system
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        this->path_ = getenv("TEMP");
+#else
+        this->path_ = "/tmp";
+#endif
+        this->bDefaultPath_ = true;
+
+        this->openFile();
+    }
+
+    /**
+        @brief Destructor, closes the log-file.
+    */
+    LogWriter::~LogWriter()
+    {
+        this->closeFile();
+    }
+
+    /**
+        @brief Returns the only existing instance of this class.
+    */
+    /*static*/ LogWriter& LogWriter::getInstance()
+    {
+        static LogWriter instance;
+        return instance;
+    }
+
+    /**
+        @brief Opens the log-file in order to write output to it.
+    */
+    void LogWriter::openFile()
+    {
+        // get the full file-name
+        std::string name = this->path_ + '/' + this->filename_;
+
+        // if we open the log file in the default directory, send a message to the user so that he can find the file in the case of a crash.
+        if (this->bDefaultPath_)
+            OutputManager::getInstance().pushMessage(level::user_info, context::undefined(), "Opening log file " + name);
+
+        // open the file
+        this->file_.open(name.c_str(), std::fstream::out);
+
+        // check if it worked and print some output
+        if (this->file_.is_open())
+            this->printLine("Log file opened", level::none);
+        else
+            OutputManager::getInstance().pushMessage(level::user_warning, context::undefined(), "Failed to open log file. File logging disabled.");
+    }
+
+    /**
+        @brief Closes the log-file.
+    */
+    void LogWriter::closeFile()
+    {
+        if (this->file_.is_open())
+        {
+            this->printLine("Log file closed", level::none);
+            this->file_.close();
+        }
+    }
+
+    /**
+        @brief Changes the path of the log-file. Re-writes the log-file by using MemoryWriter.
+    */
+    void LogWriter::setLogPath(const std::string& path)
+    {
+        // notify about the change of the log-file (because the old file will no longer be updated)
+        OutputManager::getInstance().pushMessage(level::internal_info, context::undefined(), "Migrating log file from " + this->path_ + "\nto " + path);
+
+        // close the old file, update the path and open the new file
+        this->closeFile();
+        this->path_ = path;
+        this->bDefaultPath_ = false;
+        this->openFile();
+
+        // request old output from MemoryWriter
+        MemoryWriter::getInstance().resendOutput(this);
+    }
+
+    /**
+        @brief Inherited function from BaseWriter, writers output together with a timestamp to the log-file.
+    */
+    void LogWriter::printLine(const std::string& line, OutputLevel)
+    {
+        if (!this->file_.is_open())
+            return;
+
+        // get the current time
+        time_t rawtime;
+        struct tm* timeinfo;
+        time(&rawtime);
+        timeinfo = localtime(&rawtime);
+
+        // print timestamp and output line to the log file
+        this->file_ << (timeinfo->tm_hour < 10 ? "0" : "") << timeinfo->tm_hour << ':' <<
+                       (timeinfo->tm_min  < 10 ? "0" : "") << timeinfo->tm_min  << ':' <<
+                       (timeinfo->tm_sec  < 10 ? "0" : "") << timeinfo->tm_sec  << ' ' << line << std::endl;
+    }
+}
Index: code/trunk/src/libraries/util/output/LogWriter.h
===================================================================
--- code/trunk/src/libraries/util/output/LogWriter.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/LogWriter.h	(revision 8858)
@@ -0,0 +1,82 @@
+/*
+ *   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
+    @ingroup Output
+    @brief Declaration of the LogWriter singleton which writes output to a log-file.
+*/
+
+#ifndef _LogWriter_H__
+#define _LogWriter_H__
+
+#include "util/UtilPrereqs.h"
+
+#include <fstream>
+
+#include "BaseWriter.h"
+
+namespace orxonox
+{
+    /**
+        @brief The LogWriter class inherits from BaseWriter and writes output to a log-file.
+
+        It is implemented as singleton because we (currently) use only one
+        log-file. The path of the file can be changed, in which case the file
+        is rewritten by using the output stored by MemoryWriter. This adds the
+        possibility to change the desired output levels before changing the
+        path in order to get the complete output with the new output levels
+        at the new path.
+    */
+    class _UtilExport LogWriter : public BaseWriter
+    {
+        public:
+            static LogWriter& getInstance();
+
+            void setLogPath(const std::string& path);
+
+        protected:
+            virtual void printLine(const std::string& line, OutputLevel level);
+
+        private:
+            LogWriter();
+            LogWriter(const LogWriter&);
+            virtual ~LogWriter();
+
+            void openFile();
+            void closeFile();
+
+            std::string filename_;  ///< The name of the log-file (without directories)
+            std::string path_;      ///< The path of the log-file (without file-name)
+            bool bDefaultPath_;     ///< If true, the log-file resides at the default path (which is usually a temporary directory)
+
+            std::ofstream file_;    ///< The output file stream.
+    };
+}
+
+#endif /* _LogWriter_H__ */
Index: code/trunk/src/libraries/util/output/MemoryWriter.cc
===================================================================
--- code/trunk/src/libraries/util/output/MemoryWriter.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/MemoryWriter.cc	(revision 8858)
@@ -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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the MemoryWriter singleton.
+*/
+
+#include "MemoryWriter.h"
+#include "OutputManager.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor, initializes the level mask with all levels activated.
+    */
+    MemoryWriter::MemoryWriter()
+    {
+        this->setLevelMask(level::all);
+    }
+
+    /**
+        @brief Destructor.
+    */
+    MemoryWriter::~MemoryWriter()
+    {
+    }
+
+    /**
+        @brief Returns the only existing instance of this singleton class.
+    */
+    /*static*/ MemoryWriter& MemoryWriter::getInstance()
+    {
+        static MemoryWriter instance;
+        return instance;
+    }
+
+    /**
+        @brief Implementation of the output() function inherited from OutputListener, stores the received output in memory.
+    */
+    void MemoryWriter::output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
+    {
+        this->messages_.push_back(Message(level, context, lines));
+    }
+
+    /**
+        @brief Iterates over all stored output messages and sends them to the OutputListener.
+    */
+    void MemoryWriter::resendOutput(OutputListener* listener) const
+    {
+        for (size_t i = 0; i < this->messages_.size(); ++i)
+        {
+            const Message& message = this->messages_[i];
+            listener->unfilteredOutput(message.level, *message.context, message.lines);
+        }
+    }
+
+    /**
+        @brief Unregisters the instance from OutputManager, hence it will not receive any further output.
+    */
+    void MemoryWriter::disable()
+    {
+        OutputManager::getInstance().unregisterListener(this);
+        this->output(level::debug_output, context::undefined(), std::vector<std::string>(1, "MemoryWriter disabled, further messages may be lost"));
+    }
+}
Index: code/trunk/src/libraries/util/output/MemoryWriter.h
===================================================================
--- code/trunk/src/libraries/util/output/MemoryWriter.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/MemoryWriter.h	(revision 8858)
@@ -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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the MemoryWriter singleton.
+*/
+
+#ifndef _MemoryWriter_H__
+#define _MemoryWriter_H__
+
+#include "util/UtilPrereqs.h"
+#include "OutputListener.h"
+
+namespace orxonox
+{
+    /**
+        @brief MemoryWriter is a singleton which is derived from OutputListener and writes all output to a list.
+
+        This list can be used to re-send old output to other instances of
+        OutputListener, e.g. if they were newly created or to re-write the
+        log-file.
+
+        Since MemoryWriter receives output of all levels, this means also that
+        all possible output needs to be generated as long as MemoryWriter stays
+        active. Hence disable() should be called as soon as possible.
+    */
+    class _UtilExport MemoryWriter : public OutputListener
+    {
+        /// @brief A helper struct which is used to store output and its properties.
+        struct Message
+        {
+            /// @brief Constructor, assigns all values.
+            Message(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
+                : level(level), context(&context), lines(lines) {}
+
+            OutputLevel level;                      ///< The level of the output message
+            const OutputContextContainer* context;  ///< The context of the output message
+            std::vector<std::string> lines;         ///< The lines of text of the output message
+        };
+
+        public:
+            static MemoryWriter& getInstance();
+
+            void resendOutput(OutputListener* listener) const;
+            void disable();
+
+        protected:
+            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines);
+
+        private:
+            MemoryWriter();
+            MemoryWriter(const MemoryWriter&);
+            virtual ~MemoryWriter();
+
+            std::vector<Message> messages_; ///< Stores all output messages from the creation of this instance until disable() is called.
+    };
+}
+
+#endif /* _MemoryWriter_H__ */
Index: code/trunk/src/libraries/util/output/OutputDefinitions.h
===================================================================
--- code/trunk/src/libraries/util/output/OutputDefinitions.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputDefinitions.h	(revision 8858)
@@ -0,0 +1,166 @@
+/*
+ *   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
+    @ingroup Output
+    @brief Defines output levels and output contexts.
+*/
+
+#ifndef _OutputDefinitions_H__
+#define _OutputDefinitions_H__
+
+#include "util/UtilPrereqs.h"
+#include <string>
+
+/**
+    @brief Defines a context function with a given name.
+    @param name Name of the context
+
+    Context functions return a reference to a OutputContextContainer. Context
+    functions (or the containers they return) can be passed to orxout() as
+    context argument.
+*/
+#define REGISTER_OUTPUT_CONTEXT(name) \
+    const OutputContextContainer& name() { static const OutputContextContainer& context = registerContext(#name); return context; }
+
+/**
+    @brief Defines a sub-context.
+    @param name Name of the main-context
+    @param subname Name of the sub-context
+
+    Sub-contexts act like normal contexts, except that multiple sub-contexts
+    share the context mask of their main-context. This allows contexts with
+    more descriptive names (e.g. input::keyboard) and they can be filtered
+    individually by derivatives of orxonox::SubcontextOutputListener.
+*/
+#define REGISTER_OUTPUT_SUBCONTEXT(name, subname) \
+    const OutputContextContainer& subname() { static const OutputContextContainer& context = registerContext(#name, #subname); return context; }
+
+// tolua_begin
+namespace orxonox
+{
+    namespace level
+    {
+        /**
+            @brief Output levels define type and importance of an output message.
+            They can be passed to the orxout() function as level argument.
+        */
+        enum OutputLevel
+        {
+            all              = 0xFFFF, ///< Level mask with all bits set to 1
+            none             = 0x0000, ///< Level mask with all bits set to 0
+
+            message          = 0x0001, ///< Output level, used for messages directed to the user (e.g. "Press any key to continue")
+            debug_output     = 0x0002, ///< Output level, used for temporary debug output while writing code
+            user_error       = 0x0004, ///< Output level, used for error messages which are important for the user
+            user_warning     = 0x0008, ///< Output level, used for warnings which are important for the user
+            user_status      = 0x0010, ///< Output level, used to notify the user about the program's state
+            user_info        = 0x0020, ///< Output level, used to provide the user with additional progress information
+            internal_error   = 0x0040, ///< Output level, used for error messages which are important for developers
+            internal_warning = 0x0080, ///< Output level, used for warnings which are important for developers
+            internal_status  = 0x0100, ///< Output level, used to log the program's internal state in the log file
+            internal_info    = 0x0200, ///< Output level, used to log information about the program's progress in the log file
+            verbose          = 0x0400, ///< Output level, usually not visible, used for unimportant debug information
+            verbose_more     = 0x0800, ///< Output level, usually not visible, used for unimportant debug information (less important than verbose)
+            verbose_ultra    = 0x1000  ///< Output level, usually not visible, used for unimportant debug information (even less important than verbose_more)
+        };
+    }
+// tolua_end
+
+    using namespace level;
+
+    typedef uint64_t OutputContextMask;  ///< Used to store the context masks. Each bit defines a context.
+    typedef uint16_t OutputContextSubID; ///< Used to store the IDs of sub-contexts. Each number except context::no_subcontext defines a sub-context.
+
+    /// @brief Stores all information about a context.
+    struct OutputContextContainer
+    {
+        OutputContextMask mask;     ///< The mask of the context (or the mask of the main-context if this container defines a sub-context)
+        OutputContextSubID sub_id;  ///< The id of the sub-context (or context::no_subcontext if this container doesn't define a sub-context)
+        std::string name;           ///< The name of this context
+    };
+
+    typedef const OutputContextContainer& (OutputContextFunction)();
+
+    /**
+        @brief Registers a context.
+        This is a shortcut to OutputManager::registerContext() to avoid the inclusion of its header file.
+    */
+    extern _UtilExport const OutputContextContainer& registerContext(const std::string& name, const std::string& subname = "");
+
+    namespace context
+    {
+        static const OutputContextMask all       = 0xFFFFFFFFFFFFFFFF; ///< Context mask, all bits set to 1
+        static const OutputContextMask none      = 0x0000000000000000; ///< Context mask, all bits set to 0
+
+        static const OutputContextSubID no_subcontext = 0; ///< Used as ID for contexts which are not sub-contexts
+
+        namespace
+        {
+            REGISTER_OUTPUT_CONTEXT(undefined); ///< "undefined" context which is implicitly used for all output that has no explicit context
+
+            REGISTER_OUTPUT_CONTEXT(ogre);
+            REGISTER_OUTPUT_CONTEXT(cegui);
+            REGISTER_OUTPUT_CONTEXT(lua);
+            REGISTER_OUTPUT_CONTEXT(tcl);
+            REGISTER_OUTPUT_CONTEXT(identifier);
+            REGISTER_OUTPUT_CONTEXT(object_list);
+            REGISTER_OUTPUT_CONTEXT(super);
+            REGISTER_OUTPUT_CONTEXT(language);
+            REGISTER_OUTPUT_CONTEXT(commands);
+            REGISTER_OUTPUT_CONTEXT(input);
+            REGISTER_OUTPUT_CONTEXT(events);
+            REGISTER_OUTPUT_CONTEXT(config);
+            REGISTER_OUTPUT_CONTEXT(templates);
+            REGISTER_OUTPUT_CONTEXT(loader);
+            REGISTER_OUTPUT_CONTEXT(xml);
+            REGISTER_OUTPUT_CONTEXT(network);
+            REGISTER_OUTPUT_CONTEXT(packets);
+            REGISTER_OUTPUT_CONTEXT(master_server);
+            REGISTER_OUTPUT_CONTEXT(sound);
+            REGISTER_OUTPUT_CONTEXT(lod);
+            REGISTER_OUTPUT_CONTEXT(pickups);
+            REGISTER_OUTPUT_CONTEXT(quests);
+            REGISTER_OUTPUT_CONTEXT(notifications);
+            REGISTER_OUTPUT_CONTEXT(triggers);
+            REGISTER_OUTPUT_CONTEXT(docking);
+
+            namespace misc
+            {
+                REGISTER_OUTPUT_SUBCONTEXT(misc, executor);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, factory);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, gui);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, overlays);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, script);
+            }
+        }
+    }
+} // tolua_export
+
+#endif /* _OutputDefinitions_H__ */
Index: code/trunk/src/libraries/util/output/OutputListener.cc
===================================================================
--- code/trunk/src/libraries/util/output/OutputListener.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputListener.cc	(revision 8858)
@@ -0,0 +1,149 @@
+/*
+ *   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 OutputListener class.
+*/
+
+#include "OutputListener.h"
+
+#include "OutputManager.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor, initializes the values and registers the instance at OutputManager if requested.
+        @param bRegister If \c true, the instance is automatically registered at OutputManager.
+                         Should be \c false if the constructor of the derived class generates output.
+    */
+    OutputListener::OutputListener(bool bRegister)
+    {
+        this->levelMask_ = level::none;
+        this->additionalContextsLevelMask_ = level::none;
+        this->additionalContextsMask_ = context::none;
+
+        if (bRegister)
+            OutputManager::getInstance().registerListener(this);
+    }
+
+    /**
+        @brief Destructor, unregisters the instance from OutputManager.
+    */
+    OutputListener::~OutputListener()
+    {
+        OutputManager::getInstance().unregisterListener(this);
+    }
+
+    /**
+        @brief Defines the level mask in a way which accepts all output up to the level \c max.
+    */
+    void OutputListener::setLevelMax(OutputLevel max)
+    {
+        this->setLevelRange(static_cast<OutputLevel>(0x1), max);
+    }
+
+    /**
+        @brief Defines the level mask in a way which accepts all output between the levels \c min and \c max.
+    */
+    void OutputListener::setLevelRange(OutputLevel min, OutputLevel max)
+    {
+        int mask = 0;
+        for (int level = min; level <= max; level = level << 1)
+            mask |= level;
+
+        this->setLevelMask(static_cast<OutputLevel>(mask));
+    }
+
+    /**
+        @brief Defines the level mask.
+    */
+    void OutputListener::setLevelMask(OutputLevel mask)
+    {
+        this->levelMask_ = mask;
+
+        OutputManager::getInstance().updateCombinedLevelMask();
+    }
+
+    /**
+        @brief Defines the level mask of additional contexts in a way which accepts all output up to the level \c max.
+    */
+    void OutputListener::setAdditionalContextsLevelMax(OutputLevel max)
+    {
+        this->setAdditionalContextsLevelRange(static_cast<OutputLevel>(0x1), max);
+    }
+
+    /**
+        @brief Defines the level mask of additional contexts in a way which accepts all output between the levels \c min and \c max.
+    */
+    void OutputListener::setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max)
+    {
+        int mask = 0;
+        for (int level = min; level <= max; level = level << 1)
+            mask |= level;
+
+        this->setAdditionalContextsLevelMask(static_cast<OutputLevel>(mask));
+    }
+
+    /**
+        @brief Defines the level mask of additional contexts.
+    */
+    void OutputListener::setAdditionalContextsLevelMask(OutputLevel mask)
+    {
+        this->additionalContextsLevelMask_ = mask;
+
+        OutputManager::getInstance().updateCombinedAdditionalContextsLevelMask();
+    }
+
+    /**
+        @brief Defines the mask of additional contexts.
+    */
+    void OutputListener::setAdditionalContextsMask(OutputContextMask mask)
+    {
+        this->additionalContextsMask_ = mask;
+
+        OutputManager::getInstance().updateCombinedAdditionalContextsMask();
+    }
+
+    /**
+        @brief Returns true if this listener accepts output of the given level and context, based on the levels and contexts masks.
+    */
+    bool OutputListener::acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
+    {
+        // check if the output level is accepted by the level mask (independent of the context)
+        if (this->levelMask_ & level)
+            return true;
+
+        // check if the output context is accepted by the additional context mask and if the level matches as well
+        if ((this->additionalContextsMask_ & context.mask) && (this->additionalContextsLevelMask_ & level))
+            return true;
+
+        // otherwise we don't accept the output
+        return false;
+    }
+}
Index: code/trunk/src/libraries/util/output/OutputListener.h
===================================================================
--- code/trunk/src/libraries/util/output/OutputListener.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputListener.h	(revision 8858)
@@ -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:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the OutputListener interface which receives output
+    from orxonox::OutputManager.
+*/
+
+#ifndef _OutputListener_H__
+#define _OutputListener_H__
+
+#include "util/UtilPrereqs.h"
+
+#include <vector>
+
+#include "OutputDefinitions.h"
+
+namespace orxonox
+{
+    /**
+        @brief OutputListener is an interface which is used to receive output of a certain level and context from OutputManager.
+    */
+    //  See below the class declaration for a more detailed description.
+    class _UtilExport OutputListener
+    {
+        public:
+            OutputListener(bool bRegister = true);
+            virtual ~OutputListener();
+
+            void setLevelMax(OutputLevel max);
+            void setLevelRange(OutputLevel min, OutputLevel max);
+            void setLevelMask(OutputLevel mask);
+
+            void setAdditionalContextsLevelMax(OutputLevel max);
+            void setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max);
+            void setAdditionalContextsLevelMask(OutputLevel mask);
+
+            void setAdditionalContextsMask(OutputContextMask mask);
+
+            /// @brief Returns the level mask.
+            inline OutputLevel getLevelMask() const
+                { return this->levelMask_; }
+            /// @brief Returns the additional contexts mask.
+            inline OutputContextMask getAdditionalContextsMask() const
+                { return this->additionalContextsMask_; }
+            /// @brief Returns the additional contexts level mask.
+            inline OutputLevel getAdditionalContextsLevelMask() const
+                { return this->additionalContextsLevelMask_; }
+
+            virtual bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const;
+
+            /// @brief Called by OutputManager for each line of output, checks if this listener actually accepts this output before it calls the output() function.
+            inline void unfilteredOutput(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
+                { if (this->acceptsOutput(level, context)) this->output(level, context, lines); }
+
+        protected:
+            /// @brief Pure virtual function, needs to be implemented in order to receive output.
+            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines) = 0;
+
+        private:
+            OutputLevel       levelMask_;                   ///< Mask of accepted output levels, independent of contexts
+            OutputContextMask additionalContextsMask_;      ///< Mask of accepted additional contexts
+            OutputLevel       additionalContextsLevelMask_; ///< Mask of accepted output levels of the additional contexts
+    };
+
+    /**
+        @class OutputListener
+
+        An instance of OutputListener registers itself at OutputManager and
+        declares the desired output levels and contexts. OutputManager will
+        then send output to it by calling the output() function.
+
+        OutputListener has 3 masks to define the desired output. These masks
+        can be used in two different ways (or as a combination of both):
+        \li 1. By defining the \a "level mask": The OutputListener will then
+               receive all output of these levels independent of the context.
+        \li 2. By defining the \a "additional contexts mask" and the
+               \a "additional contexts level mask": This way the listener
+               receives only output of a particular context and level.
+        \li 3. By using all 3 masks which combines the output defined by the
+               first two ways.
+
+        This can be illustrated as follows:
+
+        1. Only level mask:
+        \li level-mask = error | warning;
+
+        @verbatim
+                |   Contexts:   |
+                | A | B | C | D |
+        --------|---|---|---|---|
+        debug   | - | - | - | - |
+        --------|---|---|---|---|
+        error   | x | x | x | x |
+        --------|---|---|---|---|       [x] Receives output
+        warning | x | x | x | x |       [-] Does not receive output
+        --------|---|---|---|---|
+        status  | - | - | - | - |
+        --------|---|---|---|---|
+        verbose | - | - | - | - |
+        --------|---|---|---|---|
+        @endverbatim
+
+        2. Only additional contexts:
+        \li additional-contexts-mask = B | D;
+        \li additional-contexts-level-mask = debug | verbose;
+
+        @verbatim
+                |   Contexts:   |
+                | A | B | C | D |
+        --------|---|---|---|---|
+        debug   | - | x | - | x |
+        --------|---|---|---|---|
+        error   | - | - | - | - |
+        --------|---|---|---|---|       [x] Receives output
+        warning | - | - | - | - |       [-] Does not receive output
+        --------|---|---|---|---|
+        status  | - | - | - | - |
+        --------|---|---|---|---|
+        verbose | - | x | - | x |
+        --------|---|---|---|---|
+        @endverbatim
+
+        3. Both level mask plus additional contexts:
+        \li level-mask = error | warning;
+        \li additional-contexts-mask = B | D;
+        \li additional-contexts-level-mask = debug | verbose;
+
+        @verbatim
+                |   Contexts:   |
+                | A | B | C | D |
+        --------|---|---|---|---|
+        debug   | - | x | - | x |
+        --------|---|---|---|---|
+        error   | x | x | x | x |
+        --------|---|---|---|---|       [x] Receives output
+        warning | x | x | x | x |       [-] Does not receive output
+        --------|---|---|---|---|
+        status  | - | - | - | - |
+        --------|---|---|---|---|
+        verbose | - | x | - | x |
+        --------|---|---|---|---|
+        @endverbatim
+    */
+}
+
+#endif /* _OutputListener_H__ */
Index: code/trunk/src/libraries/util/output/OutputManager.cc
===================================================================
--- code/trunk/src/libraries/util/output/OutputManager.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputManager.cc	(revision 8858)
@@ -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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the OutputManager singleton.
+*/
+
+#include "OutputManager.h"
+
+#include "MemoryWriter.h"
+#include "ConsoleWriter.h"
+#include "LogWriter.h"
+#include "util/Output.h"
+#include "util/StringUtils.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor, initializes all values.
+    */
+    OutputManager::OutputManager()
+    {
+        this->combinedLevelMask_ = level::none;
+        this->combinedAdditionalContextsLevelMask_ = level::none;
+        this->combinedAdditionalContextsMask_ = context::none;
+
+        this->subcontextCounter_ = 0;
+    }
+
+    /**
+        @brief Destructor.
+    */
+    OutputManager::~OutputManager()
+    {
+    }
+
+    /**
+        @brief Returns the only existing instance of the OutputManager singleton.
+    */
+    /*static*/ OutputManager& OutputManager::getInstance()
+    {
+        static OutputManager instance;
+        return instance;
+    }
+
+    /**
+        @brief Returns the only existing instance of the OutputManager singleton
+        and ensures that the most important output listeners exist.
+
+        You should use this function if you send output to OutputManager and want
+        to be sure that the most important output listeners exist. Don't use it
+        elsewhere inside the output system to avoid circular calls.
+    */
+    /*static*/ OutputManager& OutputManager::getInstanceAndCreateListeners()
+    {
+        static OutputManager& instance = OutputManager::getInstance();
+
+        static MemoryWriter& memoryWriterInstance = MemoryWriter::getInstance(); (void)memoryWriterInstance;
+        static ConsoleWriter& consoleWriterInstance = ConsoleWriter::getInstance(); (void)consoleWriterInstance;
+        static LogWriter& logWriterInstance = LogWriter::getInstance(); (void)logWriterInstance;
+
+        return instance;
+    }
+
+    /**
+        @brief Sends an output message to all output listeners.
+        @param level The level of the message
+        @param context The context of the message
+        @param message The output message (may contain '\\n')
+
+        This function splits the message into lines (if it contains '\\n') and
+        sends it to the output listeners. They may ignore the message if it
+        doesn't match their level- and context-masks.
+    */
+    void OutputManager::pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message)
+    {
+        std::vector<std::string> lines;
+        vectorize(message, '\n', &lines);
+
+        for (size_t i = 0; i < this->listeners_.size(); ++i)
+            this->listeners_[i]->unfilteredOutput(level, context, lines);
+    }
+
+    /**
+        @brief Adds an output listener to the list of listeners.
+    */
+    void OutputManager::registerListener(OutputListener* listener)
+    {
+        this->listeners_.push_back(listener);
+        this->updateMasks();
+    }
+
+    /**
+        @brief Removes an output listener from the list of listeners.
+    */
+    void OutputManager::unregisterListener(OutputListener* listener)
+    {
+        for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if (*it == listener)
+            {
+                this->listeners_.erase(it);
+                break;
+            }
+        }
+        this->updateMasks();
+    }
+
+    /**
+        @brief Updates all three combined level- and context-masks.
+    */
+    void OutputManager::updateMasks()
+    {
+        this->updateCombinedLevelMask();
+        this->updateCombinedAdditionalContextsLevelMask();
+        this->updateCombinedAdditionalContextsMask();
+    }
+
+    /**
+        @brief Updates the combined level mask. The masks of all listeners are ORed to form the combined mask.
+    */
+    void OutputManager::updateCombinedLevelMask()
+    {
+        int mask = 0;
+        for (size_t i = 0; i < this->listeners_.size(); ++i)
+            mask |= this->listeners_[i]->getLevelMask();
+        this->combinedLevelMask_ = static_cast<OutputLevel>(mask);
+    }
+
+    /**
+        @brief Updates the combined additional contexts level mask. The masks of all listeners are ORed to form the combined mask.
+    */
+    void OutputManager::updateCombinedAdditionalContextsLevelMask()
+    {
+        int mask = 0;
+        for (size_t i = 0; i < this->listeners_.size(); ++i)
+            mask |= this->listeners_[i]->getAdditionalContextsLevelMask();
+        this->combinedAdditionalContextsLevelMask_ = static_cast<OutputLevel>(mask);
+    }
+
+    /**
+        @brief Updates the combined additional contexts mask. The masks of all listeners are ORed to form the combined mask.
+    */
+    void OutputManager::updateCombinedAdditionalContextsMask()
+    {
+        this->combinedAdditionalContextsMask_ = 0;
+        for (size_t i = 0; i < this->listeners_.size(); ++i)
+            this->combinedAdditionalContextsMask_ |= this->listeners_[i]->getAdditionalContextsMask();
+    }
+
+    /**
+        @brief Registers a context (or sub-context) and returns the container which identifies the context.
+        @param name The name of the context
+        @param subname The name of the sub-context (or "" if it is not a sub-context)
+
+        If the context doesn't exist, it gets created. Otherwise the existing instance is returned.
+    */
+    const OutputContextContainer& OutputManager::registerContext(const std::string& name, const std::string& subname)
+    {
+        // the full name of a context is a combination of name and subname with "::" in between
+        std::string full_name = name;
+        if (subname != "")
+            full_name += "::" + subname;
+
+        // check if the context already exists (and return it if it does)
+        std::map<std::string, OutputContextContainer>::iterator it_container = this->contextContainers_.find(full_name);
+        if (it_container != this->contextContainers_.end())
+            return it_container->second;
+
+        // create a new context container
+        OutputContextContainer container;
+        container.name = full_name;
+
+        // check if the mask of the main-context already exists
+        std::map<std::string, OutputContextMask>::iterator it_mask = this->contextMasks_.find(name);
+        if (it_mask != this->contextMasks_.end())
+        {
+            // the mask exists, assign it to the container
+            container.mask = it_mask->second;
+        }
+        else
+        {
+            // the mask doesn't exist, create it. It's a binary mask. The n-th main-context is defined by the n-th bit in the mask.
+            container.mask = static_cast<OutputContextMask>(0x1) << this->contextMasks_.size();
+            this->contextMasks_[name] = container.mask;
+
+            if (container.mask == 0)
+                orxout(internal_warning) << "More than " << sizeof(OutputContextMask) * 8 << " output contexts defined. Context '" << name << "' might not get filtered correctly" << endl;
+        }
+
+        // if the context is a sub-context, assign a unique ID.
+        if (subname == "")
+            container.sub_id = context::no_subcontext;
+        else
+            container.sub_id = ++this->subcontextCounter_; // start with 1
+
+        // add the new context to the map and return it
+        return (this->contextContainers_[full_name] = container);
+    }
+
+    /**
+        @brief Static function, shortcut to OutputManager::registerContext().
+        The function is declared in OutputDefinitions.h.
+    */
+    const OutputContextContainer& registerContext(const std::string& name, const std::string& subname)
+    {
+        return OutputManager::getInstance().registerContext(name, subname);
+    }
+
+    /**
+        @brief Returns a human readable string for each output level.
+    */
+    const std::string& OutputManager::getLevelName(OutputLevel level) const
+    {
+        switch (level)
+        {
+            // using static cache variables for speed
+            case level::none:               { static std::string name = "None"; return name; }
+            case level::message:            { static std::string name = "Message"; return name; }
+            case level::debug_output:       { static std::string name = "Debug"; return name; }
+            case level::user_error:         { static std::string name = "Error"; return name; }
+            case level::user_warning:       { static std::string name = "Warning"; return name; }
+            case level::user_status:        { static std::string name = "Status"; return name; }
+            case level::user_info:          { static std::string name = "Info"; return name; }
+            case level::internal_error:     { static std::string name = "Error (internal)"; return name; }
+            case level::internal_warning:   { static std::string name = "Warning (internal)"; return name; }
+            case level::internal_status:    { static std::string name = "Status (internal)"; return name; }
+            case level::internal_info:      { static std::string name = "Info (internal)"; return name; }
+            case level::verbose:            { static std::string name = "Verbose"; return name; }
+            case level::verbose_more:       { static std::string name = "Verbose (more)"; return name; }
+            case level::verbose_ultra:      { static std::string name = "Verbose (ultra)"; return name; }
+            default:                        { static std::string name = ""; return name; }
+        }
+    }
+
+    /**
+        @brief Returns a string containing the name of the level and the context (if any) which
+        can be prepended to an output message if it is written to the console or the log file.
+    */
+    std::string OutputManager::getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const
+    {
+        // "undefined" context is ignored because it's used implicitly if no explicit context is defined
+        static OutputContextMask undefined_mask = context::undefined().mask;
+
+        std::string prefix = this->getLevelName(level) + ": ";
+        if (context.mask != undefined_mask)
+            prefix += "[" + context.name + "] ";
+
+        return prefix;
+    }
+}
Index: code/trunk/src/libraries/util/output/OutputManager.h
===================================================================
--- code/trunk/src/libraries/util/output/OutputManager.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputManager.h	(revision 8858)
@@ -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:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the OutputManager class which receives output from orxonox::OutputStream
+    and distributes it to all instances of orxonox::OutputListener.
+*/
+
+#ifndef _OutputManager_H__
+#define _OutputManager_H__
+
+#include "util/UtilPrereqs.h"
+
+#include <vector>
+#include <map>
+
+#include "OutputDefinitions.h"
+
+namespace orxonox
+{
+    /**
+        @brief OutputManager acts as the center of the output system and is implemented as a singleton.
+
+        All instances of OutputStream (and hence also the orxout() function)
+        send their buffered output to OutputManager. OutputManager then
+        distributes this output to all registered instances of OutputListener.
+
+        For each listener OutputManager checks if it wants to receive output
+        with the given level and context. OutputManager itself also maintains
+        masks that define the accepted levels and concept. They are a
+        combination of the masks of all output listeners. See the description
+        of OutputListener for a more conclusive description of these masks.
+
+        Additionally OutputManager is used to register output contexts.
+    */
+    class _UtilExport OutputManager
+    {
+        public:
+            static OutputManager& getInstance();
+            static OutputManager& getInstanceAndCreateListeners();
+
+            void pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message);
+
+            void registerListener(OutputListener* listener);
+            void unregisterListener(OutputListener* listener);
+
+            void updateMasks();
+            void updateCombinedLevelMask();
+            void updateCombinedAdditionalContextsLevelMask();
+            void updateCombinedAdditionalContextsMask();
+
+            /**
+                @brief Returns true if at least one of the output listeners will accept output with the given level and context.
+
+                For the sake of performance, output messages with levels or
+                contexts that are not accepted should be ignored or, even
+                better, not generated at all.
+            */
+            inline bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
+            {
+                return (this->combinedLevelMask_ & level) ||
+                       ((this->combinedAdditionalContextsLevelMask_ & level) && (this->combinedAdditionalContextsMask_ & context.mask));
+            }
+
+            const OutputContextContainer& registerContext(const std::string& name, const std::string& subname = "");
+
+            const std::string& getLevelName(OutputLevel level) const;
+            std::string getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const;
+
+        private:
+            OutputManager();
+            OutputManager(const OutputManager&);
+            ~OutputManager();
+
+            std::vector<OutputListener*> listeners_;                            ///< List of all registered output listeners
+
+            OutputLevel       combinedLevelMask_;                               ///< The combined mask of accepted levels of all listeners
+            OutputLevel       combinedAdditionalContextsLevelMask_;             ///< The combined mask of accepted additional contexts levels of all listeners
+            OutputContextMask combinedAdditionalContextsMask_;                  ///< The combined mask of accepted additional contexts of all listeners
+
+            std::map<std::string, OutputContextMask> contextMasks_;             ///< Contains all main-contexts and their masks
+            std::map<std::string, OutputContextContainer> contextContainers_;   ///< Contains all contexts including sub-contexts and their containers
+            OutputContextSubID subcontextCounter_;                              ///< Counts the number of sub-contexts (and generates their IDs)
+    };
+}
+
+#endif /* _OutputManager_H__ */
Index: code/trunk/src/libraries/util/output/OutputStream.cc
===================================================================
--- code/trunk/src/libraries/util/output/OutputStream.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputStream.cc	(revision 8858)
@@ -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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the non-generic functions of the OutputStream class.
+*/
+
+#include "OutputStream.h"
+
+#include "OutputManager.h"
+
+namespace orxonox
+{
+    /**
+        @brief Default constructor, initializes level and context with default values.
+    */
+    OutputStream::OutputStream()
+    {
+        this->setOutputAttributes(level::debug_output, context::undefined());
+    }
+
+    /**
+        @brief Constructor, initializes level and context with the provided values.
+    */
+    OutputStream::OutputStream(OutputLevel level, const OutputContextContainer& context)
+    {
+        this->setOutputAttributes(level, context);
+    }
+
+    /**
+        @brief Destructor, sends remaining output to OutputManager (if any).
+    */
+    OutputStream::~OutputStream()
+    {
+        if (this->str() != "")
+            *this << " [missing endl]" << std::endl;
+    }
+
+    /**
+        @brief Sends the buffered message to OutputManager together with the stored level and context.
+        Additionally empties the buffer.
+    */
+    void OutputStream::sendMessage()
+    {
+        OutputManager::getInstanceAndCreateListeners().pushMessage(this->level_, *this->context_, this->str());
+        this->str("");
+    }
+
+    /**
+        @brief Defines level and context of the following output.
+        Also sets the bAcceptsOutput_ flag according to the masks defined in OutputManager.
+    */
+    void OutputStream::setOutputAttributes(OutputLevel level, const OutputContextContainer& context)
+    {
+        this->level_ = level;
+        this->context_ = &context;
+
+        this->bAcceptsOutput_ = OutputManager::getInstanceAndCreateListeners().acceptsOutput(level, context);
+    }
+}
Index: code/trunk/src/libraries/util/output/OutputStream.h
===================================================================
--- code/trunk/src/libraries/util/output/OutputStream.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/OutputStream.h	(revision 8858)
@@ -0,0 +1,122 @@
+/*
+ *   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
+    @ingroup Output
+    @brief Declaration of the OutputStream class which is used to send output to orxonox::OutputManager.
+*/
+
+#ifndef _OutputStream_H__
+#define _OutputStream_H__
+
+#include "util/UtilPrereqs.h"
+
+#include <sstream>
+
+#include "OutputDefinitions.h"
+
+namespace orxonox
+{
+    /**
+        @brief This class is used to buffer output and send it to OutputManager whenever std::endl is passed to it.
+
+        OutputStream inherits from std::ostringstream and acts like std::cout.
+        This means you can use the << operator to write output to the stream.
+        This class is used by the orxout() function.
+
+        @attention
+        You must end an output message with std::endl, otherwise the message
+        won't be flushed. '\\n' only adds a new line to the message.
+
+        The following code samples are all equivalent:
+        @code
+        OutputStream stream;
+        stream.setOutputAttributes(user_info, context::example());
+        stream << "Hello World" << endl;
+        @endcode
+
+        @code
+        OutputStream stream(user_info, context::example());
+        stream << "Hello World" << endl;
+        @endcode
+
+        @code
+        orxout(user_info, context::example) << "Hello World" << endl;
+        @endcode
+    */
+    class OutputStream : public std::ostringstream
+    {
+        typedef std::ostream& (*EndlType)(std::ostream&);
+
+        public:
+            _UtilExport OutputStream();
+            _UtilExport OutputStream(OutputLevel level, const OutputContextContainer& context);
+            _UtilExport ~OutputStream();
+
+            void _UtilExport setOutputAttributes(OutputLevel level, const OutputContextContainer& context);
+
+            /// @brief Generic << operator which adds output to the stream.
+            template <class T>
+            inline OutputStream& operator<<(const T& val) { return this->output(val); }
+            /// @brief Sends a manipulator to the output stream.
+            inline OutputStream& operator<<(std::ios_base& (*manipulator)(std::ios_base&)) { return this->output(manipulator); }
+            /// @brief Sends a manipulator to the output stream.
+            inline OutputStream& operator<<(std::ios&      (*manipulator)(std::ios&))      { return this->output(manipulator); }
+            /// @brief Sends a manipulator to the output stream and flushes the message if the manipulator is std::endl.
+            inline OutputStream& operator<<(std::ostream&  (*manipulator)(std::ostream&))
+            {
+                if (this->bAcceptsOutput_)
+                {
+                    if (manipulator == static_cast<EndlType>(std::endl))
+                        this->sendMessage(); // send the message to OutputManager
+                    else
+                        return this->output(manipulator); // apply the manipulator
+                }
+                return *this;
+            }
+
+        private:
+            /// @brief Generic function to add values to the output stream, using the inherited << operator from std::ostringstream.
+            template <class T>
+            inline OutputStream& output(const T& val)
+            {
+                if (this->bAcceptsOutput_)
+                    static_cast<std::ostringstream&>(*this) << val;
+                return *this;
+            }
+
+            void _UtilExport sendMessage();
+
+            OutputLevel level_;                     ///< The output level of the current message
+            const OutputContextContainer* context_; ///< The output context of the current message
+            bool bAcceptsOutput_;                   ///< After defining level and context of the following message, this flag is set according to the masks defined in OutputManager. If it is false, the OutputStream will throw away every output sent using the << operator.
+    };
+}
+
+#endif /* _OutputStream_H__ */
Index: code/trunk/src/libraries/util/output/SubcontextOutputListener.cc
===================================================================
--- code/trunk/src/libraries/util/output/SubcontextOutputListener.cc	(revision 8858)
+++ code/trunk/src/libraries/util/output/SubcontextOutputListener.cc	(revision 8858)
@@ -0,0 +1,118 @@
+/*
+ *   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 SubcontextOutputListener interface.
+*/
+
+#include "SubcontextOutputListener.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor, initializes the context masks.
+    */
+    SubcontextOutputListener::SubcontextOutputListener(bool bRegister) : OutputListener(bRegister)
+    {
+        this->subcontextsCheckMask_ = context::none;
+        this->subcontextsNoCheckMask_ = context::none;
+    }
+
+    /**
+        @brief Destructor.
+    */
+    SubcontextOutputListener::~SubcontextOutputListener()
+    {
+    }
+
+    /**
+        @brief Overwritten implementation of the function defined by OutputListener.
+
+        Contexts defined with this function are accepted independent of the
+        sub-context. The "final" mask of additional contexts is defined by the
+        combination of this mask and the masks of all accepted sub-contexts.
+    */
+    void SubcontextOutputListener::setAdditionalContextsMask(OutputContextMask mask)
+    {
+        this->subcontextsNoCheckMask_ = mask;
+
+        OutputListener::setAdditionalContextsMask(this->subcontextsCheckMask_ | this->subcontextsNoCheckMask_);
+    }
+
+    /**
+        @brief Defines the set of accepted sub-contexts.
+
+        The masks of sub-contexts in this set are added to the mask of
+        additional contexts, but output is only accepted if the exact
+        sub-context exists in this set.
+    */
+    void SubcontextOutputListener::setAdditionalSubcontexts(const std::set<const OutputContextContainer*>& subcontexts)
+    {
+        this->subcontextsCheckMask_ = context::none;
+        this->subcontexts_.clear();
+
+        // compose the mask of subcontexts and build the set of sub-context-IDs
+        for (std::set<const OutputContextContainer*>::const_iterator it = subcontexts.begin(); it != subcontexts.end(); ++it)
+        {
+            this->subcontextsCheckMask_ |= (*it)->mask;
+            this->subcontexts_.insert((*it)->sub_id);
+        }
+
+        OutputListener::setAdditionalContextsMask(this->subcontextsCheckMask_ | this->subcontextsNoCheckMask_);
+    }
+
+    /**
+        @brief Returns true if this listener accepts output of the given level and context, based on the levels and contexts masks, as well as the set of accepted sub-contexts.
+    */
+    bool SubcontextOutputListener::acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
+    {
+        // check if the output level is accepted by the level mask (independent of the context)
+        if (this->getLevelMask() & level)
+            return true;
+
+        // check if the output level is accepted by the additional contexts level mask
+        if (this->getAdditionalContextsLevelMask() & level)
+        {
+            // check if the output context is accepted by the "no check" mask
+            if (this->subcontextsNoCheckMask_ & context.mask)
+                return true;
+
+            // check if the output context is accepted by the "check" mask
+            if (this->subcontextsCheckMask_ & context.mask)
+            {
+                // check if the output's subcontext is in the set of accepted sub-context
+                if (this->subcontexts_.find(context.sub_id) != this->subcontexts_.end())
+                    return true;
+            }
+        }
+
+        // otherwise we don't accept the output
+        return false;
+    }
+}
Index: code/trunk/src/libraries/util/output/SubcontextOutputListener.h
===================================================================
--- code/trunk/src/libraries/util/output/SubcontextOutputListener.h	(revision 8858)
+++ code/trunk/src/libraries/util/output/SubcontextOutputListener.h	(revision 8858)
@@ -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
+    @ingroup Output
+    @brief Declaration of the SubcontextOutputListener interface which adds the ability to filter sub-contexts to OutputListener.
+*/
+
+#ifndef _SubcontextOutputListener_H__
+#define _SubcontextOutputListener_H__
+
+#include "util/UtilPrereqs.h"
+
+#include <set>
+
+#include "OutputListener.h"
+
+namespace orxonox
+{
+    /**
+        @brief This class extends the basic OutputListener interface and adds the ability to filter sub-contexts.
+
+        Defining additional contexts with setAdditionalContextsMask() enables
+        all sub-contexts of these additional contexts. To accept only some
+        particular sub-contexts, setAdditionalSubcontexts() has to be used.
+        Note that this requires a set, since a mask is not possible with
+        sub-contexts.
+
+        The "final" context mask which will be seen by OutputManager is the
+        combination of all regular contexts plus the masks of all sub-contexts.
+
+        @remark
+        It would have been possible to implement filtering of sub-contexts
+        directly in OutputListener and even to make OutputManager aware of
+        sub-contexts. This would reduce the amount of unnecessarily generated
+        output, but also increase the complexity of the checks whether some
+        output is needed.
+        On the other hand, filtering of sub-contexts makes the whole concept
+        more complicated, as it adds another mask and a set. So to keep it
+        clean and simple I figured it's best to put sub-context filtering into
+        a seaparate class.
+    */
+    class _UtilExport SubcontextOutputListener : public OutputListener
+    {
+        public:
+            SubcontextOutputListener(bool bRegister = true);
+            virtual ~SubcontextOutputListener();
+
+            void setAdditionalContextsMask(OutputContextMask mask);
+            void setAdditionalSubcontexts(const std::set<const OutputContextContainer*>& subcontexts);
+
+            virtual bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const;
+
+        private:
+            OutputContextMask subcontextsCheckMask_;    ///< All contexts defined by this mask need to be checked whether they are accepted by the set of sub-contexts
+            OutputContextMask subcontextsNoCheckMask_;  ///< All contexts defined by this mask don't need to be checked since we accept all sub-contexts
+            std::set<OutputContextSubID> subcontexts_;  ///< The set of accepted sub-contexts
+    };
+}
+
+#endif /* _SubcontextOutputListener_H__ */
