Index: code/branches/output/src/libraries/util/CMakeLists.txt
===================================================================
--- code/branches/output/src/libraries/util/CMakeLists.txt	(revision 8772)
+++ code/branches/output/src/libraries/util/CMakeLists.txt	(revision 8774)
@@ -43,4 +43,6 @@
   output/OutputManager.cc
   output/OutputListener.cc
+  output/LogWriter.cc
+  output/MemoryWriter.cc
 )
 
Index: code/branches/output/src/libraries/util/output/LogWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/LogWriter.cc	(revision 8774)
+++ code/branches/output/src/libraries/util/output/LogWriter.cc	(revision 8774)
@@ -0,0 +1,130 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "LogWriter.h"
+
+#include <ctime>
+
+#include "OutputManager.h"
+#include "MemoryWriter.h"
+
+namespace orxonox
+{
+namespace test
+{
+    LogWriter::LogWriter()
+    {
+        this->setLevelMax(level::internal_info);
+
+        this->filename_ = "orxonox2.log";
+
+        // Get path for a temporary file
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        this->path_ = getenv("TEMP");
+#else
+        this->path_ = "/tmp";
+#endif
+        this->bDefaultPath_ = true;
+
+        this->openFile();
+    }
+
+    LogWriter::~LogWriter()
+    {
+        this->closeFile();
+    }
+
+    /*static*/ LogWriter& LogWriter::getInstance()
+    {
+        static LogWriter instance;
+        return instance;
+    }
+
+    void LogWriter::output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+    {
+        if (!this->file_.is_open())
+            return;
+
+        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]);
+    }
+
+    void LogWriter::openFile()
+    {
+        std::string name = this->path_ + '/' + this->filename_;
+
+        if (this->bDefaultPath_)
+            OutputManager::getInstanceInternal().pushMessage(level::user_info, context::output, "Opening log file " + name);
+
+        this->file_.open(name.c_str(), std::fstream::out);
+
+        if (this->file_.is_open())
+            this->printLine("Log file opened");
+        else
+            OutputManager::getInstance().pushMessage(level::user_warning, context::output, "Failed to open log file. File logging disabled.");
+    }
+
+    void LogWriter::closeFile()
+    {
+        if (this->file_.is_open())
+        {
+            this->printLine("Log file closed");
+            this->file_.close();
+        }
+    }
+
+    void LogWriter::setLogPath(const std::string& path)
+    {
+        OutputManager::getInstance().pushMessage(level::internal_info, context::output, "Migrating log file from " + this->path_ + "\nto " + path);
+
+        this->closeFile();
+        this->path_ = path;
+        this->bDefaultPath_ = false;
+        this->openFile();
+
+        MemoryWriter::getInstance().resendOutput(this);
+    }
+
+    void LogWriter::printLine(const std::string& line)
+    {
+        // Get current time
+        time_t rawtime;
+        struct tm* timeinfo;
+        time(&rawtime);
+        timeinfo = localtime(&rawtime);
+
+        // print timestamp and 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/branches/output/src/libraries/util/output/LogWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/LogWriter.h	(revision 8774)
+++ code/branches/output/src/libraries/util/output/LogWriter.h	(revision 8774)
@@ -0,0 +1,71 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LogWriter_H__
+#define _LogWriter_H__
+
+#include "util/UtilPrereqs.h"
+
+#include <fstream>
+
+#include "OutputListener.h"
+
+namespace orxonox
+{
+namespace test
+{
+    class _UtilExport LogWriter : public OutputListener
+    {
+        public:
+            static LogWriter& getInstance();
+
+            void setLogPath(const std::string& path);
+
+        protected:
+            virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines);
+
+        private:
+            LogWriter();
+            LogWriter(const LogWriter&);
+            ~LogWriter();
+
+            void openFile();
+            void closeFile();
+
+            void printLine(const std::string& line);
+
+            std::string filename_;
+            std::string path_;
+            bool bDefaultPath_;
+
+            std::ofstream file_;
+    };
+}
+}
+
+#endif /* _LogWriter_H__ */
Index: code/branches/output/src/libraries/util/output/MemoryWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/MemoryWriter.cc	(revision 8774)
+++ code/branches/output/src/libraries/util/output/MemoryWriter.cc	(revision 8774)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "MemoryWriter.h"
+
+#include "OutputManager.h"
+
+namespace orxonox
+{
+namespace test
+{
+    MemoryWriter::MemoryWriter()
+    {
+        this->setLevelMask(level::all);
+    }
+
+    MemoryWriter::~MemoryWriter()
+    {
+    }
+
+    /*static*/ MemoryWriter& MemoryWriter::getInstance()
+    {
+        static MemoryWriter instance;
+        return instance;
+    }
+
+    void MemoryWriter::output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+    {
+        this->messages_.push_back(Message(level, context, lines));
+    }
+
+    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);
+        }
+    }
+
+    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/branches/output/src/libraries/util/output/MemoryWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/MemoryWriter.h	(revision 8774)
+++ code/branches/output/src/libraries/util/output/MemoryWriter.h	(revision 8774)
@@ -0,0 +1,70 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MemoryWriter_H__
+#define _MemoryWriter_H__
+
+#include "util/UtilPrereqs.h"
+#include "OutputListener.h"
+
+namespace orxonox
+{
+namespace test
+{
+    class _UtilExport MemoryWriter : public OutputListener
+    {
+        struct Message
+        {
+            Message(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+                : level(level), context(context), lines(lines) {}
+
+            OutputLevel level;
+            OutputContext context;
+            std::vector<std::string> lines;
+        };
+
+        public:
+            static MemoryWriter& getInstance();
+
+            void resendOutput(OutputListener* listener) const;
+            void disable();
+
+        protected:
+            virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines);
+
+        private:
+            MemoryWriter();
+            MemoryWriter(const MemoryWriter&);
+            ~MemoryWriter();
+
+            std::vector<Message> messages_;
+    };
+}
+}
+
+#endif /* _MemoryWriter_H__ */
Index: code/branches/output/src/libraries/util/output/OutputDefinitions.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputDefinitions.h	(revision 8772)
+++ code/branches/output/src/libraries/util/output/OutputDefinitions.h	(revision 8774)
@@ -69,4 +69,5 @@
         static const OutputContext test1     = registerContext("test1");
         static const OutputContext test2     = registerContext("test2");
