Index: code/branches/testing/src/libraries/util/output/LogWriter.cc
===================================================================
--- code/branches/testing/src/libraries/util/output/LogWriter.cc	(revision 9543)
+++ code/branches/testing/src/libraries/util/output/LogWriter.cc	(revision 9544)
@@ -39,7 +39,10 @@
 #include "OutputManager.h"
 #include "MemoryWriter.h"
+#include "util/Convert.h"
 
 namespace orxonox
 {
+    static const int MAX_ARCHIVED_FILES = 9;
+
     /**
         @brief Constructor, initializes the desired output levels and the name and path of the log-file, and opens the log-file.
@@ -82,4 +85,7 @@
     void LogWriter::openFile()
     {
+        // archive the old log file
+        this->archive();
+
         // open the file
         this->file_.open(this->getPath().c_str(), std::fstream::out);
@@ -102,4 +108,48 @@
             this->file_.close();
         }
+    }
+
+    /**
+     * @brief Archives old copies of the log file by adding increasing numbers to the filename.
+     */
+    void LogWriter::archive(int index)
+    {
+        std::string oldPath = this->getArchivedPath(index);
+
+        // see if the file already exists, otherwise return
+        std::ifstream stream(oldPath.c_str());
+        bool exists = stream.is_open();
+        stream.close();
+
+        if (!exists)
+            return;
+
+        if (index < MAX_ARCHIVED_FILES)
+        {
+            // increment the index and archive the file with the next higher index
+            this->archive(++index);
+
+            // create the new path based on the incremented index
+            std::string newPath = this->getArchivedPath(index);
+
+            // move the file
+            std::rename(oldPath.c_str(), newPath.c_str());
+        }
+        else
+        {
+            // delete the file
+            std::remove(oldPath.c_str());
+        }
+    }
+    
+    /**
+     * @brief Returns the path for archived copies of the logfile (based on the archive index)
+     */
+    std::string LogWriter::getArchivedPath(int index) const
+    {
+        std::string path = this->getPath();
+        if (index > 0)
+            path += '.' + multi_cast<std::string>(index);
+        return path;
     }
 
Index: code/branches/testing/src/libraries/util/output/LogWriter.h
===================================================================
--- code/branches/testing/src/libraries/util/output/LogWriter.h	(revision 9543)
+++ code/branches/testing/src/libraries/util/output/LogWriter.h	(revision 9544)
@@ -76,4 +76,7 @@
             void closeFile();
 
+            void archive(int index = 0);
+            std::string getArchivedPath(int index) const;
+
             std::string filename_;  ///< The name of the log-file (without directory)
             std::string directory_; ///< The directory where the log-file resided (without file-name)
Index: code/branches/testing/test/util/output/LogWriterTest.cc
===================================================================
--- code/branches/testing/test/util/output/LogWriterTest.cc	(revision 9543)
+++ code/branches/testing/test/util/output/LogWriterTest.cc	(revision 9544)
@@ -2,7 +2,18 @@
 #include "util/Output.h"
 #include "util/output/LogWriter.h"
+#include "util/Convert.h"
 
 namespace orxonox
 {
+    namespace
+    {
+        class MockLogWriter : public LogWriter
+        {
+            public:
+                virtual void printLine(const std::string& line, OutputLevel level)
+                    { this->LogWriter::printLine(line, level); }
+        };
+    }
+
     // test constructor opens file
     TEST(LogWriterTest, ConstructorOpensFile)
@@ -15,13 +26,40 @@
     bool fileExists(const std::string& path)
     {
-        std::ifstream stream(path.c_str(), std::fstream::in);
-        bool exists = stream.is_open();
+        std::ifstream stream(path.c_str());
+        bool exists = stream.is_open() && stream.good();
         stream.close();
         return exists;
     }
 
-    bool fileSuccessfullyDeleted(const std::string& path)
-    {
-        return std::remove(path.c_str()) == 0;
+    std::string getLineWhichContains(const std::string& path, const std::string& message)
+    {
+        std::ifstream file(path.c_str());
+        EXPECT_TRUE(file.is_open());
+        EXPECT_TRUE(file.good());
+        EXPECT_FALSE(file.eof());
+
+        while (file.is_open() && file.good() && !file.eof())
+        {
+            std::string line;
+            std::getline(file, line);
+
+            // see if we find the output and return
+            if (line.find(message) == (line.size() - message.size()))
+                return line;
+        }
+
+        return std::string();
+    }
+
+    bool fileContains(const std::string& path, const std::string& message)
+    {
+        return !getLineWhichContains(path, message).empty();
+    }
+
+    bool deleteFile(const std::string& path)
+    {
+        bool result = std::remove(path.c_str()) == 0;
+        EXPECT_FALSE(fileExists(path));
+        return result;
     }
 
@@ -31,5 +69,5 @@
 
         // cleanup before test
-        fileSuccessfullyDeleted(path);
+        deleteFile(path);
 
         {
@@ -41,5 +79,5 @@
 
         // cleanup after test
-        EXPECT_TRUE(fileSuccessfullyDeleted(path));
+        EXPECT_TRUE(deleteFile(path));
     }
 
@@ -61,23 +99,5 @@
         }
 
-        {
-            std::ifstream file(path.c_str(), std::fstream::in);
-            ASSERT_TRUE(file.is_open());
-            ASSERT_TRUE(file.good());
-            ASSERT_FALSE(file.eof());
-
-            while (!file.eof())
-            {
-                std::string line;
-                std::getline(file, line);
-
-                // see if we find the output and return
-                if (line.find("mytestoutput") != std::string::npos)
-                    return;
-            }
-
-            // output not found - failure!
-            FAIL();
-        }
+        EXPECT_TRUE(fileContains(path, "mytestoutput"));
     }
 
@@ -99,34 +119,105 @@
         }
 
