Index: code/branches/console/cmake/FindBoost.cmake
===================================================================
--- code/branches/console/cmake/FindBoost.cmake	(revision 1229)
+++ code/branches/console/cmake/FindBoost.cmake	(revision 1230)
@@ -101,4 +101,6 @@
 # Add in some path suffixes. These will have to be updated whenever a new Boost version comes out.
 SET(SUFFIX_FOR_PATH
+ boost-1_35_0
+ boost-1_35
  boost-1_34_1
  boost-1_34_0
@@ -112,5 +114,8 @@
 #
 IF(WIN32)
-  SET(Boost_INCLUDE_DIR ../libs/boost_1_33_1)
+  SET(Boost_INCLUDE_DIR
+#    ../libs/boost_1_33_1
+    ../libs/boost_1_35_0
+  )
 ELSE(WIN32)
   FIND_PATH(Boost_INCLUDE_DIR NAMES boost/config.hpp PATH_SUFFIXES ${SUFFIX_FOR_PATH} PATHS
@@ -187,4 +192,5 @@
   gcc-1_33_1
   gcc-mt-1_33_1
+  mgw34-mt-1_35
 )
 
Index: code/branches/console/src/core/CMakeLists.txt
===================================================================
--- code/branches/console/src/core/CMakeLists.txt	(revision 1229)
+++ code/branches/console/src/core/CMakeLists.txt	(revision 1230)
@@ -27,4 +27,5 @@
   Script.cc
   TclBind.cc
+  TclThreadManager.cc
 )
 
@@ -37,3 +38,4 @@
   ${Lua_LIBRARIES}
   ${OIS_LIBRARIES}
+  ${Boost_thread_LIBRARIES}
 )
Index: code/branches/console/src/core/CommandExecutor.cc
===================================================================
--- code/branches/console/src/core/CommandExecutor.cc	(revision 1229)
+++ code/branches/console/src/core/CommandExecutor.cc	(revision 1230)
@@ -50,4 +50,5 @@
     ConsoleCommandShortcutExtern(exec, AccessLevel::None);
     ConsoleCommandShortcutExtern(echo, AccessLevel::None);
+    ConsoleCommandShortcutExtern(puts, AccessLevel::None);
 
     ConsoleCommandShortcutExtern(read, AccessLevel::None);
@@ -92,5 +93,14 @@
     std::string echo(const std::string& text)
     {
+        std::cout << text << std::endl;
         return text;
+    }
+
+    void puts(bool newline, const std::string& text)
+    {
+        if (newline)
+            std::cout << text << std::endl;
+        else
+            std::cout << text;
     }
 
@@ -384,13 +394,13 @@
         if (useTcl)
         {
-            return TclBind::eval(command);
-        }
-        else
-        {
-            if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
-                CommandExecutor::parse(command);
-
-            return CommandExecutor::execute(CommandExecutor::getEvaluation());
-        }
+            std::string temp = getLowercase(removeTrailingWhitespaces(command));
+            if (!(temp.find("tclthread") == 0 || temp.find("tclthreadmanager") == 0))
+                return TclBind::eval(command);
+        }
+
+        if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
+            CommandExecutor::parse(command);
+
+        return CommandExecutor::execute(CommandExecutor::getEvaluation());
     }
 
Index: code/branches/console/src/core/CommandExecutor.h
===================================================================
--- code/branches/console/src/core/CommandExecutor.h	(revision 1229)
+++ code/branches/console/src/core/CommandExecutor.h	(revision 1230)
@@ -65,4 +65,5 @@
     void exec(const std::string& filename);
     std::string echo(const std::string& text);
+    void puts(bool newline, const std::string& test);
 
     void write(const std::string& filename, const std::string& text);
