Index: code/branches/console/src/core/CMakeLists.txt
===================================================================
--- code/branches/console/src/core/CMakeLists.txt	(revision 1312)
+++ code/branches/console/src/core/CMakeLists.txt	(revision 1313)
@@ -18,4 +18,5 @@
   InputBuffer.cc
   CommandExecutor.cc
+  Shell.cc
   Language.cc
   ClassTreeMask.cc
Index: code/branches/console/src/core/ClassManager.h
===================================================================
--- code/branches/console/src/core/ClassManager.h	(revision 1312)
+++ code/branches/console/src/core/ClassManager.h	(revision 1313)
@@ -49,4 +49,5 @@
 #include "Identifier.h"
 #include "IdentifierDistributor.h"
+#include "Debug.h"
 
 namespace orxonox
Index: code/branches/console/src/core/ConfigValueContainer.cc
===================================================================
--- code/branches/console/src/core/ConfigValueContainer.cc	(revision 1312)
+++ code/branches/console/src/core/ConfigValueContainer.cc	(revision 1313)
@@ -123,4 +123,5 @@
             if (index < this->valueVector_.size())
             {
+                // Erase the entry from the vector, change (shift) all entries beginning with index in the config file, remove the last entry from the file
                 this->valueVector_.erase(this->valueVector_.begin() + index);
                 for (unsigned int i = index; i < this->valueVector_.size(); i++)
Index: code/branches/console/src/core/ConfigValueContainer.h
===================================================================
--- code/branches/console/src/core/ConfigValueContainer.h	(revision 1312)
+++ code/branches/console/src/core/ConfigValueContainer.h	(revision 1313)
@@ -107,4 +107,12 @@
             void update();
 
+            bool parse(const std::string& input);
+            bool parse(const std::string& input, const MultiTypeMath& defvalue);
+
+            bool set(unsigned int index, const std::string& input);
+            bool tset(unsigned int index, const std::string& input);
+            bool parse(unsigned int index, const std::string& input);
+            bool parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue);
+
             /** @brief Converts the config-value to a string. @return The string */
             inline std::string toString() const
@@ -115,12 +123,4 @@
 
         private:
-            bool parse(const std::string& input);
-            bool parse(const std::string& input, const MultiTypeMath& defvalue);
-
-            bool set(unsigned int index, const std::string& input);
-            bool tset(unsigned int index, const std::string& input);
-            bool parse(unsigned int index, const std::string& input);
-            bool parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue);
-
             bool                       bIsVector_;                  //!< True if the container contains a std::vector
 
Index: code/branches/console/src/core/CorePrereqs.h
===================================================================
--- code/branches/console/src/core/CorePrereqs.h	(revision 1312)
+++ code/branches/console/src/core/CorePrereqs.h	(revision 1313)
@@ -140,4 +140,5 @@
   class OutputHandler;
   class Shell;
+  class ShellListener;
   template <class T>
   class SubclassIdentifier;
Index: code/branches/console/src/core/Identifier.h
===================================================================
--- code/branches/console/src/core/Identifier.h	(revision 1312)
+++ code/branches/console/src/core/Identifier.h	(revision 1313)
@@ -63,4 +63,5 @@
 #include "Debug.h"
 #include "Iterator.h"
+#include "MetaObjectList.h"
 #include "util/String.h"
 
Index: code/branches/console/src/core/InputBuffer.cc
===================================================================
--- code/branches/console/src/core/InputBuffer.cc	(revision 1312)
+++ code/branches/console/src/core/InputBuffer.cc	(revision 1313)
@@ -45,4 +45,5 @@
         this->keyboard_ = InputManager::getSingleton().getKeyboard();
         this->buffer_ = "";
+        this->cursor_ = 0;
     }
 
@@ -52,42 +53,80 @@
         this->keyboard_ = InputManager::getSingleton().getKeyboard();
         this->buffer_ = "";
