Index: /code/branches/releasetodo/data/gui/scripts/SingleplayerMenu.lua
===================================================================
--- /code/branches/releasetodo/data/gui/scripts/SingleplayerMenu.lua	(revision 7624)
+++ /code/branches/releasetodo/data/gui/scripts/SingleplayerMenu.lua	(revision 7625)
@@ -6,13 +6,10 @@
     listbox = winMgr:getWindow("orxonox/SingleplayerLevelListbox")
     preselect = orxonox.LevelManager:getInstance():getDefaultLevel()
-    orxonox.LevelManager:getInstance():compileAvailableLevelList()
+    size = orxonox.LevelManager:getInstance():getNumberOfLevels()
     local levelList = {}
     local index = 0
     local level = ""
-    while true do
+    while index < size do
       level = orxonox.LevelManager:getInstance():getAvailableLevelListItem(index)
-      if level == "" then
-        break
-      end
       table.insert(levelList, level)
       index = index + 1
Index: /code/branches/releasetodo/data/levels/empty_level.oxw
===================================================================
--- /code/branches/releasetodo/data/levels/empty_level.oxw	(revision 7624)
+++ /code/branches/releasetodo/data/levels/empty_level.oxw	(revision 7625)
@@ -1,2 +1,8 @@
+<LevelInfo
+ name = "Empty level"
+ description = "A level with absolutely nothing in it."
+ tags = "test, empty"
+/>
+
 <?lua
   include("stats.oxo")
Index: /code/branches/releasetodo/data/levels/notifications.oxw
===================================================================
--- /code/branches/releasetodo/data/levels/notifications.oxw	(revision 7624)
+++ /code/branches/releasetodo/data/levels/notifications.oxw	(revision 7625)
@@ -1,2 +1,8 @@
+<LevelInfo
+ name = "Notifications showcase"
+ description = "Level to test and showcase notifications."
+ tags = "test, showcase, notifications"
+/>
+
 <?lua
   include("hudtemplates3.oxo")
@@ -5,10 +11,4 @@
   include("templates/lodinformation.oxt")
 ?>
-
-<LevelInfo
- name = "Notifications showcase"
- description = "Level to test and showcase notifications."
- tags = "test, showcase, notifications"
-/>
 
 <Level
Index: de/branches/releasetodo/src/orxonox/LevelInfo.cc
===================================================================
--- /code/branches/releasetodo/src/orxonox/LevelInfo.cc	(revision 7624)
+++ 	(revision )
@@ -1,89 +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:
- *      Damian 'Mozork' Frick
- *   Co-authors:
- *      ...
- *
- */
-
-#include "LevelInfo.h"
-
-#include <sstream>
-#include <vector>
-
-#include "util/SubString.h"
-#include "core/CoreIncludes.h"
-#include "core/XMLPort.h"
-
-#include "LevelManager.h"
-
-namespace orxonox
-{
-    CreateFactory(LevelInfo);
-
-    LevelInfo::LevelInfo(BaseObject* creator) : BaseObject(creator)
-    {
-        RegisterObject(LevelInfo);
-
-    }
-
-    LevelInfo::~LevelInfo()
-    {
-        
-    }
-
-    void LevelInfo::XMLPort(Element& xmlelement, XMLPort::Mode mode)
-    {
-        SUPER(LevelInfo, XMLPort, xmlelement, mode);
-
-        XMLPortParam(LevelInfo, "description", setDescription, getDescription, xmlelement, mode);
-        XMLPortParam(LevelInfo, "tags", setTags, getTags, xmlelement, mode).defaultValues("");
-    }
-    
-    void LevelInfo::setTags(const std::string& tags)
-    {
-        const std::vector<std::string>& strings = SubString(tags, ",", " ").getAllStrings();
-        for(std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); it++)
-            this->addTag(*it);
-            
-        this->tagsUpdated();
-    }
-    
-    void LevelInfo::tagsUpdated(void)
-    {
-        std::stringstream stream;
-        std::set<std::string>::const_iterator temp;
-        for(std::set<std::string>::const_iterator it = this->tags_.begin(); it != this->tags_.end(); )
-        {
-            temp = it;
-            if(++it == this->tags_.end()) // If this is the last tag.
-                stream << *temp;
-            else
-                stream << *temp << ", ";
-        }
-            
-        this->tagsString_ = stream.str();
-    }
-    
-}
-    
Index: /code/branches/releasetodo/src/orxonox/LevelInfo.h
===================================================================
--- /code/branches/releasetodo/src/orxonox/LevelInfo.h	(revision 7624)
+++ /code/branches/releasetodo/src/orxonox/LevelInfo.h	(revision 7625)
@@ -27,4 +27,10 @@
  */
 