Index: code/branches/console/src/core/InputBuffer.cc
===================================================================
--- code/branches/console/src/core/InputBuffer.cc	(revision 1229)
+++ code/branches/console/src/core/InputBuffer.cc	(revision 1230)
@@ -39,5 +39,5 @@
     {
         //this->bActivated_ = false;
-        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜ0123456789 \\\"(){}[]<>.:,;_-+*/=!?|$&%^";
+        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜ0123456789 \\\"(){}[]<>.:,;_-+*/=!?|$&%^~";
         this->keyboard_ = InputManager::getSingleton().getKeyboard();
         this->buffer_ = "";
Index: code/branches/console/src/core/OutputHandler.cc
===================================================================
--- code/branches/console/src/core/OutputHandler.cc	(revision 1229)
+++ code/branches/console/src/core/OutputHandler.cc	(revision 1230)
@@ -38,5 +38,9 @@
 namespace orxonox
 {
-    ConsoleCommandShortcutGeneric(log, createExecutor(createFunctor(&OutputHandler::log), "log", AccessLevel::None));
+    ConsoleCommandShortcutGeneric(log,     createExecutor(createFunctor(&OutputHandler::log),     "log",     AccessLevel::None));
+    ConsoleCommandShortcutGeneric(error,   createExecutor(createFunctor(&OutputHandler::error),   "error",   AccessLevel::None));
+    ConsoleCommandShortcutGeneric(warning, createExecutor(createFunctor(&OutputHandler::warning), "warning", AccessLevel::None));
+    ConsoleCommandShortcutGeneric(info,    createExecutor(createFunctor(&OutputHandler::info),    "info",    AccessLevel::None));
+    ConsoleCommandShortcutGeneric(debug,   createExecutor(createFunctor(&OutputHandler::debug),   "debug",   AccessLevel::None));
 
     /**
Index: code/branches/console/src/core/OutputHandler.h
===================================================================
--- code/branches/console/src/core/OutputHandler.h	(revision 1229)
+++ code/branches/console/src/core/OutputHandler.h	(revision 1230)
@@ -63,4 +63,20 @@
             static inline std::string log(const std::string& text)
                 { OutputHandler::getOutStream().setOutputLevel(0); OutputHandler::getOutStream().output(text + "\n"); return text; }
+
+            /** @brief Puts an error on the outstream. @param text The text */
+            static inline std::string error(const std::string& text)
+                { OutputHandler::getOutStream().setOutputLevel(1); OutputHandler::getOutStream().output(text + "\n"); return text; }
+
+            /** @brief Puts a warning on the outstream. @param text The text */
+            static inline std::string warning(const std::string& text)
+                { OutputHandler::getOutStream().setOutputLevel(2); OutputHandler::getOutStream().output(text + "\n"); return text; }
+
+            /** @brief Puts an info on the outstream. @param text The text */
+            static inline std::string info(const std::string& text)
+                { OutputHandler::getOutStream().setOutputLevel(3); OutputHandler::getOutStream().output(text + "\n"); return text; }
+
+            /** @brief Puts some debug output on the outstream. @param text The text */
+            static inline std::string debug(const std::string& text)
+                { OutputHandler::getOutStream().setOutputLevel(4); OutputHandler::getOutStream().output(text + "\n"); return text; }
 
             /** @brief Returns a reference to the logfile. @return The logfile */
Index: code/branches/console/src/core/TclBind.cc
===================================================================
--- code/branches/console/src/core/TclBind.cc	(revision 1229)
+++ code/branches/console/src/core/TclBind.cc	(revision 1230)
@@ -70,9 +70,8 @@
         {
             this->interpreter_ = new Tcl::interpreter(this->tclLibPath_);
-            this->interpreter_->def("puts", TclBind::puts, Tcl::variadic());
-            this->interpreter_->def("orxonox", TclBind::orxonox, Tcl::variadic());
-            this->interpreter_->def("execute", TclBind::execute, Tcl::variadic());
-            this->interpreter_->eval("proc unknown {args} { return [orxonox $args] }");
+            this->interpreter_->def("orxonox", TclBind::tcl_orxonox, Tcl::variadic());
+            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
             this->interpreter_->eval("rename exit tclexit; proc exit {} { orxonox exit }");
+            this->interpreter_->eval("redef_puts");
         }
     }
@@ -89,12 +88,12 @@
     }
 