-    }
-
-    void InputBuffer::set(const std::string& input)
+        this->cursor_ = 0;
+    }
+
+    void InputBuffer::unregisterListener(InputBufferListener* listener)
+    {
+        for (std::list<InputBufferListenerTuple>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+        {
+            if ((*it).listener_ == listener)
+                this->listeners_.erase(it++);
+            else
+                ++it;
+        }
+    }
+
+    void InputBuffer::set(const std::string& input, bool update)
+    {
+        this->clear(false);
+        this->insert(input, update);
+    }
+
+    void InputBuffer::insert(const std::string& input, bool update)
+    {
+        for (unsigned int i = 0; i < input.size(); ++i)
+        {
+            this->insert(input[i], false);
+
+            if (update)
+                this->updated(input[i], false);
+        }
+
+        if (update)
+            this->updated();
+    }
+
+    void InputBuffer::insert(const char& input, bool update)
+    {
+        if (this->charIsAllowed(input))
+        {
+            this->buffer_.insert(this->cursor_, 1, input);
+            ++this->cursor_;
+        }
+
+        if (update)
+            this->updated(input, true);
+    }
+
+    void InputBuffer::clear(bool update)
     {
         this->buffer_ = "";
-        this->append(input);
-    }
-
-    void InputBuffer::append(const std::string& input)
-    {
-        for (unsigned int i = 0; i < input.size(); i++)
-        {
-            if (this->charIsAllowed(input[i]))
-                this->buffer_ += input[i];
-
-            this->updated(input[i], false);
-        }
-        this->updated();
-    }
-
-    void InputBuffer::append(const char& input)
-    {
-        if (this->charIsAllowed(input))
-            this->buffer_ += input;
-
-        this->updated(input, true);
-    }
-
-    void InputBuffer::clear()
-    {
-        this->buffer_ = "";
-        this->updated();
-    }
-
-    void InputBuffer::removeLast()
-    {
-        this->buffer_ = this->buffer_.substr(0, this->buffer_.size() - 1);
-        this->updated();
+        this->cursor_ = 0;
+
+        if (update)
+            this->updated();
+    }
+
+    void InputBuffer::removeBehindCursor(bool update)
+    {
+        if (this->cursor_ > 0)
+        {
+            --this->cursor_;
+            this->buffer_.erase(this->cursor_, 1);
+
+            if (update)
+                this->updated();
+        }
+    }
+
+    void InputBuffer::removeAtCursor(bool update)
+    {
+        if (this->cursor_ < this->buffer_.size())
+        {
+            this->buffer_.erase(this->cursor_, 1);
+
+            if (update)
+                this->updated();
+        }
     }
 
@@ -130,5 +169,5 @@
             if (e.key == OIS::KC_V)
             {
-                this->append(fromClipboard());
+                this->insert(fromClipboard());
                 return true;
             }
@@ -149,5 +188,5 @@
             if (e.key == OIS::KC_INSERT)
             {
-                this->append(fromClipboard());
+                this->insert(fromClipboard());
                 return true;
             }
@@ -160,5 +199,5 @@
         }
 
-        this->append((char)e.text);
+        this->insert((char)e.text);
         return true;
     }
Index: code/branches/console/src/core/InputBuffer.h
===================================================================
--- code/branches/console/src/core/InputBuffer.h	(revision 1312)
+++ code/branches/console/src/core/InputBuffer.h	(revision 1313)
@@ -102,9 +102,12 @@
             }
 
-            void set(const std::string& input);
-            void append(const std::string& input);
-            void append(const char& input);
-            void removeLast();
-            void clear();
+            void unregisterListener(InputBufferListener* listener);
+
+            void set(const std::string& input, bool update = true);
+            void insert(const std::string& input, bool update = true);
+            void insert(const char& input, bool update = true);
+            void clear(bool update = true);
+            void removeAtCursor(bool update = true);
+            void removeBehindCursor(bool update = true);
 
             void updated();
@@ -113,4 +116,19 @@
             inline std::string get() const
                 { return this->buffer_; }
+            inline unsigned int getSize() const
+                { return this->buffer_.size(); }
+
+            inline unsigned int getCursorPosition() const
+                { return this->cursor_; }
+            inline void setCursorPosition(unsigned int cursor)
+                { if (cursor <= this->buffer_.size()) { this->cursor_ = cursor; } }
+            inline void setCursorToEnd()
+                { this->cursor_ = this->buffer_.size(); }
+            inline void setCursorToBegin()
+                { this->cursor_ = 0; }
+            inline void increaseCursor()
+                { if (this->cursor_ < this->buffer_.size()) { ++this->cursor_; } }
+            inline void decreaseCursor()
+                { if (this->cursor_ > 0) { --this->cursor_; } }
 
         private:
@@ -124,4 +142,5 @@
             std::list<InputBufferListenerTuple> listeners_;
             std::string allowedChars_;
+            unsigned int cursor_;
     };
 }
Index: code/branches/console/src/core/InputHandler.cc
===================================================================
--- code/branches/console/src/core/InputHandler.cc	(revision 1312)
+++ code/branches/console/src/core/InputHandler.cc	(revision 1313)
@@ -34,4 +34,5 @@
 #include "InputHandler.h"
 #include "Debug.h"
+#include "Iterator.h"
 #include "util/Convert.h"
 #include "InputEventListener.h"
Index: code/branches/console/src/core/Iterator.h
===================================================================
--- code/branches/console/src/core/Iterator.h	(revision 1312)
+++ code/branches/console/src/core/Iterator.h	(revision 1313)
@@ -50,5 +50,4 @@
 
 #include "ObjectList.h"
-#include "Debug.h"
 
 namespace orxonox
Index: code/branches/console/src/core/Language.cc
===================================================================
--- code/branches/console/src/core/Language.cc	(revision 1312)
+++ code/branches/console/src/core/Language.cc	(revision 1313)
@@ -37,4 +37,6 @@
 
 #include "CoreSettings.h"
+
+#include "Debug.h"
 
 namespace orxonox
Index: code/branches/console/src/core/Language.h
===================================================================
--- code/branches/console/src/core/Language.h	(revision 1312)
+++ code/branches/console/src/core/Language.h	(revision 1313)
@@ -50,5 +50,4 @@
 #include <map>
 #include <string>