+/**
+    @file LevelInfo.h
+    @brief Definition of the LevelInfo and LevelInfoItem class.
+    @ingroup Orxonox
+*/
+
 #ifndef _LevelInfo_H__
 #define _LevelInfo_H__
@@ -34,39 +40,153 @@
 #include <set>
 #include <string>
+
 #include "core/BaseObject.h"
+#include "core/OrxonoxClass.h"
 
-namespace orxonox // tolua_export
-{  // tolua_export
-    class _OrxonoxExport LevelInfo  // tolua_export
-        : public BaseObject
-    { // tolua_export
-    
+namespace orxonox
+{
+
+    /**
+    @brief
+        The LevelInfoItem class stores information regarding a @ref orxonox::Level "Level" and makes that information it accessible trough the @ref orxonox::LevelManager "LevelManager".
+        A LevelInfoItem object is commonly created from a @ref orxonox::LevelInfo "LevelInfo" object, using its <code>copy()</code> method.
+
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport LevelInfoItem : virtual public OrxonoxClass
+    {
+        public:
+            LevelInfoItem(); //!< Default constructor.
+            LevelInfoItem(const std::string& name, const std::string filename); //!< Constructor. Initializes the object.
+            virtual ~LevelInfoItem(); //!< Destructor.
+
+            /**
+            @brief Set the name of the Level.
+            @param name The name to be set.
+            */
+            inline void setName(const std::string& name)
+                { this->name_ = std::string(name); }
+            /**
+            @brief Get the name of the Level.
+            @return Returns the name of the Level.
+            */
+            inline const std::string& getName(void)
+                { return this->name_; }
+
+            /**
+            @brief Set the description of the Level.
+            @param description The description to be set.
+            */
+            inline void setDescription(const std::string& description)
+                { this->description_ = std::string(description); }
+            /**
+            @brief Get the description of the Level.
+            @return Returns the description of the Level.
+            */
+            inline const std::string& getDescription() const
+                { return this->description_; }
+
+            void setTags(const std::string& tags); //!< Set the tags the Level is tagged with.
+            bool addTag(const std::string& tag, bool update = true); //!< Add a tag to the set of tags the Level is tagged with.
+            /**
+            @brief Get the lis of the tags the Level is tagged with.
+            @return Returns a comma-seperated string of all the tags the Level is tagged with.
+            */
+            inline const std::string& getTags(void) const
+                { return this->tagsString_; }
+            /**
+            @brief Get whether the Level has a specific tag.
+            @param tag The tag for which is checked.
+            @return Returns true if the Level is tagged with the input tag.
+            */
+            bool hasTag(const std::string& tag) const
+                { return this->tags_.find(tag) != this->tags_.end(); }
+
+            /**
+            @brief Get the XML-filename of the Level.
+            @return Returns the XML-filename (including *.oxw extension) of the Level.
+            */
+            inline const std::string& getXMLFilename(void)
+                { return this->xmlfilename_; }
+
+        protected:
+            /**
+            @brief Set the XML-filename of the Level.
+            @param filename The XML-filename to be set.
+            */
+            inline void setXMLFilename(const std::string& filename)
+                { this->xmlfilename_ = std::string(filename); }
+
+            std::string xmlfilename_; //!< The XML-filename of the Level.
+
+        private:
+            void tagsUpdated(void); //!< Updates the comma-seperated string of all tags, if the set of tags has changed.
+
+            std::string name_; //!< The name of the Level.
+            std::string description_; //!< The description of the Level.
+            std::set<std::string> tags_; //!< The set of tags the Level is tagged with.
+            std::string tagsString_; //!< The comma-seperated string of all the tags the Level is tagged with.
+    };
+
+    /**
+    @brief
+        The LevelInfo class can be used to store information regarding a @ref orxonox::Level "Level" in its level file.
+        The following parameters can be specified:
+        - @b name The name of the level.
+        - @b description The description of the level.
+        - @b tags A comma-seperated string of tags.
+
+        An example would be:
+        @code
+        <LevelInfo
+            name = "Levelname"
+            description = "This is just some awesome level."
+            tags = "test, awesome"
+        />
+        @endcode
+        The LevelInfo is best located at the top of the level file.
+
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport LevelInfo : public BaseObject, public LevelInfoItem
+    {
         public:
             LevelInfo(BaseObject* creator);
             virtual ~LevelInfo();
-            
-            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
 
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Creates a LevelInfo object through XML.
+
+            /**
+            @brief Set the description of the Level.
+            @param description The description to be set.
+            */
             inline void setDescription(const std::string& description)
-                { this->description_ = description; }
-            inline const std::string& getDescription() const // tolua_export
-                { return this->description_; }
-                
-            void setTags(const std::string& tags);
-            inline bool addTag(const std::string& tag)
-                { bool success = this->tags_.insert(tag).second; if(success) this->tagsUpdated(); return success; }
+                { this->LevelInfoItem::setDescription(description); }
+            /**
+            @brief Get the description of the Level.
+            @return Returns the description of the Level.
+            */
+            inline const std::string& getDescription() const
+                { return this->LevelInfoItem::getDescription(); }
+
+            /**
+            @brief Set the tags the Level is tagged with.
+            @param tags A comma-seperated string of all the tags to be set.
+            */
+            inline void setTags(const std::string& tags)
+                { this->LevelInfoItem::setTags(tags); }
+            /**
+            @brief Get the lis of the tags the Level is tagged with.
+            @return Returns a comma-seperated string of all the tags the Level is tagged with.
+            */
             inline const std::string& getTags(void) const
-                { return this->tagsString_; }
-            bool hasTag(const std::string& tag) { return this->tags_.find(tag) != this->tags_.end(); } // tolua_export
-            
-        private:
-            void tagsUpdated(void);
-        
-            std::string description_;
-            std::set<std::string> tags_;
-            std::string tagsString_;
-            
-    }; // tolua_export
-} // tolua_export
+                { return this->LevelInfoItem::getTags(); }
 
