Index: code/trunk/src/libraries/util/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/util/CMakeLists.txt	(revision 8706)
+++ code/trunk/src/libraries/util/CMakeLists.txt	(revision 8729)
@@ -19,5 +19,6 @@
 
 SET_SOURCE_FILES(UTIL_SRC_FILES
-COMPILATION_BEGIN StableCompilation.cc
+
+BUILD_UNIT StableBuildUnit.cc
   Clipboard.cc
   Clock.cc
@@ -32,5 +33,5 @@
   SmallObjectAllocator.cc
   SubString.cc
-COMPILATION_END
+END_BUILD_UNIT
 
   MultiType.cc
@@ -40,11 +41,4 @@
   StringUtils.cc
 )
-
-IF(MSVC)
-  # Simply using #pragma warning(disable:4244) doesn't really disable it
-  # if the warning occurs in a template in another file
-  # Hence promote it manually to a higher warning level (4)
-  SET_SOURCE_FILES_PROPERTIES(MultiType.cc PROPERTIES COMPILE_FLAGS "-w44244")
-ENDIF()
 
 ORXONOX_ADD_LIBRARY(util
Index: code/trunk/src/libraries/util/Convert.h
===================================================================
--- code/trunk/src/libraries/util/Convert.h	(revision 8706)
+++ code/trunk/src/libraries/util/Convert.h	(revision 8729)
@@ -133,4 +133,10 @@
 #include "ImplicitConversion.h"
 
+// disable warnings about possible loss of data
+#ifdef ORXONOX_COMPILER_MSVC
+#  pragma warning(push)
+#  pragma warning(disable:4244)
+#endif
+
 namespace orxonox
 {
@@ -471,3 +477,8 @@
 }
 
+// Reinstate warnings
+#ifdef ORXONOX_COMPILER_MSVC
+#  pragma warning(pop)
+#endif
+
 #endif /* _Convert_H__ */
Index: code/trunk/src/libraries/util/Debug.h
===================================================================
--- code/trunk/src/libraries/util/Debug.h	(revision 8706)
+++ code/trunk/src/libraries/util/Debug.h	(revision 8729)
@@ -83,6 +83,4 @@
 #ifdef ORXONOX_RELEASE
     const int hardDebugLevel = OutputLevel::Verbose;
-#elif defined(NDEBUG)
-    const int hardDebugLevel = OutputLevel::Verbose;
 #else
     //! Maximum level for debug output that should be even processed at run time
@@ -125,3 +123,9 @@
             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/Math.h
===================================================================
--- code/trunk/src/libraries/util/Math.h	(revision 8706)
+++ code/trunk/src/libraries/util/Math.h	(revision 8729)
@@ -299,29 +299,4 @@
 
     _UtilExport unsigned long getUniqueNumber();
-
-    /**
-        @brief A Vector class containing two integers @a x and @a y.
-    */
-    class IntVector2
-    {
-    public:
-        IntVector2() : x(0), y(0) { }
-        IntVector2(int _x, int _y) : x(_x), y(_y) { }
-        int x;
-        int y;
-    };
-
-    /**
-        @brief A Vector class containing three integers @a x, @a y, and @a z.
-    */
-    class IntVector3
-    {
-    public:
-        IntVector3() : x(0), y(0), z(0) { }
-        IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }
-        int x;
-        int y;
-        int z;
-    };
 }
 
Index: code/trunk/src/libraries/util/OutputHandler.cc
===================================================================
--- code/trunk/src/libraries/util/OutputHandler.cc	(revision 8706)
+++ code/trunk/src/libraries/util/OutputHandler.cc	(revision 8729)
@@ -69,5 +69,5 @@
         */
         LogFileWriter()
-            : OutputListener(OutputHandler::logFileOutputListenerName_s)
+            : OutputListener("LogFile")
         {
             // Get path for a temporary file
@@ -85,9 +85,10 @@
             timeinfo = localtime(&rawtime);
 
-            this->logFile_.open(this->logFilename_.c_str(), std::fstream::out);
-            this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl;
-            this->logFile_.flush();
-
-            this->outputStream_ = &this->logFile_;
+            this->openFile();
+            if (this->logFile_.is_open())
+            {
+                this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl;
+                this->logFile_.flush();
+            }
         }
 
@@ -95,6 +96,9 @@
         ~LogFileWriter()
         {
-            this->logFile_ << "Closed log" << std::endl;
-            this->logFile_.close();
+            if (this->logFile_.is_open())
+            {
+                this->logFile_ << "Closed log" << std::endl;
+                this->logFile_.close();
+            }
         }
 