-        {
-            std::ifstream file(path.c_str(), std::fstream::in);
-            ASSERT_TRUE(file.is_open());
-            ASSERT_TRUE(file.good());
-            ASSERT_FALSE(file.eof());
-
-            while (!file.eof())
-            {
-                std::string line;
-                std::getline(file, line);
-
-                // see if we find the output and return
-                if (line.find("myothertestoutput") != std::string::npos)
-                {
-                    EXPECT_TRUE(std::isdigit(line[0]));
-                    EXPECT_TRUE(std::isdigit(line[1]));
-                    EXPECT_EQ(':', line[2]);
-                    EXPECT_TRUE(std::isdigit(line[3]));
-                    EXPECT_TRUE(std::isdigit(line[4]));
-                    EXPECT_EQ(':', line[5]);
-                    EXPECT_TRUE(std::isdigit(line[6]));
-                    EXPECT_TRUE(std::isdigit(line[7]));
-                    EXPECT_EQ(' ', line[8]);
-                    return;
-                }
-            }
-
-            // output not found - failure!
-            FAIL();
-        }
+        std::string line = getLineWhichContains(path, "myothertestoutput");
+        EXPECT_FALSE(line.empty());
+        EXPECT_TRUE(std::isdigit(line[0]));
+        EXPECT_TRUE(std::isdigit(line[1]));
+        EXPECT_EQ(':', line[2]);
+        EXPECT_TRUE(std::isdigit(line[3]));
+        EXPECT_TRUE(std::isdigit(line[4]));
+        EXPECT_EQ(':', line[5]);
+        EXPECT_TRUE(std::isdigit(line[6]));
+        EXPECT_TRUE(std::isdigit(line[7]));
+        EXPECT_EQ(' ', line[8]);
+    }
+
+    void deleteAllLogFiles()
+    {
+        std::string path;
+        {
+            LogWriter writer;
+            path = writer.getPath();
+        }
+
+        deleteFile(path);
+        deleteFile(path + ".1");
+        deleteFile(path + ".2");
+        deleteFile(path + ".3");
+        deleteFile(path + ".4");
+        deleteFile(path + ".5");
+        deleteFile(path + ".6");
+        deleteFile(path + ".7");
+        deleteFile(path + ".8");
+        deleteFile(path + ".9");
+    }
+
+    TEST(LogWriterTest, ArchivesOldLogFile)
+    {
+        deleteAllLogFiles();
+
+        std::string path;
+
+        {
+            MockLogWriter writer;
+            path = writer.getPath();
+            writer.printLine("test1", level::message);
+        }
+
+        EXPECT_TRUE(fileExists(path));
+        EXPECT_TRUE(fileContains(path, "test1"));
+        EXPECT_FALSE(fileExists(path + ".1"));
+        EXPECT_FALSE(fileExists(path + ".2"));
+        EXPECT_FALSE(fileExists(path + ".3"));
+
+        {
+            MockLogWriter writer;
+            writer.printLine("test2", level::message);
+        }
+
+        EXPECT_TRUE(fileExists(path));
+        EXPECT_TRUE(fileContains(path, "test2"));
+        EXPECT_TRUE(fileExists(path + ".1"));
+        EXPECT_TRUE(fileContains(path + ".1", "test1"));
+        EXPECT_FALSE(fileExists(path + ".2"));
+        EXPECT_FALSE(fileExists(path + ".3"));
+
+        {
+            MockLogWriter writer;
+            writer.printLine("test3", level::message);
+        }
+
+        EXPECT_TRUE(fileExists(path));
+        EXPECT_TRUE(fileContains(path, "test3"));
+        EXPECT_TRUE(fileExists(path + ".1"));
+        EXPECT_TRUE(fileContains(path + ".1", "test2"));
+        EXPECT_TRUE(fileExists(path + ".2"));
+        EXPECT_TRUE(fileContains(path + ".2", "test1"));
+        EXPECT_FALSE(fileExists(path + ".3"));
+    }
+
+    TEST(LogWriterTest, ArchivesNineLogFiles)
+    {
+        deleteAllLogFiles();
+
+        std::string path;
+        for (int i = 0; i < 20; ++i)
+        {
+            MockLogWriter writer;
+            path = writer.getPath();
+            writer.printLine("test" + multi_cast<std::string>(i), level::message);
+        }
+
+        EXPECT_TRUE(fileContains(path, "test19"));
+        EXPECT_TRUE(fileContains(path + ".1", "test18"));
+        EXPECT_TRUE(fileContains(path + ".2", "test17"));
+        EXPECT_TRUE(fileContains(path + ".3", "test16"));
+        EXPECT_TRUE(fileContains(path + ".4", "test15"));
+        EXPECT_TRUE(fileContains(path + ".5", "test14"));
+        EXPECT_TRUE(fileContains(path + ".6", "test13"));
+        EXPECT_TRUE(fileContains(path + ".7", "test12"));
+        EXPECT_TRUE(fileContains(path + ".8", "test11"));
+        EXPECT_TRUE(fileContains(path + ".9", "test10"));
+        EXPECT_FALSE(fileExists(path + ".10"));
+        EXPECT_FALSE(fileExists(path + ".11"));
     }
 }