-    void TclBind::puts(Tcl::object const &args)
+    void TclBind::tcl_puts(Tcl::object const &args)
     {
         COUT(0) << args.get() << std::endl;
     }
 
-    std::string TclBind::orxonox(Tcl::object const &args)
+    std::string TclBind::tcl_orxonox(Tcl::object const &args)
     {
-std::cout << "Tcl_execute: args: " << args.get() << std::endl;
+std::cout << "Tcl_orxonox: args: " << args.get() << std::endl;
         std::string command = args.get();
 
@@ -111,6 +110,14 @@
     }
 
-    void TclBind::execute(Tcl::object const &args)
+    void TclBind::tcl_execute(Tcl::object const &args)
     {
+std::cout << "Tcl_execute: args: " << args.get() << std::endl;
+        std::string command = args.get();
+
+        if (command.size() >= 2 && command[0] == '{' && command[command.size() - 1] == '}')
+            command = command.substr(1, command.size() - 2);
+
+        if (!CommandExecutor::execute(command, false))
+            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
     }
 
@@ -145,5 +152,5 @@
         catch (Tcl::tcl_error const &e)
         {
-            COUT(1) << "Error: " << e.what() << std::endl;
+            COUT(1) << "Tcl error: " << e.what() << std::endl;
         }
         catch (std::exception const &e)