@@ -102,16 +106,36 @@
         void setLogPath(const std::string& path)
         {
-            this->logFile_.close();
-            // Read old file into a buffer
-            std::ifstream old(this->logFilename_.c_str());
+            if (this->logFile_.is_open())
+                this->logFile_.close();
+
+            // Open the new file
             this->logFilename_ = path + logFileBaseName_g;
-            // Open the new file and feed it the content of the old one
+            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);
-            this->logFile_ << old.rdbuf();
-            this->logFile_.flush();
-            old.close();
-        }
-
-    private:
+
+            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
@@ -133,5 +157,5 @@
         //! Only assigns the output stream with std::cout
         ConsoleWriter()
-            : OutputListener("consoleLog")
+            : OutputListener("Console")
         {
             this->outputStream_ = &std::cout;
@@ -147,7 +171,8 @@
         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
-        Only output below or equal to the current soft debug level is written
-        to minimise huge arrays for the normal run.
+        At some point, OutputHandler::disableMemoryLog() has to be called in
+        order to avoid large memory footprints of this class.
     */
     class MemoryLogWriter : public OutputListener
@@ -156,8 +181,4 @@
         friend class OutputHandler;
 
-        /**
-        @brief
-            Sets the right soft debug level and registers itself
-        */
         MemoryLogWriter()
             : OutputListener("memoryLog")
@@ -166,5 +187,5 @@
         }
 
-        //! Pushed the just written output to the internal array
+        //! Push the just written output to the internal array
         void outputChanged(int level)
         {
@@ -180,6 +201,6 @@
 
     private:
-        std::ostringstream                        buffer_; //!< Stream object used to process the output
-        std::vector<std::pair<int, std::string> > output_; //!< Vector containing ALL output
+        std::ostringstream          buffer_; //!< Stream object used to process the output
+        OutputHandler::OutputVector output_; //!< Vector containing ALL output
     };
 
@@ -188,6 +209,5 @@
     ///// OutputHandler /////
     /////////////////////////
-    const std::string OutputHandler::logFileOutputListenerName_s = "logFile";
-          int         OutputHandler::softDebugLevel_s = hardDebugLevel;
+    int OutputHandler::softDebugLevel_s = hardDebugLevel;
 
     //! Creates the LogFileWriter and the MemoryLogWriter
@@ -195,25 +215,28 @@
         : outputLevel_(OutputLevel::Verbose)
     {
+        // Note: These levels only concern startup before orxonox.ini is read.
 #ifdef ORXONOX_RELEASE
-        const OutputLevel::Value defaultLevelConsole = OutputLevel::Error;
-        const OutputLevel::Value defaultLevelLogFile = OutputLevel::Info;
+        const OutputLevel::Value initialLevelConsole = OutputLevel::Error;
 #else
-        const OutputLevel::Value defaultLevelConsole = OutputLevel::Info;
-        const OutputLevel::Value defaultLevelLogFile = OutputLevel::Debug;
+        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_ = defaultLevelLogFile;
+        this->logFile_->softDebugLevel_ = intialLevelLogFile;
         this->registerOutputListener(this->logFile_);
 
         this->consoleWriter_ = new ConsoleWriter();
-        this->consoleWriter_->softDebugLevel_ = defaultLevelConsole;
+        this->consoleWriter_->softDebugLevel_ = initialLevelConsole;
         this->registerOutputListener(this->consoleWriter_);
 
-        this->output_ = new MemoryLogWriter();
-        // We capture as much input as the listener with the highest level
-        this->output_->softDebugLevel_ = getSoftDebugLevel();
-        this->registerOutputListener(this->output_);
+        this->memoryBuffer_ = new MemoryLogWriter();
+        // Write everything, e.g. use hardDebugLevel
+        this->memoryBuffer_->softDebugLevel_ = hardDebugLevel;
+        this->registerOutputListener(this->memoryBuffer_);
     }
 
@@ -223,5 +246,5 @@
         delete this->logFile_;
         delete this->consoleWriter_;
-        delete this->output_;
+        delete this->memoryBuffer_; // Might already be NULL
     }
 