-#endif /* _Level_H__ */
+            LevelInfoItem* copy(void); //!< Copies the contents of this LevelInfo object to a new LevelInfoItem object.
+
+    };
+}
+
+#endif /* _LevelInfo_H__ */
Index: /code/branches/releasetodo/src/orxonox/LevelManager.cc
===================================================================
--- /code/branches/releasetodo/src/orxonox/LevelManager.cc	(revision 7624)
+++ /code/branches/releasetodo/src/orxonox/LevelManager.cc	(revision 7625)
@@ -59,4 +59,6 @@
             ModifyConfigValue(defaultLevelName_, tset, CommandLineParser::getValue("level").getString());
         }
+
+        this->compileAvailableLevelList();
     }
 
@@ -128,22 +130,38 @@
     }
 
+    unsigned int LevelManager::getNumberOfLevels()
+    {
+        this->updateAvailableLevelList();
+
+        COUT(0) << "Number of Levels: " << this->infos_.size() << std::endl;
+
+        return this->availableLevels_.size();
+    }
+
     const std::string& LevelManager::getAvailableLevelListItem(unsigned int index) const
     {
-        if (index >= availableLevels_.size())
+        if (index >= this->availableLevels_.size())
             return BLANKSTRING;
         else
-            return availableLevels_[index];
+        {
+            std::map<std::string, LevelInfoItem*>::const_iterator it = this->infos_.find(this->availableLevels_[index]);
+            assert(it->second);
+            return it->second->getName();
+        }
     }
 
     void LevelManager::compileAvailableLevelList()
     {
-        this->availableLevels_.clear();
         Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
+        // Iterate over all *.oxw level files.
         for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
         {
+            //TODO: Replace with tag,
             if (it->find("old/") != 0)
             {
                 size_t pos = it->find(".oxw");
-                COUT(0) << *it << std::endl;
+
+                bool infoExists = false;
+                // Load the LevelInfo object from the level file.
                 XMLFile file = XMLFile(*it);
                 ClassTreeMask mask = ClassTreeMask();
@@ -151,9 +169,28 @@
                 mask.include(ClassIdentifier<LevelInfo>::getIdentifier());
                 Loader::load(&file, mask);
-                
+                for(ObjectList<LevelInfo>::iterator item = ObjectList<LevelInfo>::begin(); item != ObjectList<LevelInfo>::end(); ++item)
+                {
+                    LevelInfoItem* info = item->copy();
+                    COUT(0) << "BUUUUUUUUUH: " << info->getName() << " | " << info->getXMLFilename() << " | " << it->substr(0, pos) << std::endl;
+                    if(info->getXMLFilename() == *it)
+                    {
+                        this->infos_.insert(std::pair<std::string, LevelInfoItem*>(it->substr(0, pos),info));
+                        infoExists = true;
+                    }
+                }
+                Loader::unload(&file, mask);
+                if(!infoExists)
+                {
+                    this->infos_.insert(std::pair<std::string, LevelInfoItem*>(it->substr(0, pos), new LevelInfoItem(it->substr(0, pos), *it)));
+                }
+
                 this->availableLevels_.push_back(it->substr(0, pos));
             }
         }
+    }
 