-
 
 #define AddLanguageEntry(label, fallbackstring) \
Index: code/branches/console/src/core/OrxonoxClass.cc
===================================================================
--- code/branches/console/src/core/OrxonoxClass.cc	(revision 1312)
+++ code/branches/console/src/core/OrxonoxClass.cc	(revision 1313)
@@ -33,4 +33,6 @@
 
 #include "OrxonoxClass.h"
+#include "MetaObjectList.h"
+#include "Identifier.h"
 
 namespace orxonox
@@ -39,4 +41,6 @@
     OrxonoxClass::OrxonoxClass()
     {
+        this->metaList_ = new MetaObjectList();
+
         this->setConfigValues();
 
@@ -48,7 +52,88 @@
     OrxonoxClass::~OrxonoxClass()
     {
+        delete this->metaList_;
+
         // parents_ exists only if isCreatingHierarchy() of the associated Identifier returned true while creating the class
         if (this->parents_)
             delete this->parents_;
     }
+
+    /** @brief Returns true if the objects class is of the given type or a derivative. */
+    bool OrxonoxClass::isA(const Identifier* identifier)
+        { return this->getIdentifier()->isA(identifier); }
+    /** @brief Returns true if the objects class is exactly of the given type. */
+    bool OrxonoxClass::isExactlyA(const Identifier* identifier)
+        { return this->getIdentifier()->isExactlyA(identifier); }
+    /** @brief Returns true if the objects class is a child of the given type. */
+    bool OrxonoxClass::isChildOf(const Identifier* identifier)
+        { return this->getIdentifier()->isChildOf(identifier); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectChildOf(const Identifier* identifier)
+        { return this->getIdentifier()->isDirectChildOf(identifier); }
+    /** @brief Returns true if the objects class is a parent of the given type. */
+    bool OrxonoxClass::isParentOf(const Identifier* identifier)
+        { return this->getIdentifier()->isParentOf(identifier); }
+    /** @brief Returns true if the objects class is a direct parent of the given type. */
+    bool OrxonoxClass::isDirectParentOf(const Identifier* identifier)
+        { return this->getIdentifier()->isDirectParentOf(identifier); }
+
+
+    /** @brief Returns true if the objects class is of the given type or a derivative. */
+    bool OrxonoxClass::isA(const SubclassIdentifier<class B>* identifier)
+        { return this->getIdentifier()->isA(identifier->getIdentifier()); }
+    /** @brief Returns true if the objects class is exactly of the given type. */
+    bool OrxonoxClass::isExactlyA(const SubclassIdentifier<class B>* identifier)
+        { return this->getIdentifier()->isExactlyA(identifier->getIdentifier()); }
+    /** @brief Returns true if the objects class is a child of the given type. */
+    bool OrxonoxClass::isChildOf(const SubclassIdentifier<class B>* identifier)
+        { return this->getIdentifier()->isChildOf(identifier->getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<class B>* identifier)
+        { return this->getIdentifier()->isDirectChildOf(identifier->getIdentifier()); }
+    /** @brief Returns true if the objects class is a parent of the given type. */
+    bool OrxonoxClass::isParentOf(const SubclassIdentifier<class B>* identifier)
+        { return this->getIdentifier()->isParentOf(identifier->getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct parent of the given type. */
+    bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<class B>* identifier)
+        { return this->getIdentifier()->isDirectParentOf(identifier->getIdentifier()); }
+
+
+    /** @brief Returns true if the objects class is of the given type or a derivative. */
+    bool OrxonoxClass::isA(const SubclassIdentifier<class B> identifier)
+        { return this->getIdentifier()->isA(identifier.getIdentifier()); }
+    /** @brief Returns true if the objects class is exactly of the given type. */
+    bool OrxonoxClass::isExactlyA(const SubclassIdentifier<class B> identifier)
+        { return this->getIdentifier()->isExactlyA(identifier.getIdentifier()); }
+    /** @brief Returns true if the objects class is a child of the given type. */
+    bool OrxonoxClass::isChildOf(const SubclassIdentifier<class B> identifier)
+        { return this->getIdentifier()->isChildOf(identifier.getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<class B> identifier)
+        { return this->getIdentifier()->isDirectChildOf(identifier.getIdentifier()); }
+    /** @brief Returns true if the objects class is a parent of the given type. */
+    bool OrxonoxClass::isParentOf(const SubclassIdentifier<class B> identifier)
+        { return this->getIdentifier()->isParentOf(identifier.getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct parent of the given type. */
+    bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<class B> identifier)
+        { return this->getIdentifier()->isDirectParentOf(identifier.getIdentifier()); }
+
+
+    /** @brief Returns true if the objects class is of the given type or a derivative. */
+    bool OrxonoxClass::isA(const OrxonoxClass* object)
+        { return this->getIdentifier()->isA(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is exactly of the given type. */
+    bool OrxonoxClass::isExactlyA(const OrxonoxClass* object)
+        { return this->getIdentifier()->isExactlyA(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a child of the given type. */
+    bool OrxonoxClass::isChildOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isChildOf(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectChildOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isDirectChildOf(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a parent of the given type. */
+    bool OrxonoxClass::isParentOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isParentOf(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectParentOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isDirectParentOf(object->getIdentifier()); }
 }
Index: code/branches/console/src/core/OrxonoxClass.h
===================================================================
--- code/branches/console/src/core/OrxonoxClass.h	(revision 1312)
+++ code/branches/console/src/core/OrxonoxClass.h	(revision 1313)
@@ -43,7 +43,4 @@
 #include <string>
 
-#include "MetaObjectList.h"
-#include "Iterator.h"
-
 namespace orxonox
 {
@@ -75,90 +72,39 @@
 
             /** @brief Returns the MetaObjectList of the object, containing a link to all ObjectLists and ObjectListElements the object is registered in. @return The list */
-            inline MetaObjectList& getMetaList() { return this->metaList_; }
+            inline MetaObjectList& getMetaList() { return (*this->metaList_); }
 
 
-            /** @brief Returns true if the objects class is of the given type or a derivative. */
-            inline bool isA(const Identifier* identifier)
-                { return this->getIdentifier()->isA(identifier); }
-            /** @brief Returns true if the objects class is exactly of the given type. */
-            inline bool isExactlyA(const Identifier* identifier)
-                { return this->getIdentifier()->isExactlyA(identifier); }
-            /** @brief Returns true if the objects class is a child of the given type. */
-            inline bool isChildOf(const Identifier* identifier)
-                { return this->getIdentifier()->isChildOf(identifier); }
-            /** @brief Returns true if the objects class is a direct child of the given type. */
-            inline bool isDirectChildOf(const Identifier* identifier)
-                { return this->getIdentifier()->isDirectChildOf(identifier); }
-            /** @brief Returns true if the objects class is a parent of the given type. */
-            inline bool isParentOf(const Identifier* identifier)
-                { return this->getIdentifier()->isParentOf(identifier); }
-            /** @brief Returns true if the objects class is a direct parent of the given type. */
-            inline bool isDirectParentOf(const Identifier* identifier)
-                { return this->getIdentifier()->isDirectParentOf(identifier); }
+            bool isA(const Identifier* identifier);
+            bool isExactlyA(const Identifier* identifier);
+            bool isChildOf(const Identifier* identifier);
+            bool isDirectChildOf(const Identifier* identifier);
+            bool isParentOf(const Identifier* identifier);
+            bool isDirectParentOf(const Identifier* identifier);
 
+            bool isA(const SubclassIdentifier<class B>* identifier);
+            bool isExactlyA(const SubclassIdentifier<class B>* identifier);
+            bool isChildOf(const SubclassIdentifier<class B>* identifier);
+            bool isDirectChildOf(const SubclassIdentifier<class B>* identifier);
+            bool isParentOf(const SubclassIdentifier<class B>* identifier);
+            bool isDirectParentOf(const SubclassIdentifier<class B>* identifier);
 
-            /** @brief Returns true if the objects class is of the given type or a derivative. */
-            inline bool isA(const SubclassIdentifier<class B>* identifier)
-                { return this->getIdentifier()->isA(identifier->getIdentifier()); }
-            /** @brief Returns true if the objects class is exactly of the given type. */
-            inline bool isExactlyA(const SubclassIdentifier<class B>* identifier)
-                { return this->getIdentifier()->isExactlyA(identifier->getIdentifier()); }
-            /** @brief Returns true if the objects class is a child of the given type. */
-            inline bool isChildOf(const SubclassIdentifier<class B>* identifier)
-                { return this->getIdentifier()->isChildOf(identifier->getIdentifier()); }
-            /** @brief Returns true if the objects class is a direct child of the given type. */
-            inline bool isDirectChildOf(const SubclassIdentifier<class B>* identifier)
-                { return this->getIdentifier()->isDirectChildOf(identifier->getIdentifier()); }
-            /** @brief Returns true if the objects class is a parent of the given type. */
-            inline bool isParentOf(const SubclassIdentifier<class B>* identifier)
-                { return this->getIdentifier()->isParentOf(identifier->getIdentifier()); }
-            /** @brief Returns true if the objects class is a direct parent of the given type. */
-            inline bool isDirectParentOf(const SubclassIdentifier<class B>* identifier)
-                { return this->getIdentifier()->isDirectParentOf(identifier->getIdentifier()); }
+            bool isA(const SubclassIdentifier<class B> identifier);
+            bool isExactlyA(const SubclassIdentifier<class B> identifier);
+            bool isChildOf(const SubclassIdentifier<class B> identifier);
+            bool isDirectChildOf(const SubclassIdentifier<class B> identifier);
+            bool isParentOf(const SubclassIdentifier<class B> identifier);
+            bool isDirectParentOf(const SubclassIdentifier<class B> identifier);
 
-
-            /** @brief Returns true if the objects class is of the given type or a derivative. */
-            inline bool isA(const SubclassIdentifier<class B> identifier)
-                { return this->getIdentifier()->isA(identifier.getIdentifier()); }
-            /** @brief Returns true if the objects class is exactly of the given type. */
-            inline bool isExactlyA(const SubclassIdentifier<class B> identifier)
-                { return this->getIdentifier()->isExactlyA(identifier.getIdentifier()); }
-            /** @brief Returns true if the objects class is a child of the given type. */
-            inline bool isChildOf(const SubclassIdentifier<class B> identifier)
-                { return this->getIdentifier()->isChildOf(identifier.getIdentifier()); }
-            /** @brief Returns true if the objects class is a direct child of the given type. */
-            inline bool isDirectChildOf(const SubclassIdentifier<class B> identifier)
-                { return this->getIdentifier()->isDirectChildOf(identifier.getIdentifier()); }
-            /** @brief Returns true if the objects class is a parent of the given type. */
-            inline bool isParentOf(const SubclassIdentifier<class B> identifier)
-                { return this->getIdentifier()->isParentOf(identifier.getIdentifier()); }
-            /** @brief Returns true if the objects class is a direct parent of the given type. */
-            inline bool isDirectParentOf(const SubclassIdentifier<class B> identifier)
-                { return this->getIdentifier()->isDirectParentOf(identifier.getIdentifier()); }
-
-
-            /** @brief Returns true if the objects class is of the given type or a derivative. */
-            inline bool isA(const OrxonoxClass* object)
-                { return this->getIdentifier()->isA(object->getIdentifier()); }
-            /** @brief Returns true if the objects class is exactly of the given type. */
-            inline bool isExactlyA(const OrxonoxClass* object)
-                { return this->getIdentifier()->isExactlyA(object->getIdentifier()); }
-            /** @brief Returns true if the objects class is a child of the given type. */
-            inline bool isChildOf(const OrxonoxClass* object)
-                { return this->getIdentifier()->isChildOf(object->getIdentifier()); }
-            /** @brief Returns true if the objects class is a direct child of the given type. */
-            inline bool isDirectChildOf(const OrxonoxClass* object)
-                { return this->getIdentifier()->isDirectChildOf(object->getIdentifier()); }
-            /** @brief Returns true if the objects class is a parent of the given type. */
-            inline bool isParentOf(const OrxonoxClass* object)
-                { return this->getIdentifier()->isParentOf(object->getIdentifier()); }
-            /** @brief Returns true if the objects class is a direct child of the given type. */
-            inline bool isDirectParentOf(const OrxonoxClass* object)
-                { return this->getIdentifier()->isDirectParentOf(object->getIdentifier()); }
+            bool isA(const OrxonoxClass* object);
+            bool isExactlyA(const OrxonoxClass* object);
+            bool isChildOf(const OrxonoxClass* object);
+            bool isDirectChildOf(const OrxonoxClass* object);
+            bool isParentOf(const OrxonoxClass* object);
+            bool isDirectParentOf(const OrxonoxClass* object);
 
         private:
-            Identifier* identifier_;                    //!< The Identifier of the object
+            Identifier* identifier_;                   //!< The Identifier of the object
             std::set<const Identifier*>* parents_;     //!< List of all parents of the object
-            MetaObjectList metaList_;                   //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
+            MetaObjectList* metaList_;                 //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
     };
 }
Index: code/branches/console/src/core/OutputBuffer.cc
===================================================================
--- code/branches/console/src/core/OutputBuffer.cc	(revision 1312)
+++ code/branches/console/src/core/OutputBuffer.cc	(revision 1313)
@@ -33,20 +33,18 @@
 namespace orxonox
 {
-    OutputBuffer& OutputBuffer::getOutputBuffer()
-    {
-        static OutputBuffer instance;
-        return instance;
-    }
-
     void OutputBuffer::registerListener(OutputBufferListener* listener)
     {
-        this->listeners_.insert(listener);
+        this->listeners_.insert(this->listeners_.end(), listener);
     }
 
     void OutputBuffer::unregisterListener(OutputBufferListener* listener)
     {
-        std::set<OutputBufferListener*>::iterator it = this->listeners_.find(listener);
-        if (it != this->listeners_.end())
-            this->listeners_.erase(it);
+        for (std::list<OutputBufferListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+        {
+            if ((*it) == listener)
+                this->listeners_.erase(it++);
+            else
+                ++it;
+        }
     }
 
@@ -63,4 +61,5 @@
             this->stream_.flush();
 
+        // Return true if this was a whole new line, ended by \n
         return (!eof);
     }
@@ -68,6 +67,6 @@
     void OutputBuffer::callListeners()
     {
-        for (std::set<OutputBufferListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
-            (*it)->bufferChanged();
+        for (std::list<OutputBufferListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+            (*it)->outputChanged();
     }
 }
Index: code/branches/console/src/core/OutputBuffer.h
===================================================================
--- code/branches/console/src/core/OutputBuffer.h	(revision 1312)
+++ code/branches/console/src/core/OutputBuffer.h	(revision 1313)
@@ -30,5 +30,5 @@
 #define _OutputBuffer_H__
 
-#include <set>
+#include <list>
 #include <sstream>
 
@@ -37,7 +37,8 @@
 namespace orxonox
 {
-    class OutputBufferListener
+    class _CoreExport OutputBufferListener
     {
         friend class OutputBuffer;
+
         virtual void outputChanged() = 0;
     };
@@ -46,5 +47,6 @@
     {
         public:
-            static OutputBuffer& getOutputBuffer();
+            OutputBuffer() {}
+            ~OutputBuffer() {}
 
             template <class T>
@@ -53,5 +55,5 @@
                 this->stream_ << object;
                 this->callListeners();
-                return &this;
+                return *this;
             }
 
@@ -86,13 +88,14 @@
             void unregisterListener(OutputBufferListener* listener);
 
+            inline operator std::stringstream&()
+            {
+                return this->stream_;
+            }
+
         private:
-            OutputBuffer() {}
-            OutputBuffer(const OutputBuffer& other);
-            ~OutputBuffer() {}
-
             void callListeners();
 
             std::stringstream stream_;
-            std::set<OutputBufferListener*> listeners_;
+            std::list<OutputBufferListener*> listeners_;
     };
 }
Index: code/branches/console/src/core/OutputHandler.cc
===================================================================
--- code/branches/console/src/core/OutputHandler.cc	(revision 1312)
+++ code/branches/console/src/core/OutputHandler.cc	(revision 1313)
@@ -101,4 +101,7 @@
         }
 
+        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
+            Shell::getInstance().getOutputBuffer() << sb;
+
         return *this;
     }
@@ -119,4 +122,7 @@
             this->logfile_.flush();
         }
+
+        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
+            manipulator(Shell::getInstance().getOutputBuffer());
 
         return *this;
@@ -139,4 +145,7 @@
         }
 
+        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
+            manipulator(Shell::getInstance().getOutputBuffer());
+
         return *this;
     }
@@ -158,4 +167,7 @@
         }
 
+        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
+            manipulator(Shell::getInstance().getOutputBuffer());
+
         return *this;
     }
Index: code/branches/console/src/core/OutputHandler.h
===================================================================
--- code/branches/console/src/core/OutputHandler.h	(revision 1312)
+++ code/branches/console/src/core/OutputHandler.h	(revision 1313)
@@ -43,4 +43,6 @@
 #include <fstream>
 #include <string>
+
+#include "Shell.h"
 
 namespace orxonox
@@ -154,4 +156,7 @@
         }
 
+        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
+            Shell::getInstance().getOutputBuffer() << output;
+
         return *this;
     }
@@ -175,4 +180,7 @@
         }
 
+        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= out.getOutputLevel())
+            Shell::getInstance().getOutputBuffer() << output;
+
         return out;
     }