+        static const OutputContext output    = registerContext("output");
     }
 }
Index: code/branches/output/src/libraries/util/output/OutputListener.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputListener.h	(revision 8772)
+++ code/branches/output/src/libraries/util/output/OutputListener.h	(revision 8774)
@@ -42,6 +42,4 @@
     class _UtilExport OutputListener
     {
-        friend class OutputManager;
-
         public:
             OutputListener();
@@ -63,4 +61,8 @@
                 { return ((this->levelMask_ & level) && (this->contextMask_ & context)); }
 
+            inline void unfilteredOutput(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+                { if (this->acceptsOutput(level, context)) this->output(level, context, lines); }
+
+        protected:
             virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines) = 0;
 
Index: code/branches/output/src/libraries/util/output/OutputManager.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputManager.cc	(revision 8772)
+++ code/branches/output/src/libraries/util/output/OutputManager.cc	(revision 8774)
@@ -31,4 +31,6 @@
 #include "util/Debug.h"
 #include "OutputListener.h"
+#include "MemoryWriter.h"
+#include "LogWriter.h"
 
 namespace orxonox
@@ -44,14 +46,8 @@
             }
 
+        protected:
             virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
             {
-                std::string prefix = OutputManager::getInstance().getLevelName(level) + ": ";
-                if (context != context::undefined)
-                {
-                    std::string context_name = OutputManager::getInstance().getContextName(context);
-                    if (context_name == "")
-                        context_name = OutputManager::getInstance().getComposedContextName(context);
-                    prefix += "[" + context_name + "] ";
-                }
+                const std::string& prefix = OutputManager::getInstance().getDefaultPrefix(level, context);
                 std::string blanks(prefix.length(), ' ');
 
@@ -74,5 +70,9 @@
     {
         static OutputManager& instance = OutputManager::getInstanceInternal();
+
         static ConsoleOutput consoleOutputInstance;
+        static MemoryWriter& memoryWriterInstance = MemoryWriter::getInstance(); (void)memoryWriterInstance;
+        static LogWriter& logWriterInstance = LogWriter::getInstance(); (void)logWriterInstance;
+
         return instance;
     }
@@ -94,6 +94,5 @@
 
         for (size_t i = 0; i < this->listeners_.size(); ++i)
-            if (this->listeners_[i]->acceptsOutput(level, context))
-                this->listeners_[i]->output(level, context, lines);
+            this->listeners_[i]->unfilteredOutput(level, context, lines);
     }
 
@@ -211,4 +210,17 @@
         return name;
     }
+
+    std::string OutputManager::getDefaultPrefix(OutputLevel level, OutputContext context) const
+    {
+        std::string prefix = this->getLevelName(level) + ": ";
+        if (context != context::undefined)
+        {
+            std::string context_name = this->getContextName(context);
+            if (context_name == "")
+                context_name = this->getComposedContextName(context);
+            prefix += "[" + context_name + "] ";
+        }
+        return prefix;
+    }
 }
 }
Index: code/branches/output/src/libraries/util/output/OutputManager.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputManager.h	(revision 8772)
+++ code/branches/output/src/libraries/util/output/OutputManager.h	(revision 8774)
@@ -46,8 +46,7 @@
     class _UtilExport OutputManager
     {
-        friend class OutputListener;
-
         public:
             static OutputManager& getInstance();
+            static OutputManager& getInstanceInternal();
 
             void pushMessage(OutputLevel level, OutputContext context, const std::string& message);
@@ -73,4 +72,5 @@
             const std::string& getContextName(OutputContext context) const;
             std::string getComposedContextName(OutputContext context) const;
+            std::string getDefaultPrefix(OutputLevel level, OutputContext context) const;
 
         private:
@@ -78,6 +78,4 @@
             OutputManager(const OutputManager&);
             ~OutputManager();
-
-            static OutputManager& getInstanceInternal();
 
             std::vector<OutputListener*> listeners_;