+    void LevelManager::updateAvailableLevelList(void)
+    {
+        //TODO: Implement some kind of update?
     }
 }
Index: /code/branches/releasetodo/src/orxonox/LevelManager.h
===================================================================
--- /code/branches/releasetodo/src/orxonox/LevelManager.h	(revision 7624)
+++ /code/branches/releasetodo/src/orxonox/LevelManager.h	(revision 7625)
@@ -34,4 +34,5 @@
 #include <cassert>
 #include <list>
+#include <map>
 #include <string>
 
@@ -59,5 +60,5 @@
             void setDefaultLevel(const std::string& levelName); //tolua_export
             const std::string& getDefaultLevel() const; //tolua_export
-            void compileAvailableLevelList(); //tolua_export
+            unsigned int getNumberOfLevels(void); //tolua_export
             const std::string& getAvailableLevelListItem(unsigned int index) const; //tolua_export
 
@@ -69,6 +70,10 @@
             void activateNextLevel();
 
+            void compileAvailableLevelList(void);
+            void updateAvailableLevelList(void);
+
             std::list<Level*> levels_s;
             std::vector<std::string> availableLevels_;
+            std::map<std::string, LevelInfoItem*> infos_;
 
             // config values
Index: /code/branches/releasetodo/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- /code/branches/releasetodo/src/orxonox/OrxonoxPrereqs.h	(revision 7624)
+++ /code/branches/releasetodo/src/orxonox/OrxonoxPrereqs.h	(revision 7625)
@@ -68,4 +68,5 @@
     class Level;
     class LevelInfo;
+    class LevelInfoItem;
     class LevelManager;
     class PawnManager;