Index: code/branches/console/src/core/Shell.cc
===================================================================
--- code/branches/console/src/core/Shell.cc	(revision 1312)
+++ code/branches/console/src/core/Shell.cc	(revision 1313)
@@ -27,9 +27,12 @@
  */
 
-#include "CorePrereqs.h"
-
-#include "OrxonoxClass.h"
-#include "InputBuffer.h"
-#include "OutputBuffer.h"
+#include "Shell.h"
+#include "CommandExecutor.h"
+#include "CoreIncludes.h"
+#include "ConfigValueIncludes.h"
+
+#define SHELL_UPDATE_LISTENERS(function) \
+    for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) \
+        (*it)->function()
 
 namespace orxonox
@@ -37,38 +40,267 @@
     Shell::Shell()
     {
+        RegisterRootObject(Shell);
+
+        this->scrollPosition_ = 0;
+        this->maxHistoryLength_ = 100;
+        this->historyPosition_ = 0;
+        this->historyOffset_ = 0;
+
+        this->clearLines();
+
         this->inputBuffer_.registerListener(this, &Shell::inputChanged, true);
         this->inputBuffer_.registerListener(this, &Shell::execute, '\r', false);
         this->inputBuffer_.registerListener(this, &Shell::hintandcomplete, '\t', true);
-        this->inputBuffer_.registerListener(this, &Shell::clear, '§', true);
         this->inputBuffer_.registerListener(this, &Shell::backspace, '\b', true);
+        this->inputBuffer_.registerListener(this, &Shell::deletechar, OIS::KC_DELETE);
         this->inputBuffer_.registerListener(this, &Shell::exit, (char)27, true);
         this->inputBuffer_.registerListener(this, &Shell::cursor_right, OIS::KC_RIGHT);
         this->inputBuffer_.registerListener(this, &Shell::cursor_left, OIS::KC_LEFT);
+        this->inputBuffer_.registerListener(this, &Shell::cursor_end, OIS::KC_END);
+        this->inputBuffer_.registerListener(this, &Shell::cursor_home, OIS::KC_HOME);
         this->inputBuffer_.registerListener(this, &Shell::history_up, OIS::KC_UP);
         this->inputBuffer_.registerListener(this, &Shell::history_down, OIS::KC_DOWN);
         this->inputBuffer_.registerListener(this, &Shell::scroll_up, OIS::KC_PGUP);
         this->inputBuffer_.registerListener(this, &Shell::scroll_down, OIS::KC_PGDOWN);
+
+        this->setConfigValues();
     }
 
     Shell& Shell::getInstance()
     {
-        static instance Shell;
+        static Shell instance;
         return instance;
     }
 
     void Shell::setConfigValues()