Index: code/branches/console/src/core/TclBind.h
===================================================================
--- code/branches/console/src/core/TclBind.h	(revision 1229)
+++ code/branches/console/src/core/TclBind.h	(revision 1230)
@@ -36,17 +36,21 @@
 namespace orxonox
 {
-    class TclBind
+    class _CoreExport TclBind
     {
         public:
             static TclBind& getInstance();
 
+            static std::string tcl(const std::string& tclcode);
+
             void setDataPath(const std::string& datapath);
+            std::string getTclLibPath() const { return this->tclLibPath_; }
             void createTclInterpreter();
             void createNewTclInterpreter();
 
-            static void puts(Tcl::object const &args);
-            static void execute(Tcl::object const &args);
-            static std::string orxonox(Tcl::object const &args);
-            static std::string tcl(const std::string& tclcode);
+            static void tcl_puts(Tcl::object const &args);
+
+            static void tcl_execute(Tcl::object const &args);
+            static std::string tcl_orxonox(Tcl::object const &args);
+
             static bool eval(const std::string& tclcode);
 
Index: code/branches/console/src/core/TclThreadManager.cc
===================================================================
--- code/branches/console/src/core/TclThreadManager.cc	(revision 1230)
+++ code/branches/console/src/core/TclThreadManager.cc	(revision 1230)
@@ -0,0 +1,410 @@
+/*
+ *   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:
+ *      ...
+ *
+ */
+
+#include <iostream>
+#include <string>
+
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
+#include <OgreTimer.h>
+
+#include "CoreIncludes.h"
+#include "ConsoleCommand.h"
+#include "CommandExecutor.h"
+#include "Debug.h"
+#include "TclBind.h"
+#include "TclThreadManager.h"
+#include "util/Convert.h"
+
+#define TCLTHREAD_MAX_QUEUE_LENGTH 1024
+#define TCLTHREAD_MAX_CPU_USAGE 0.50
+
+namespace orxonox
+{
+    ConsoleCommand(TclThreadManager, tclthread, AccessLevel::None, true);
+    ConsoleCommand(TclThreadManager, create,    AccessLevel::None, false);
+    ConsoleCommand(TclThreadManager, destroy,   AccessLevel::None, false);
+    ConsoleCommand(TclThreadManager, execute,   AccessLevel::None, false);
+    ConsoleCommand(TclThreadManager, query,     AccessLevel::None, false);
+
+    TclThreadManager* instance = &TclThreadManager::getInstance();
+
+    TclThreadManager::TclThreadManager()
+    {
+        RegisterRootObject(TclThreadManager);
+
+        this->IDcount_ = 0;
+        this->isReady_ = false;
+    }
+
+    TclThreadManager& TclThreadManager::getInstance()
+    {
+        static TclThreadManager instance;
+        return instance;
+    }
+
+    void TclThreadManager::tclthread(unsigned int threadID, const std::string& command)
+    {
+        TclThreadManager::execute(threadID, command);
+    }
+
+    unsigned int TclThreadManager::create()
+    {
+        if (TclThreadManager::getInstance().createTclThread())
+        {
+            COUT(0) << "Created new Tcl-thread with ID " << TclThreadManager::getInstance().IDcount_ << "." << std::endl;
+            return TclThreadManager::getInstance().IDcount_;
+        }
+        return 0;
+    }
+
+    void TclThreadManager::destroy(unsigned int threadID)
+    {
+        if (TclThreadManager::getInstance().destroyTclThread(threadID))
+        {
+            COUT(0) << "Destroyed Tcl-thread with ID " << threadID << "." << std::endl;
+        }
+    }
+
+    void TclThreadManager::execute(unsigned int threadID, const std::string& command)
+    {
+        TclThreadManager::getInstance().pushCommandBack(threadID, command);
+    }
+
+    std::string TclThreadManager::query(unsigned int threadID, const std::string& command)
+    {
+        return TclThreadManager::getInstance().eval(threadID, command);
+    }
+
+    void TclThreadManager::tcl_execute(Tcl::object const &args)
+    {
+std::cout << "3_1\n";
+std::cout << "Tcl-thread_execute: args: " << args.get() << std::endl;
+        std::string command = args.get();
+
+        if (command.size() >= 2 && command[0] == '{' && command[command.size() - 1] == '}')
+            command = command.substr(1, command.size() - 2);
+
+        TclThreadManager::getInstance().pushCommandBack(command);
+    }
+
+    std::string TclThreadManager::tcl_orxonox(Tcl::object const &args)
+    {
+std::cout << "4_1\n";
+std::cout << "Tcl-thread_orxonox: args: " << args.get() << std::endl;
+        std::string command = args.get();
+
+        if (command.size() >= 2 && command[0] == '{' && command[command.size() - 1] == '}')
+            command = command.substr(1, command.size() - 2);
+
+        return TclThreadManager::getInstance().eval(command);
+    }
+
+    Tcl::interpreter* TclThreadManager::createTclInterpreter(unsigned int threadID) const
+    {
+        Tcl::interpreter* i = new Tcl::interpreter(TclBind::getInstance().getTclLibPath());
+
+        i->def("orxonox", TclThreadManager::tcl_orxonox, Tcl::variadic());
+        i->def("execute", TclThreadManager::tcl_execute, Tcl::variadic());
+
+        std::string id = getConvertedValue<unsigned int, std::string>(threadID);
+        i->eval("rename exit tclexit; proc exit {} { orxonox TclThreadManager destroy " + id + " }");
+        i->eval("set threadid " + id);
+        i->eval("redef_puts");
+
+        return i;
+    }
+
+    bool TclThreadManager::createTclThread()
+    {
+        this->IDcount_++;
+        Tcl::interpreter* i = this->createTclInterpreter(this->IDcount_);
+        boost::try_mutex* m = new boost::try_mutex;
+        boost::thread*    t = new boost::thread(boost::bind(&tclThreadLoop, i, m, this->IDcount_));
+        TclThread newthread = {i, t, m};
+        {
+            // mutex threads
+            boost::mutex::scoped_lock lock(this->threadsMutex_);
+            this->threads_[this->IDcount_] = newthread;
+        }
+        {
+            // mutes threadqueues
+            boost::mutex::scoped_lock lock(this->threadQueuesMutex_);
+            this->threadQueues_[this->IDcount_];
+        }
+        return true;
+    }
+
+    bool TclThreadManager::destroyTclThread(unsigned int threadID)
+    {
+        // mutex threads
+        boost::mutex::scoped_lock lock(this->threadsMutex_);
+
+        std::map<unsigned int, TclThread>::iterator it = this->threads_.find(threadID);
+        if (it != this->threads_.end())
+        {
+            delete (*it).second.interpreter_;
+            delete (*it).second.thread_;
+            delete (*it).second.mutex_;
+
+            this->threads_.erase(it);
+            {
+                // mutex threadqueues
+                boost::mutex::scoped_lock lock(this->threadQueuesMutex_);
+                this->threadQueues_.erase(threadID);
+            }
+            return true;
+        }
+        else
+        {
+            COUT(1) << "Error: No Tcl-thread with ID " << threadID << "." << std::endl;
+            return false;
+        }
+    }
+
+    void TclThreadManager::pushCommandBack(const std::string& command)
+    {
+        // mutex orxqueue
+        boost::mutex::scoped_lock lock(this->orxonoxQueueMutex_);
+
+        while (this->orxonoxQueue_.size() == TCLTHREAD_MAX_QUEUE_LENGTH)
+            this->orxonoxQueueCondition_.wait(lock);
+
+        this->orxonoxQueue_.push(command);
+    }
+
+    std::string TclThreadManager::popCommandFront()
+    {
+        // mutex orxqueue
+        boost::mutex::scoped_lock lock(this->orxonoxQueueMutex_);
+
+        std::string command = this->orxonoxQueue_.front();
+        this->orxonoxQueue_.pop();
+
+        this->orxonoxQueueCondition_.notify_one();
+
+        return command;
+    }
+
+    bool TclThreadManager::isEmpty()
+    {
+        // mutex orxqueue
+        boost::mutex::scoped_lock lock(this->orxonoxQueueMutex_);
+
+        return this->orxonoxQueue_.empty();
+    }
+
+    void TclThreadManager::pushCommandBack(unsigned int threadID, const std::string& command)
+    {
+        // mutex threadqueues
+        boost::mutex::scoped_lock lock(this->threadQueuesMutex_);
+
+        std::map<unsigned int, std::queue<std::string> >::iterator it = this->threadQueues_.find(threadID);
+        if (it != this->threadQueues_.end())
+        {
+            (*it).second.push(command);
+        }
+        else
+        {
+            COUT(1) << "Error: No Tcl-thread with ID " << threadID << "." << std::endl;
+        }
+    }
+
+    std::string TclThreadManager::popCommandFront(unsigned int threadID)
+    {
+        // mutex threadqueues
+        boost::mutex::scoped_lock lock(this->threadQueuesMutex_);
+
+        std::map<unsigned int, std::queue<std::string> >::iterator it = this->threadQueues_.find(threadID);
+        if (it != this->threadQueues_.end())
+        {
+            std::string command = (*it).second.front();
+            (*it).second.pop();
+            return command;
+        }
+        else
+        {
+            COUT(1) << "Error: No Tcl-thread with ID " << threadID << "." << std::endl;
+            return "";
+        }
+    }
+
+    bool TclThreadManager::isEmpty(unsigned int threadID)
+    {
+        // mutex threadqueues
+        boost::mutex::scoped_lock lock(this->threadQueuesMutex_);
+
+        std::map<unsigned int, std::queue<std::string> >::iterator it = this->threadQueues_.find(threadID);
+        if (it != this->threadQueues_.end())
+        {
+            return (*it).second.empty();
+        }
+        else
+        {
+            COUT(1) << "Error: No Tcl-thread with ID " << threadID << "." << std::endl;
+            return true;
+        }
+    }
+
+    std::string TclThreadManager::eval(const std::string& command)
+    {
+        boost::mutex::scoped_lock lock(this->orxonoxEvalMutex_);
+
+        while (!this->isReady_)
+            this->orxonoxEvalCondition_.wait(lock);
+
+        CommandExecutor::execute(command, false);
+
+        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
+            return CommandExecutor::getLastEvaluation().getReturnvalue().toString();
+
+        return "";
+    }
+
+    std::string TclThreadManager::eval(unsigned int threadID, const std::string& command)
+    {
+        // mutex threads
+        boost::mutex::scoped_lock lock(this->threadsMutex_);
+
+        std::map<unsigned int, TclThread>::iterator it = this->threads_.find(threadID);
+        if (it != this->threads_.end())
+        {
+            boost::try_mutex::scoped_try_lock lock(*(*it).second.mutex_, boost::defer_lock_t());
+            bool threadIsReady = false;
+            try
+            {
+                threadIsReady = lock.try_lock();
+            }
+            catch(boost::lock_error& e){ std::cout << "lockerror thread" << std::endl; }
+
+            if (threadIsReady)
+            {
+                try
+                {
+std::cout << "2_1\n";
+                    return (*it).second.interpreter_->eval(command);
+                }
+                catch (Tcl::tcl_error const &e)
+                {
+std::cout << "2_2\n";
+                    COUT(1) << "Tcl error: " << e.what() << std::endl;
+                }
+                catch (std::exception const &e)
+                {
+std::cout << "2_3\n";
+                    COUT(1) << "Error while executing tcl: " << e.what() << std::endl;
+                }
+            }
+            else
+            {
+                COUT(1) << "Error: Tcl-thread with ID " << threadID << " is not ready. Wait until it's finished or start a new thread." << std::endl;
+            }
+        }
+        else
+        {
+            COUT(1) << "Error: No Tcl-thread with ID " << threadID << "." << std::endl;
+        }
+        return "";
+    }
+
+    void TclThreadManager::tick(float dt)
+    {
+        {
+            boost::mutex::scoped_lock lock(this->orxonoxEvalMutex_);
+            this->isReady_ = true;
+        }
+
+        this->orxonoxEvalCondition_.notify_one();
+        boost::this_thread::yield();
+
+        {
+            boost::mutex::scoped_lock lock(this->orxonoxEvalMutex_);
+            this->isReady_ = false;
+        }
+
+        unsigned long maxtime = (unsigned long)(dt * 1000000 * TCLTHREAD_MAX_CPU_USAGE);
+        Ogre::Timer timer;
+        while (!TclThreadManager::getInstance().isEmpty())
+        {
+            CommandExecutor::execute(TclThreadManager::getInstance().popCommandFront(), false);
+            if (timer.getMicroseconds() > maxtime)
+                break;
+        }
+    }
+
+    void tclThreadLoop(Tcl::interpreter* interpreter, boost::try_mutex* mutex, unsigned int threadID)
+    {
+        while (true)
+        {
+            {
+                boost::try_mutex::scoped_try_lock lock(*mutex, boost::defer_lock_t());
+                bool threadIsReady = false;
+                try
+                {
+                    threadIsReady = lock.try_lock();
+                }
+                catch(boost::lock_error& e){ std::cout << "lockerror thread" << std::endl; }
+
+                if (threadIsReady)
+                {
+                    while (!TclThreadManager::getInstance().isEmpty(threadID))
+                    {
+                        try
+                        {
+std::cout << "1\n";
+std::cout << threadID << std::endl;
+std::string temp = TclThreadManager::getInstance().popCommandFront(threadID);
+std::cout << temp << std::endl;
+                            interpreter->eval(temp);
+std::cout << "2\n";
+                        }
+                        catch (Tcl::tcl_error const &e)
+                        {
+std::cout << "3\n";
+                            TclThreadManager::getInstance().pushCommandBack("error Tcl error (thread " + getConvertedValue<unsigned int, std::string>(threadID) + "): " + e.what());
+                        }
+                        catch (std::exception const &e)
+                        {
+std::cout << "4\n";
+                            TclThreadManager::getInstance().pushCommandBack("error Error while executing tcl (thread " + getConvertedValue<unsigned int, std::string>(threadID) + "): " + e.what());
+                        }
+                        catch (...)
+                        {
+std::cout << "5\n";
+                            TclThreadManager::getInstance().pushCommandBack("error Error while executing tcl (thread " + getConvertedValue<unsigned int, std::string>(threadID) + ").");
+                        }
+                    }
+                }
+            }
+
+            while (TclThreadManager::getInstance().isEmpty(threadID))
+                boost::this_thread::yield();
+        }
+    }
+}
Index: code/branches/console/src/core/TclThreadManager.h
===================================================================
--- code/branches/console/src/core/TclThreadManager.h	(revision 1230)
+++ code/branches/console/src/core/TclThreadManager.h	(revision 1230)
@@ -0,0 +1,105 @@
+/*
+ *   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 _TclThreadManager_H__
+#define _TclThreadManager_H__
+
+#include <queue>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+#include "CorePrereqs.h"
+#include "Tickable.h"
+#include "cpptcl/CppTcl.h"
+
+namespace orxonox
+{
+    class boost::thread;
+
+    struct TclThread
+    {
+        Tcl::interpreter* interpreter_;
+        boost::thread* thread_;
+        boost::try_mutex* mutex_;
+    };
+
+    class _CoreExport TclThreadManager : public Tickable
+    {
+        public:
+            static TclThreadManager& getInstance();
+
+            static void tclthread(unsigned int threadID, const std::string& command);
+            static unsigned int create();
+            static void destroy(unsigned int threadID);
+            static void execute(unsigned int threadID, const std::string& command);
+            static std::string query(unsigned int threadID, const std::string& command);
+
+            static void tcl_execute(Tcl::object const &args);
+            static std::string tcl_orxonox(Tcl::object const &args);
+
+            Tcl::interpreter* createTclInterpreter(unsigned int threadID) const;
+            bool createTclThread();
+            bool destroyTclThread(unsigned int threadID);
+
+            void pushCommandBack(const std::string& command);
+            std::string popCommandFront();
+            bool isEmpty();
+
+            void pushCommandBack(unsigned int threadID, const std::string& command);
+            std::string popCommandFront(unsigned int threadID);
+            bool isEmpty(unsigned int threadID);
+
+            std::string eval(const std::string& command);
+            std::string eval(unsigned int threadID, const std::string& command);
+
+            virtual void tick(float dt);
+
+        private:
+            TclThreadManager();
+
+            bool isReady_;
+
+            unsigned int IDcount_;
+            std::map<unsigned int, TclThread> threads_;
+            std::map<unsigned int, std::queue<std::string> > threadQueues_;
+            std::queue<std::string> orxonoxQueue_;
+
+            boost::mutex orxonoxQueueMutex_;
+            boost::mutex threadQueuesMutex_;
+            boost::mutex threadsMutex_;
+            boost::mutex orxonoxEvalMutex_;
+
+            boost::condition orxonoxQueueCondition_;
+            boost::condition orxonoxEvalCondition_;
+    };
+
+    _CoreExport void tclThreadLoop(Tcl::interpreter* interpreter, boost::try_mutex* mutex, unsigned int threadID);
+}
+
+#endif /* _TclThreadManager_H__ */
Index: code/branches/console/src/cpptcl/CppTcl.cc
===================================================================
--- code/branches/console/src/cpptcl/CppTcl.cc	(revision 1229)
+++ code/branches/console/src/cpptcl/CppTcl.cc	(revision 1230)