@@ -234,5 +257,5 @@
     void OutputHandler::registerOutputListener(OutputListener* listener)
     {
-        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
         {
             if ((*it)->name_ == listener->name_)
@@ -243,11 +266,18 @@
         }
         this->listeners_.push_back(listener);
-        // Update global soft debug level
-        this->setSoftDebugLevel(listener->getOutputListenerName(), listener->getSoftDebugLevel());
+        this->updateGlobalDebugLevel();
     }
 
     void OutputHandler::unregisterOutputListener(OutputListener* listener)
     {
-        this->listeners_.remove(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();
     }
 
@@ -255,4 +285,20 @@
     {
         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();
     }
 
@@ -267,17 +313,19 @@
     }
 
-    OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorBegin() const
-    {
-        return this->output_->output_.begin();
-    }
-
-    OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorEnd() const
-    {
-        return this->output_->output_.end();
+    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::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
         {
             if ((*it)->name_ == name)
@@ -289,13 +337,19 @@
     void OutputHandler::setSoftDebugLevel(const std::string& name, int level)
     {
-        int globalSoftDebugLevel = -1;
-        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
         {
             if ((*it)->name_ == name)
                 (*it)->softDebugLevel_ = level;
-            if ((*it)->softDebugLevel_ > globalSoftDebugLevel)
-                globalSoftDebugLevel = (*it)->softDebugLevel_;
-        }
-        // Update global soft debug 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 8706)
+++ code/trunk/src/libraries/util/OutputHandler.h	(revision 8729)
@@ -39,5 +39,4 @@
 #include "UtilPrereqs.h"
 
-#include <list>
 #include <ostream>
 #include <string>
@@ -63,4 +62,5 @@
         enum Value
         {
+            TDebug  = -1,
             None    = 0,
             Error   = 1,
@@ -103,9 +103,7 @@
                 { return OutputHandler::getInstance().setOutputLevel(level); }
 
-            typedef std::vector<std::pair<int, std::string> >::const_iterator OutputVectorIterator;
-            //! Returns an iterator to the beginning of the all-output vector
-            OutputVectorIterator getOutputVectorBegin() const;
-            //! Returns an iterator to the end of the all-output vector
-            OutputVectorIterator getOutputVectorEnd() const;
+            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
@@ -136,8 +134,15 @@
             //! 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
@@ -213,7 +218,4 @@
             inline operator int() const { return 0; }
 
-            //! Name of the OutputListener that writes to the log file
-            static const std::string logFileOutputListenerName_s;
-
         private:
             OutputHandler();
@@ -221,10 +223,13 @@
             OutputHandler(const OutputHandler& rhs);      //!< Copy-constructor: Unused and undefined
 
-            std::list<OutputListener*> listeners_;        //!< Array with all registered output listeners
-            int                        outputLevel_;      //!< The level of the incoming output
-            LogFileWriter*             logFile_;          //!< Listener that writes to the log file
-            ConsoleWriter*             consoleWriter_;    //!< Listener for std::cout (just program beginning)
-            MemoryLogWriter*           output_;           //!< Listener that Stores ALL output below the current soft debug level
-            static int                 softDebugLevel_s;  //!< Maximum of all soft debug levels. @note This is only static for faster access
+            /// 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
     };
 
@@ -251,12 +256,4 @@
         //! Returns the name of this output listener
         const std::string& getOutputListenerName() const { return this->name_; }
-        //! Returns the soft debug level of the listener
-        int getSoftDebugLevel() const { return this->softDebugLevel_; }
-        //! Sets the soft debug level of the listener
-        void setSoftDebugLevel(int level)
-        {
-            this->softDebugLevel_ = level;
-            OutputHandler::getInstance().setSoftDebugLevel(this->name_, level);
-        }
 
     protected:
@@ -271,5 +268,5 @@
     inline OutputHandler& OutputHandler::output(const T& output)
     {
-        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
         {
             if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL)
Index: code/trunk/src/libraries/util/TriBool.h
===================================================================
--- code/trunk/src/libraries/util/TriBool.h	(revision 8706)
+++ 	(revision )
@@ -1,59 +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:
- *      Reto Grieder
- *   Co-authors:
- *      ...
- *
- */
-
-/**
-    @file
-    @ingroup Util
-*/
-
-#ifndef _TriBool_H__
-#define _TriBool_H__
-
-#include "UtilPrereqs.h"
-
-// tolua_begin
-namespace orxonox
-{
-    /** Sort of a boolean value that also has state \c Dontcare
-    @remarks
-        Even though \c False has the value 0, both \c True and \c Dontcare have
-        a value other than 0. Keep that in mind when using TriBools in if statements.
-    */
-    namespace TriBool
-    {
-        enum Value
-        {
-            False    =  0,
-            True     =  1,
-            Dontcare =  2
-        };
-    }
-}
-// tolua_end
-
-#endif /* _TriBool_H__ */
Index: code/trunk/src/libraries/util/UtilPrereqs.h
===================================================================
--- code/trunk/src/libraries/util/UtilPrereqs.h	(revision 8706)
+++ code/trunk/src/libraries/util/UtilPrereqs.h	(revision 8729)
@@ -87,6 +87,4 @@
     class Exception;
     class ExprParser;
-    class IntVector2;
-    class IntVector3;
     class MultiType;
     class OutputHandler;
Index: code/trunk/src/libraries/util/tribool.h
===================================================================
--- code/trunk/src/libraries/util/tribool.h	(revision 8729)
+++ code/trunk/src/libraries/util/tribool.h	(revision 8729)
@@ -0,0 +1,138 @@
+// Three-state boolean logic library
+
+// Copyright Douglas Gregor 2002-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Modifications by Orxonox to shape the third state into 'dontcare' instead
+// of 'indeterminate'. The difference is that 'dontcare' is actually a value
+// so that (dontcare == dontcare).
+// Also removed all logic operators except for == and !=
+
+
+// For more information, see http://www.boost.org
+#ifndef ORXONOX_TRIBOOL_H
+#define ORXONOX_TRIBOOL_H
+
+namespace orxonox {
+
+/**
+ * INTERNAL ONLY
+ * The type of the 'dontcare' keyword.
+ */
+struct dontcare_keyword_t { };
+
+/**
+ * \brief Keyword for the dontcare tribool value
+ */
+const dontcare_keyword_t dontcare = dontcare_keyword_t();
+
+/**
+ * \brief A 3-state boolean type.
+ *
+ * 3-state boolean values are either true, false, or
+ * dontcare.
+ */
+class tribool
+{
+public:
+  /**
+   * Construct a new 3-state boolean value with the value 'false'.
+   *
+   * \throws nothrow
+   */
+  tribool() : value(false_value) {}
+
+  /**
+   * Construct a new 3-state boolean value with the given boolean
+   * value, which may be \c true or \c false.
+   *
+   * \throws nothrow
+   */
+  tribool(bool value) : value(value? true_value : false_value) {}
+
+  /**
+   * Construct a new 3-state boolean value with an dontcare value.
+   *
+   * \throws nothrow
+   */
+  tribool(dontcare_keyword_t) : value(dontcare_value) {}
+
+  /**
+   * \brief Compare tribools for equality
+   *
+   * \returns the result of comparing two tribool values.
+   * \throws nothrow
+   */
+  inline bool operator==(tribool y)
+  {
+    return (this->value == y.value);
+  }
+
+  /**
+   * \overload
+   */
+  inline bool operator==(bool y) { return (*this) == tribool(y); }
+
+  /**
+   * \overload
+   */
+  inline bool operator==(dontcare_keyword_t)
+  { return tribool(dontcare) == (*this); }
+
+  /**
+   * \brief Compare tribools for inequality
+   *
+   * \returns the result of comparing two tribool values for inequality.
+   * \throws nothrow
+   */
+  inline bool operator!=(tribool y)
+  {
+    return !((*this) == y);
+  }
+
+  /**
+   * \overload
+   */
+  inline bool operator!=(bool y) { return (*this) != tribool(y); }
+
+  /**
+   * \overload
+   */
+  inline bool operator!=(dontcare_keyword_t)
+  { return (*this) != tribool(dontcare); }
+
+  /**
+   * The actual stored value in this 3-state boolean, which may be false, true,
+   * or dontcare.
+   */
+  enum value_t { false_value, true_value, dontcare_value } value;
+};
+
+/**
+ * \overload
+ */
+inline bool operator==(bool x, tribool y) { return tribool(x) == y; }
+
+/**
+ * \overload
+ */
+inline bool operator==(dontcare_keyword_t, tribool x)
+{ return tribool(dontcare) == x; }
+
+/**
+ * \overload
+ */
+inline bool operator!=(bool x, tribool y) { return tribool(x) != y; }
+
+/**
+ * \overload
+ */
+inline bool operator!=(dontcare_keyword_t, tribool x)
+{ return tribool(dontcare) != x; }
+
+} // end namespace orxonox
+
+#endif // ORXONOX_TRIBOOL_H
+