+    {
+        SetConfigValue(maxHistoryLength_, 100);
+        SetConfigValue(historyOffset_, 0);
+        SetConfigValueVector(commandHistory_, std::vector<std::string>(1, ""));
+
+        if (this->historyOffset_ >= this->maxHistoryLength_)
+            this->historyOffset_ = 0;
+
+        while (this->commandHistory_.size() > this->maxHistoryLength_)
+        {
+            unsigned int index = this->commandHistory_.size() - 1;
+            this->commandHistory_.erase(this->commandHistory_.begin() + index);
+            ModifyConfigValue(commandHistory_, remove, index);
+        }
+    }
+
+    void Shell::registerListener(ShellListener* listener)
+    {
+        this->listeners_.insert(this->listeners_.end(), listener);
+    }
+
+    void Shell::unregisterListener(ShellListener* listener)
+    {
+        for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+        {
+            if ((*it) == listener)
+                this->listeners_.erase(it++);
+            else
+                ++it;
+        }
+    }
+
+    void Shell::setCursorPosition(unsigned int cursor)
+    {
+        this->inputBuffer_.setCursorPosition(cursor);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::setInput(const std::string& input)
+    {
+        this->inputBuffer_.set(input);
+        this->inputChanged();
+    }
+
+    void Shell::addLine(const std::string& line, unsigned int level)
+    {
+        if ((*this->lines_.begin()) != "")
+        {
+            orxonox::OutputHandler::getOutStream().setOutputLevel(level) << std::endl;
+        }
+        orxonox::OutputHandler::getOutStream().setOutputLevel(level) << line << std::endl;
+    }
+
+    void Shell::clearLines()
+    {
+        this->lines_.clear();
+        this->lines_.insert(this->lines_.begin(), "");
+        this->scrollIterator_ = this->lines_.begin();
+
+        this->scrollPosition_ = 0;
+
+        SHELL_UPDATE_LISTENERS(linesChanged);
+    }
+
+    std::list<std::string>::const_iterator Shell::getNewestLineIterator() const
+    {
+        if (this->scrollPosition_)
+            return this->scrollIterator_;
+        else
+            return this->lines_.begin();
+    }
+
+    std::list<std::string>::const_iterator Shell::getEndIterator() const
+    {
+        return this->lines_.end();
+    }
+
+    void Shell::addToHistory(const std::string& command)
+    {
+        this->historyOffset_ = (this->historyOffset_ + 1) % this->maxHistoryLength_;
+        ModifyConfigValue(commandHistory_, set, this->historyOffset_, command);
+        this->commandHistory_[this->historyOffset_] = command;
+        this->historyPosition_ = 0;
+    }
+
+    std::string Shell::getFromHistory() const
+    {
+        return this->commandHistory_[(this->historyOffset_ - this->historyPosition_) % this->maxHistoryLength_];
+    }
 
     void Shell::outputChanged()
+    {
+        std::string output;
+        while (this->outputBuffer_.getLine(&output))
+        {
+            (*this->lines_.begin()) += output;
+            this->lines_.insert(this->lines_.begin(), "");
+
+            if (this->scrollPosition_)
+                this->scrollPosition_++;
+            else
+                this->scrollIterator_ = this->lines_.begin();
+
+            SHELL_UPDATE_LISTENERS(linesChanged);
+            SHELL_UPDATE_LISTENERS(lineAdded);
+        }
+
+        (*this->lines_.begin()) += output;
+        SHELL_UPDATE_LISTENERS(onlyLastLineChanged);
+    }
+
     void Shell::inputChanged()
+    {
+        SHELL_UPDATE_LISTENERS(inputChanged);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
     void Shell::execute()
+    {
+        if (CommandExecutor::execute(this->inputBuffer_.get()))
+            this->addLine(this->inputBuffer_.get(), 0);
+        else
+            this->addLine("Error: Can't execute \"" + this->inputBuffer_.get() + "\".", 1);
+
+        this->clear();
+    }
+
     void Shell::hintandcomplete()
+    {
+        this->addLine(CommandExecutor::hint(this->inputBuffer_.get()), 0);
+        this->inputBuffer_.set(CommandExecutor::complete(this->inputBuffer_.get()));
+
+        this->inputChanged();
+    }
+
     void Shell::backspace()
+    {
+        this->inputBuffer_.removeBehindCursor();
+        SHELL_UPDATE_LISTENERS(inputChanged);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::deletechar()
+    {
+        this->inputBuffer_.removeAtCursor();
+        SHELL_UPDATE_LISTENERS(inputChanged);
+    }
+
     void Shell::clear()
+    {
+        this->inputBuffer_.clear();
+        SHELL_UPDATE_LISTENERS(inputChanged);
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
     void Shell::cursor_right()
+    {
+        this->inputBuffer_.increaseCursor();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
     void Shell::cursor_left()
+    {
+        this->inputBuffer_.decreaseCursor();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::cursor_end()
+    {
+        this->inputBuffer_.setCursorToEnd();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
+    void Shell::cursor_home()
+    {
+        this->inputBuffer_.setCursorToBegin();
+        SHELL_UPDATE_LISTENERS(cursorChanged);
+    }
+
     void Shell::history_up()
+    {
+        if (this->historyPosition_ < (this->commandHistory_.size() - 1))
+        {
+            this->historyPosition_++;
+            this->inputBuffer_.set(this->getFromHistory());
+        }
+    }
+
     void Shell::history_down()
+    {
+        if (this->historyPosition_ > 0)
+        {
+            this->historyPosition_++;
+            this->inputBuffer_.set(this->getFromHistory());
+        }
+    }
+
     void Shell::scroll_up()
+    {
+        if (this->scrollIterator_ != this->lines_.end())
+        {
+            ++this->scrollIterator_;
+            ++this->scrollPosition_;
+
+            SHELL_UPDATE_LISTENERS(linesChanged);
+        }
+    }
+
     void Shell::scroll_down()
+    {
+        if (this->scrollIterator_ != this->lines_.begin())
+        {
+            --this->scrollIterator_;
+            --this->scrollPosition_;
+
+            SHELL_UPDATE_LISTENERS(linesChanged);
+        }
+    }
+
     void Shell::exit()
+    {
+        if (this->inputBuffer_.getSize() > 0)
+        {
+            this->clear();
+            return;
+        }
+
+        this->clear();
+        SHELL_UPDATE_LISTENERS(exit);
+    }
 }
Index: code/branches/console/src/core/Shell.h
===================================================================
--- code/branches/console/src/core/Shell.h	(revision 1312)
+++ code/branches/console/src/core/Shell.h	(revision 1313)
@@ -30,4 +30,7 @@
 #define _Shell_H__
 
+#include <list>
+#include <vector>
+
 #include "CorePrereqs.h"
 
@@ -38,11 +41,15 @@
 namespace orxonox
 {
-    class ShellListener
+    class _CoreExport ShellListener
     {
-        virtual void outputChanged() = 0;
-        virtual void lastLineChanged() = 0;
-        virtual void inputChanged() = 0;
-        virtual void exit() = 0;
-    }
+        friend class Shell;
+
+        virtual void linesChanged() {}
+        virtual void onlyLastLineChanged() {}
+        virtual void lineAdded() {}
+        virtual void inputChanged() {}
+        virtual void cursorChanged() {}
+        virtual void exit() {}
+    };
 
     class _CoreExport Shell : virtual public OrxonoxClass, public InputBufferListener, public OutputBufferListener
@@ -53,8 +60,41 @@
             virtual void setConfigValues();
 
+            void registerListener(ShellListener* listener);
+            void unregisterListener(ShellListener* listener);
+
+            inline InputBuffer& getInputBuffer()
+                { return this->inputBuffer_; }
+            inline OutputBuffer& getOutputBuffer()
+                { return this->outputBuffer_; }
+
+            void setCursorPosition(unsigned int cursor);
+            inline unsigned int getCursorPosition() const
+                { return this->inputBuffer_.getCursorPosition(); }
+
+            void setInput(const std::string& input);
+
+            inline void clearInput()
+                { this->setInput(""); }
+            inline std::string getInput() const
+                { return this->inputBuffer_.get(); }
+
+            inline std::list<std::string>::const_iterator getNewestLineIterator() const;
+            inline std::list<std::string>::const_iterator getEndIterator() const;
+
+            void addLine(const std::string& line, unsigned int level);
+            void clearLines();
+
+            inline unsigned int getNumLines() const
+                { return this->lines_.size(); }
+            inline unsigned int getScrollPosition() const
+                { return this->scrollPosition_; }
+
         private:
             Shell();
             Shell(const Shell& other);
-            ~Shell() {}
+            virtual ~Shell() {}
+
+            void addToHistory(const std::string& command);
+            std::string getFromHistory() const;
 
             virtual void outputChanged();
@@ -63,6 +103,10 @@
             void hintandcomplete();
             void backspace();
+            void deletechar();
+            void clear();
             void cursor_right();
             void cursor_left();
+            void cursor_end();
+            void cursor_home();
             void history_up();
             void history_down();
@@ -71,10 +115,14 @@
             void exit();
 
+            std::list<ShellListener*> listeners_;
             InputBuffer inputBuffer_;
-            OutputBuffer OutputBuffer_;
+            OutputBuffer outputBuffer_;
             std::list<std::string> lines_;
-            unsigned int cursor_;
+            std::list<std::string>::const_iterator scrollIterator_;
+            unsigned int scrollPosition_;
             std::vector<std::string> commandHistory_;
             unsigned int maxHistoryLength_;
+            unsigned int historyPosition_;
+            unsigned int historyOffset_;
     };
 }
