Index: code/trunk/cmake/tools/TargetUtilities.cmake
===================================================================
--- code/trunk/cmake/tools/TargetUtilities.cmake	(revision 8078)
+++ code/trunk/cmake/tools/TargetUtilities.cmake	(revision 8079)
@@ -266,5 +266,5 @@
     ADD_MODULE(${_target_name})
     # Ensure that the main program depends on the module
-    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE STRING "" FORCE)
+    SET(ORXONOX_MODULES ${ORXONOX_MODULES} ${_target_name} CACHE INTERNAL "")
   ENDIF()
 
Index: code/trunk/data/defaultConfig/keybindings.ini
===================================================================
--- code/trunk/data/defaultConfig/keybindings.ini	(revision 8078)
+++ code/trunk/data/defaultConfig/keybindings.ini	(revision 8079)
@@ -42,5 +42,5 @@
 KeyF9=
 KeyG=greet
-KeyGrave="openConsole"
+KeyGrave="InGameConsole openConsole"
 KeyH=
 KeyHome=
@@ -127,5 +127,5 @@
 KeyU=""
 KeyUP="scale 1 moveFrontBack"
-KeyUnassigned="openConsole"
+KeyUnassigned="InGameConsole openConsole"
 KeyUnderline=
 KeyUnlabeled=
Index: code/trunk/data/gui/configs/CEGUIConfig.xsd
===================================================================
--- code/trunk/data/gui/configs/CEGUIConfig.xsd	(revision 8078)
+++ code/trunk/data/gui/configs/CEGUIConfig.xsd	(revision 8079)
@@ -2,5 +2,5 @@
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
 
-	<xsd:element name="CEGUIConfig" type="CEGUIConfigType"/>
+    <xsd:element name="CEGUIConfig" type="CEGUIConfigType"/>
 
     <xsd:simpleType name="LogLevel">
@@ -12,16 +12,16 @@
         </xsd:restriction>
     </xsd:simpleType>
-    
-	<xsd:complexType name="CEGUIConfigType">
-		<xsd:attribute name="Logfile" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="Scheme" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="DefaultFont" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="Layout" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="InitScript" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="TerminateScript" type="xsd:string" use="optional" default=""/>
-		<xsd:attribute name="DefaultResourceGroup" type="xsd:string" use="optional"  default="" />
+
+    <xsd:complexType name="CEGUIConfigType">
+        <xsd:attribute name="Logfile" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="Scheme" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="DefaultFont" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="Layout" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="InitScript" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="TerminateScript" type="xsd:string" use="optional" default=""/>
+        <xsd:attribute name="DefaultResourceGroup" type="xsd:string" use="optional"  default="" />
         <xsd:attribute name="LoggingLevel" type="LogLevel" use="optional"  default="Standard" />
-	</xsd:complexType>
-	
+    </xsd:complexType>
+
 </xsd:schema>
 
Index: code/trunk/data/gui/layouts/GraphicsMenu.layout
===================================================================
--- code/trunk/data/gui/layouts/GraphicsMenu.layout	(revision 8078)
+++ code/trunk/data/gui/layouts/GraphicsMenu.layout	(revision 8079)
@@ -15,76 +15,194 @@
             <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
             <Property Name="VertFormatting" Value="TopAligned" />
-            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.2,0},{0.75,0},{0.6375,0}}" />
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/Resolution" >
-                <Property Name="Text" Value="Resolution" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.15,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/TabControl" Name="orxonox/GraphicsTabControl" >
+                <Property Name="TabHeight" Value="{0,26.4388}" />
                 <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.10,0},{0.475,0},{0.65,0}}" />
-                <Window Type="MenuWidgets/Listbox" Name="orxonox/ResolutionListbox" >
+                <Property Name="TabPanePosition" Value="Top" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.1,0},{0.95,0},{0.925,0}}" />
+                <Window Type="DefaultWindow" Name="orxonox/Display" >
+                    <Property Name="Text" Value="Display" />
                     <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.2,0},{0.95,0},{0.95,0}}" />
-                    <Event Name="ItemSelectionChanged" Function="GraphicsMenu.GraphicsResolutionListbox_changed"/>
+                    <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Resolution" >
+                        <Property Name="Text" Value="Resolution" />
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="VertFormatting" Value="TopAligned" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.025,0},{0.035,0},{0.4875,0},{0.96,0}}" />
+                        <Window Type="MenuWidgets/Checkbox" Name="orxonox/Display/Resolution/Fullscreen" >
+                            <Property Name="Text" Value="Fullscreen" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.27,0}}" />
+                            <Event Name="CheckStateChanged" Function="GraphicsMenu.callback_FullscreenCheckbox_CheckStateChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/Combobox" Name="orxonox/Display/Resolution/Combobox" >
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="ClippedByParent" Value="False" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.3,0},{0.95,0},{1.2,0}}" />
+                            <Property Name="MaxEditTextLength" Value="1073741823" />
+                            <Event Name="ListSelectionAccepted" Function="GraphicsMenu.callback_ResolutionCombobox_ListSelectionAccepted" />
+                        </Window>
+                        <Window Type="MenuWidgets/Editbox" Name="orxonox/Display/Resolution/EditboxWidth" >
+                            <Property Name="MaxTextLength" Value="1073741823" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.45,0},{0.45,0},{0.57,0}}" />
+                            <Event Name="TextChanged" Function="GraphicsMenu.callback_ResolutionEditboxWidth_TextChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/Editbox" Name="orxonox/Display/Resolution/EditboxHeight" >
+                            <Property Name="MaxTextLength" Value="1073741823" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.55,0},{0.45,0},{0.95,0},{0.57,0}}" />
+                            <Event Name="TextChanged" Function="GraphicsMenu.callback_ResolutionEditboxHeight_TextChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Resolution/x" >
+                            <Property Name="Text" Value="x" />
+                            <Property Name="FrameEnabled" Value="False" />
+                            <Property Name="HorzFormatting" Value="HorzCentred" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.45,0},{0.45,0},{0.55,0},{0.57,0}}" />
+                            <Property Name="BackgroundEnabled" Value="False" />
+                        </Window>
+                        <Window Type="MenuWidgets/Button" Name="orxonox/Display/Resolution/Apply" >
+                            <Property Name="Text" Value="Apply" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.61,0},{0.75,0},{0.73,0}}" />
+                            <Event Name="Clicked" Function="GraphicsMenu.callback_Apply_Clicked" />
+                        </Window>
+                        <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Resolution/AspectRatioLabel" >
+                            <Property Name="Text" Value="Aspect Ratio" />
+                            <Property Name="FrameEnabled" Value="False" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.825,0},{0.6,0},{0.95,0}}" />
+                            <Property Name="BackgroundEnabled" Value="False" />
+                        </Window>
+                        <Window Type="MenuWidgets/Editbox" Name="orxonox/Display/Resolution/AspectRatio" >
+                            <Property Name="Text" Value="1" />
+                            <Property Name="MaxTextLength" Value="1073741823" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.65,0},{0.825,0},{0.95,0},{0.95,0}}" />
+                        </Window>
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Theme" >
+                        <Property Name="Text" Value="Theme" />
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="VertFormatting" Value="TopAligned" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.035,0},{0.975,0},{0.32,0}}" />
+                        <Window Type="MenuWidgets/Combobox" Name="orxonox/Display/Theme/Combobox" >
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="ClippedByParent" Value="False" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.5,0},{0.95,0},{1.6,0}}" />
+                            <Property Name="MaxEditTextLength" Value="1073741823" />
+                            <Event Name="ListSelectionAccepted" Function="GraphicsMenu.callback_ThemeCombobox_ListSelectionAccepted" />
+                        </Window>
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/More" >
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.37,0},{0.975,0},{0.7,0}}" />
+                        <Window Type="MenuWidgets/Checkbox" Name="orxonox/Display/More/VSync" >
+                            <Property Name="Text" Value="VSync" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.1,0},{0.95,0},{0.45,0}}" />
+                            <Event Name="CheckStateChanged" Function="GraphicsMenu.callback_VSyncCheckbox_CheckStateChanged" />
+                        </Window>
+                        <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/More/FSAALabel" >
+                            <Property Name="Text" Value="FSAA" />
+                            <Property Name="FrameEnabled" Value="False" />
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.55,0},{0.3,0},{0.9,0}}" />
+                            <Property Name="BackgroundEnabled" Value="False" />
+                        </Window>
+                        <Window Type="MenuWidgets/Combobox" Name="orxonox/Display/More/FSAA" >
+                            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                            <Property Name="ClippedByParent" Value="False" />
+                            <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.55,0},{0.95,0},{2.1,0}}" />
+                            <Property Name="MaxEditTextLength" Value="1073741823" />
+                            <Event Name="ListSelectionAccepted" Function="GraphicsMenu.callback_FSAACombobox_ListSelectionAccepted" />
+                        </Window>
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/Notice" >
+                        <Property Name="Font" Value="BlueHighway-12" />
+                        <Property Name="Text" >Changing the theme, FSAA,
+or VSync requires a restart</Property>
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.75,0},{0.975,0},{0.96,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Display/NoticeRed" >
+                        <Property Name="Font" Value="BlueHighway-12" />
+                        <Property Name="Text" >Restart required</Property>
+                        <Property Name="TextColours" Value="tl:FFFF0000 tr:FFFF8888 bl:FFFF8888 br:FFFFFFFF" />
+                        <Property Name="HorzFormatting" Value="HorzCentred" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.75,0},{0.975,0},{0.96,0}}" />
+                    </Window>
+                </Window>
+                <Window Type="DefaultWindow" Name="orxonox/Settings" >
+                    <Property Name="Text" Value="Settings" />
+                    <Property Name="Visible" Value="False" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Settings/FovLabel" >
+                        <Property Name="Text" Value="Vertical field of view (FOV)" />
+                        <Property Name="FrameEnabled" Value="False" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.05,0},{0.5,0},{0.12,0}}" />
+                        <Property Name="BackgroundEnabled" Value="False" />
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Settings/FpsLimitLabel" >
+                        <Property Name="Text" Value="Maximal frame rate" />
+                        <Property Name="FrameEnabled" Value="False" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.18,0},{0.5,0},{0.25,0}}" />
+                        <Property Name="BackgroundEnabled" Value="False" />
+                    </Window>
+                    <Window Type="MenuWidgets/StaticText" Name="orxonox/Settings/ParticleLodLabel" >
+                        <Property Name="Text" Value="Particle detail level" />
+                        <Property Name="FrameEnabled" Value="False" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.31,0},{0.5,0},{0.38,0}}" />
+                        <Property Name="BackgroundEnabled" Value="False" />
+                    </Window>
+                    <Window Type="MenuWidgets/Editbox" Name="orxonox/Settings/Fov" >
+                        <Property Name="MaxTextLength" Value="1073741823" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5,0},{0.03,0},{0.65,0},{0.14,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/Editbox" Name="orxonox/Settings/FpsLimit" >
+                        <Property Name="MaxTextLength" Value="1073741823" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5,0},{0.16,0},{0.65,0},{0.27,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/Combobox" Name="orxonox/Settings/ParticleLodCombobox" >
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="ClippedByParent" Value="False" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.5,0},{0.29,0},{0.7,0},{0.725,0}}" />
+                        <Property Name="MaxEditTextLength" Value="1073741823" />
+                    </Window>
+                    <Window Type="MenuWidgets/Checkbox" Name="orxonox/Settings/MeshLodCheckbox" >
+                        <Property Name="Text" Value="Enable mesh LOD" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.44,0},{0.5,0},{0.51,0}}" />
+                    </Window>
+                    <Window Type="MenuWidgets/Checkbox" Name="orxonox/Settings/MotionBlurCheckbox" >
+                        <Property Name="Text" Value="Enable motion blur" />
+                        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                        <Property Name="UnifiedAreaRect" Value="{{0.035,0},{0.57,0},{0.5,0},{0.64,0}}" />
+                    </Window>
                 </Window>
             </Window>
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/Themes" >
-                <Property Name="Text" Value="Themes" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.10,0},{0.95,0},{0.35,0}}" />
-                <Window Type="MenuWidgets/Listbox" Name="orxonox/ThemeDropBox" >
-                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.3,0},{0.95,0},{0.95,0}" />
-                    <Event Name="ItemSelectionChanged" Function="GraphicsMenu.ThemeDropBox_changed"/>
-                </Window>
-            </Window>
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/Brightness" >
-                <Property Name="Text" Value="Brightness" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.70,0},{0.475,0},{0.85,0}}" />
-                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/BrightnessScrollbar" >
-                    <Property Name="Disabled" Value="true" />
-                    <Property Name="PageSize" Value="0" />
-                    <Property Name="StepSize" Value="0.1" />
-                    <Property Name="OverlapSize" Value="0" />
-                    <Property Name="DocumentSize" Value="1" />
-                    <Property Name="ScrollPosition" Value="0" />
-                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.6,0},{0.95,0},{0.8,0}}" />
-                    <Event Name="ThumbTrackStarted" Function="GraphicsMenu.GraphicsBrightnessScrollbar_started" />
-                    <Event Name="ThumbTrackEnded" Function="GraphicsMenu.GraphicsBrightnessScrollbar_ended" />
-                    <Event Name="ScrollPosChanged" Function="GraphicsMenu.GraphicsBrightnessScrollbar_changed" />
-                </Window>
-            </Window>
-            <Window Type="MenuWidgets/Checkbox" Name="orxonox/FullscreenCheckbox" >
-                <Property Name="Text" Value="Fullscreen" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="UnifiedAreaRect" Value="{{0.65,0},{0.35,0},{0.85,0},{0.425,0}}" />
-                <Event Name="CheckStateChanged" Function="GraphicsMenu.GraphicsFullscreenCheckbox_clicked"/>
-            </Window>
-            <Window Type="MenuWidgets/StaticText" Name="orxonox/GraphicsInfo" >
-                <Property Name="Text" >
-Changes in graphics
-settings require
-a game restart.</Property>
-                <Property Name="TextColours" Value="FFFFFFFF" />
-                <Property Name="InheritsAlpha" Value="False" />
-                <Property Name="HorzFormatting" Value="HorzCentred" />
-                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-                <Property Name="VertFormatting" Value="TopAligned" />
-                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.425,0},{0.95,0},{0.85,0}}" />
-            </Window>
         </Window>
-        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsBackButton" >
-            <Property Name="Text" Value="Back" />
+        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsOkButton" >
+            <Property Name="Text" Value="OK" />
             <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
-            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
-            <Event Name="Clicked" Function="GraphicsMenu.GraphicsBackButton_clicked"/>
+            <Property Name="UnifiedAreaRect" Value="{{0.2875,0},{0.6625,0},{0.4875,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="GraphicsMenu.callback_Ok_Clicked" />
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsCancelButton" >
+            <Property Name="Text" Value="Cancel" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.6625,0},{0.7125,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="GraphicsMenu.callback_Cancel_Clicked" />
         </Window>
     </Window>
Index: code/trunk/data/gui/schemes/GUIScheme.xsd
===================================================================
--- code/trunk/data/gui/schemes/GUIScheme.xsd	(revision 8078)
+++ code/trunk/data/gui/schemes/GUIScheme.xsd	(revision 8079)
@@ -1,53 +1,53 @@
 <?xml version="1.0" ?>
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
-	<xsd:element name="GUIScheme" type="SchemeType" />
-	<xsd:complexType name="SchemeType">
+    <xsd:element name="GUIScheme" type="SchemeType" />
+    <xsd:complexType name="SchemeType">
         <xsd:choice minOccurs="0" maxOccurs="unbounded">
-			<xsd:element name="Imageset" type="NamedDataType" />
+            <xsd:element name="Imageset" type="NamedDataType" />
             <xsd:element name="ImagesetFromImage" type="NamedDataType" />
-			<xsd:element name="Font" type="NamedDataType" />
+            <xsd:element name="Font" type="NamedDataType" />
             <xsd:element name="LookNFeel" type="FileDataType" />
-			<xsd:element name="WindowSet" type="WindowSetType" />
-			<xsd:element name="WindowRendererSet" type="WindowRendererSetType" />
-			<xsd:element name="WindowAlias" type="WindowAliasType" />
+            <xsd:element name="WindowSet" type="WindowSetType" />
+            <xsd:element name="WindowRendererSet" type="WindowRendererSetType" />
+            <xsd:element name="WindowAlias" type="WindowAliasType" />
             <xsd:element name="FalagardMapping" type="FalagardMapType" />
-		</xsd:choice>
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowSetType">
-		<xsd:sequence>
+        </xsd:choice>
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowSetType">
+        <xsd:sequence>
             <xsd:element name="WindowFactory" type="WindowFactoryType" minOccurs="0" maxOccurs="unbounded" />
-		</xsd:sequence>
-		<xsd:attribute name="Filename" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowRendererSetType">
-		<xsd:sequence>
+        </xsd:sequence>
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowRendererSetType">
+        <xsd:sequence>
             <xsd:element name="WindowRendererFactory" type="WindowRendererFactoryType" minOccurs="0" maxOccurs="unbounded" />
-		</xsd:sequence>
-		<xsd:attribute name="Filename" type="xsd:string" use="required" />
-	</xsd:complexType>
+        </xsd:sequence>
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+    </xsd:complexType>
     <xsd:complexType name="FileDataType">
         <xsd:attribute name="Filename" type="xsd:string" use="required" />
         <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
     </xsd:complexType>
-	<xsd:complexType name="NamedDataType">
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-		<xsd:attribute name="Filename" type="xsd:string" use="required" />
-		<xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowFactoryType">
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowRendererFactoryType">
-		<xsd:attribute name="Name" type="xsd:string" use="required" />
-	</xsd:complexType>
-	<xsd:complexType name="WindowAliasType">
-		<xsd:attribute name="Alias" type="xsd:string" use="required" />
-		<xsd:attribute name="Target" type="xsd:string" use="required" />
-	</xsd:complexType>
+    <xsd:complexType name="NamedDataType">
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+        <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowFactoryType">
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowRendererFactoryType">
+        <xsd:attribute name="Name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    <xsd:complexType name="WindowAliasType">
+        <xsd:attribute name="Alias" type="xsd:string" use="required" />
+        <xsd:attribute name="Target" type="xsd:string" use="required" />
+    </xsd:complexType>
     <xsd:complexType name="FalagardMapType">
         <xsd:attribute name="WindowType" type="xsd:string" use="required" />
         <xsd:attribute name="TargetType" type="xsd:string" use="required" />
-		<xsd:attribute name="Renderer" type="xsd:string" use="required" />
+        <xsd:attribute name="Renderer" type="xsd:string" use="required" />
         <xsd:attribute name="LookNFeel" type="xsd:string" use="required" />
     </xsd:complexType>
Index: code/trunk/data/gui/schemes/OrxonoxLook.scheme
===================================================================
--- code/trunk/data/gui/schemes/OrxonoxLook.scheme	(revision 8078)
+++ code/trunk/data/gui/schemes/OrxonoxLook.scheme	(revision 8079)
@@ -1,7 +1,7 @@
 <?xml version="1.0" ?>
 <GUIScheme Name="OrxonoxLook">
-	<Imageset Name="OrxonoxLook" Filename="OrxonoxLook.imageset" />
-	<LookNFeel Filename="OrxonoxLook.looknfeel" />
-	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+    <Imageset Name="OrxonoxLook" Filename="OrxonoxLook.imageset" />
+    <LookNFeel Filename="OrxonoxLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
 
     <!-- Standard widgets -->
@@ -45,5 +45,5 @@
     <FalagardMapping WindowType="OrxonoxLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="OrxonoxLook/Tooltip" />
     <FalagardMapping WindowType="OrxonoxLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="OrxonoxLook/Tree" />
-    
+
     <!-- Additional widgets -->
     <FalagardMapping WindowType="OrxonoxLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="OrxonoxLook/AltProgressBar" />
Index: code/trunk/data/gui/schemes/TaharezGreenLook.scheme
===================================================================
--- code/trunk/data/gui/schemes/TaharezGreenLook.scheme	(revision 8078)
+++ code/trunk/data/gui/schemes/TaharezGreenLook.scheme	(revision 8079)
@@ -1,7 +1,7 @@
 <?xml version="1.0" ?>
 <GUIScheme Name="TaharezGreenLook">
-	<Imageset Name="TaharezGreenLook" Filename="TaharezGreenLook.imageset" />
-	<LookNFeel Filename="TaharezGreenLook.looknfeel" />
-	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+    <Imageset Name="TaharezGreenLook" Filename="TaharezGreenLook.imageset" />
+    <LookNFeel Filename="TaharezGreenLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
 
     <!-- Standard widgets -->
@@ -45,5 +45,5 @@
     <FalagardMapping WindowType="TaharezGreenLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezGreenLook/Tooltip" />
     <FalagardMapping WindowType="TaharezGreenLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezGreenLook/Tree" />
-    
+
     <!-- Additional widgets -->
     <FalagardMapping WindowType="TaharezGreenLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezGreenLook/AltProgressBar" />
Index: code/trunk/data/gui/schemes/TaharezLook.scheme
===================================================================
--- code/trunk/data/gui/schemes/TaharezLook.scheme	(revision 8078)
+++ code/trunk/data/gui/schemes/TaharezLook.scheme	(revision 8079)
@@ -1,7 +1,7 @@
 <?xml version="1.0" ?>
 <GUIScheme Name="TaharezLook">
-	<Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
-	<LookNFeel Filename="TaharezLook.looknfeel" />
-	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+    <Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+    <LookNFeel Filename="TaharezLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
 
     <!-- Standard widgets -->
@@ -45,5 +45,5 @@
     <FalagardMapping WindowType="TaharezLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezLook/Tooltip" />
     <FalagardMapping WindowType="TaharezLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezLook/Tree" />
-    
+
     <!-- Additional widgets -->
     <FalagardMapping WindowType="TaharezLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/AltProgressBar" />
Index: code/trunk/data/gui/scripts/AudioMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/AudioMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/AudioMenu.lua	(revision 8079)
@@ -2,11 +2,4 @@
 
 local P = createMenuSheet("AudioMenu")
-
-P.buttonList = {}
-
-function P.onShow()
-    P.oldindex = -2
-    P.index = -1
-end
 
 function P.onLoad()
@@ -50,9 +43,8 @@
     end
 
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/AudioBackButton"),
-            ["function"]  = P.AudioBackButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.AudioBackButton_clicked
+    })
 end
 
@@ -185,8 +177,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 1)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/ControlsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/ControlsMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/ControlsMenu.lua	(revision 8079)
@@ -2,35 +2,24 @@
 
 local P = createMenuSheet("ControlsMenu")
-P.buttonList = {}
 P.loadAlong = { "MouseControlsMenu", "KeyBindMenu" }
 
 function P.onLoad()
-    P.multiplayerMode = "startClient" 
+    P.multiplayerMode = "startClient"
 
     --buttons are arranged in a 3x1 matrix:
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/MouseControlsButton"),
-            ["function"]  = P.ControlsMouseControlsButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.ControlsMouseControlsButton_clicked
+    })
 
-    local item = {
+    P:setButton(2, 1, {
             ["button"] = winMgr:getWindow("orxonox/KeybindingsButton"),
-            ["function"]  = P.ControlsKeyboardControlsButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.ControlsKeyboardControlsButton_clicked
+    })
 
-    local item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/ControlsBackButton"),
-            ["function"]  = P.ControlsBackButton_clicked
-    }
-    P.buttonList[3] = item
-
-end
-
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
+            ["callback"]  = P.ControlsBackButton_clicked
+    })
 end
 
@@ -47,8 +36,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 3, 1)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/CreditsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/CreditsMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/CreditsMenu.lua	(revision 8079)
@@ -3,20 +3,14 @@
 local P = createMenuSheet("CreditsMenu")
 
-P.buttonList = {}
 P.scrollbarWidth = 13
 
 function P.onLoad()
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/CreditsBackButton"),
-            ["function"]  = P.CreditsBackButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.CreditsBackButton_clicked
+    })
 end
 
 function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-
     local description = winMgr:getWindow("orxonox/CreditsText")
     description:setProperty("HorzFormatting", "WordWrapLeftAligned")
@@ -33,8 +27,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 1)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/DecisionPopup.lua
===================================================================
--- code/trunk/data/gui/scripts/DecisionPopup.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/DecisionPopup.lua	(revision 8079)
@@ -3,27 +3,20 @@
 local P = createMenuSheet("DecisionPopup")
 
-P.buttonList = {}
-
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-end
-
 function P.onLoad()
 
     --button are arranged in a 1x2 matrix
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/DecisionPopup_button_yes"),
-            ["function"]  = P.button_yes
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.button_yes
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/DecisionPopup_button_no"),
-            ["function"]  = P.button_no
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.button_no
+    })
+end
 
+function P.onShow()
+    P:setSelection(1, 1)
 end
 
@@ -51,8 +44,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 2)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/GUISheet.lua
===================================================================
--- code/trunk/data/gui/scripts/GUISheet.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/GUISheet.lua	(revision 8079)
@@ -16,4 +16,24 @@
 end
 
+-- Override this function if you need to do work on show
+function P:onShow()
+end
+
+-- Override this function if you need to do work on hide
+function P:onHide()
+end
+
+-- Override this function if you need to do work on quit
+function P:onQuit()
+end
+
+-- Override this function if you want to react on keystrokes
+function P:onKeyPressed()
+end
+
+-- Override this function if you want to update the gui after the window was resized
+function P:onWindowResized()
+end
+
 -- show function for the GUI
 function P:show()
@@ -21,9 +41,8 @@
     self.bVisible = true
 
+    -- set the selected button's state
+    self:setSelectedButtonsStateToSelected()
+
     self:onShow()
-end
-
--- Override this function if you need to do work on show
-function P:onShow()
 end
 
@@ -36,10 +55,11 @@
 end
 
--- Override this function if you need to do work on hide
-function P:onHide()
-end
-
--- Override this function if you need to do work just after the sheet has been hidden
-function P:afterHide()
+function P:quit()
+    -- reset the selected button
+    if self.buttons then
+        self:resetSelection()
+    end
+
+    self:onQuit()
 end
 
@@ -64,5 +84,314 @@
 end
 
-function P:onKeyPressed(e)
+-- Handles key pressed while the gui sheed is displayed
+function P:keyPressed()
+    if self.buttons then
+        if code == "208" then     -- key down
+            self:moveSelectionRow(1)
+        elseif code == "200" then -- key up
+            self:moveSelectionRow(-1)
+        elseif code == "205" then -- key right
+            self:moveSelectionColumn(1)
+        elseif code == "203" then -- key left
+            self:moveSelectionColumn(-1)
+        elseif code == "28" or code == "156"  then -- key enter or key numpad enter
+            self:pressSelectedButton()
+        end
+    end
+
+    self:onKeyPressed()
+end
+
+function P:windowResized()
+    self:onWindowResized()
+end
+
+
+-------------------------------------------------------------------------------
+-- Keyboard control -----------------------------------------------------------
+-------------------------------------------------------------------------------
+
+-- Initializes the buttons table, used to control the menu with the keyboard
+function P:initButtons(rows, columns)
+    self.rows = rows
+    self.columns = columns
+    self.buttons = {}
+    self.selectedRow = 0
+    self.selectedColumn = 0
+    self.ratio = 1
+end
+
+-- ratio: the button's with divided by the button's height (used to calculate distance between buttons - adjust this until you get the desired behavior)
+function P:setRatio(ratio)
+    self.ratio = ratio
+end
+
+-- Defines the button for a given position in the table. The upper-left button is at position (1, 1)
+function P:setButton(row, column, button)
+    if not self.buttons then
+        -- init the table
+        self:initButtons(row, column)
+    elseif row > self.rows or column > self.columns then
+        -- rearrange the table
+        local maxRows = math.max(self.rows, row)
+        local maxColumns = math.max(self.columns, column)
+
+        for r = self.rows, 1, -1 do
+            for c = self.columns, 1, -1 do
+                local b = self:getButton(r, c)
+                if b then
+                    self.buttons[(r - 1) * self.columns + (c - 1)] = nil
+                    self.buttons[(r - 1) * maxColumns + (c - 1)] = b
+                end
+            end
+        end
+
+        self.rows = maxRows
+        self.columns = maxColumns
+    end
+
+    self.buttons[(row - 1) * self.columns + (column - 1)] = button
+end
+
+-- Returns the button at a given position in the table. The upper-left button is at position (1, 1)
+function P:getButton(row, column)
+    if self.buttons then
+        return self.buttons[(row - 1) * self.columns + (column - 1)]
+    else
+        return nil
+    end
+end
+
+-- Returns the selected button
+function P:getSelectedButton()
+    if self:hasSelection() then
+        return self:getButton(self.selectedRow, self.selectedColumn)
+    else
+        return nil
+    end
+end
+
+-- Presses the selected button if any
+function P:pressSelectedButton()
+    if self:getSelectedButton() then
+        self.pressedEnter = true
+        self:getSelectedButton().callback()
+        self.pressedEnter = false
+    end
+end
+
+-- Sets the selection to a given row and column. The upper-left button is at position (1, 1)
+function P:setSelection(row, column)
+    if not self.buttons then
+        return
+    end
+
+    assert(row > 0 and column > 0 and row <= self.rows and column <= self.columns, "(" .. row .. "/" .. column .. ") is not in the valid bounds of the table (1/1)-(" .. self.rows .. "/" .. self.columns .. ")")
+
+    self:setSelectedButtonsStateToNormal()
+
+    self.selectedRow = row
+    self.selectedColumn = column
+
+    self:setSelectedButtonsStateToSelected()
+end
+
+-- Sets the selection to the button closest to the given row and column. The upper-left button is at position (1, 1)
+function P:setSelectionNear(row, column)
+    if not self.buttons then
+        return
+    end
+
+    assert(row > 0 and column > 0 and row <= self.rows and column <= self.columns, "(" .. row .. "/" .. column .. ") is not in the valid bounds of the table (1/1)-(" .. self.rows .. "/" .. self.columns .. ")")
+
+    if self:getButton(row, column) then
+        self:setSelection(row, column)
+    else
+        local min = 1000000
+        local minRow, minColumn
+
+        for r = 1, self.rows do
+            for c = 1, self.columns do
+                if self:getButton(r, c) then
+                    local distance = math.sqrt((row - r)^2 + ((column - c) * self.ratio)^2)
+                    if distance < min then
+                        min = distance; minRow = r; minColumn = c
+                    end
+                end
+            end
+        end
+
+        if minRow and minColumn then
+            self:setSelection(minRow, minColumn)
+        else
+            self:resetSelection()
+        end
+    end
+end
+
+-- Moves the selection by a given number of rows (a positive value means down, a negative value means up)
+function P:moveSelectionRow(relRow)
+    self:moveSelection(relRow, "selectedRow", "selectedColumn", "rows", "columns", true)
+end
+
+-- Moves the selection by a given number of columns (a positive value means right, a negative value means left)
+function P:moveSelectionColumn(relColumn)
+    self:moveSelection(relColumn, "selectedColumn", "selectedRow", "columns", "rows", false)
+end
+
+-- Generic move function, the values are determined at runtime depending on the arguments
+function P:moveSelection(relMove, selectedThis, selectedOther, limitThis, limitOther, isRow)
+    if not self.buttons then
+        return
+    end
+
+    -- if there's no selection yet, prepare it such that the selection enters the table from the desired side
+    if self.selectedRow > 0 or self.selectedColumn > 0 then
+        self:setSelectedButtonsStateToNormal()
+    else
+        if relMove > 0 then
+            self[selectedThis] = 0
+            self[selectedOther] = 1
+        elseif relMove < 0 then
+            self[selectedThis] = self[limitThis] + 1
+            self[selectedOther] = 1
+        else
+            return
+        end
+    end
+
+    -- move the selection according to the parameters
+    self[selectedThis] = self[selectedThis] + relMove
+
+    -- wrap around on overflow or underflow
+    while self[selectedThis] > self[limitThis] do self[selectedThis] = self[selectedThis] - self[limitThis] end
+    while self[selectedThis] <= 0              do self[selectedThis] = self[selectedThis] + self[limitThis] end
+
+    -- if the button is deactivated, search the button closest to the desired location
+    if self:getSelectedButton() == nil then
+        local min = 1000000
+        local minV1, minV2
+        local limit, step
+
+        if relMove > 0 then
+            limit = self[limitThis]
+            step = 1
+        else
+            limit = 1
+            step = -1
+        end
+
+        for v1 = self[selectedThis], limit, step do
+            for v2 = 1, self[limitOther] do
+                local button
+                if isRow == true then
+                    button = self:getButton(v1, v2)
+                else
+                    button = self:getButton(v2, v1)
+                end
+                if button then
+                    local distance
+                    if isRow == true then
+                        distance = math.sqrt((self[selectedThis] - v1)^2 + ((self[selectedOther] - v2) * self.ratio)^2)
+                    else
+                        distance = math.sqrt(((self[selectedThis] - v1) * self.ratio)^2 + (self[selectedOther] - v2)^2)
+                    end
+                    if distance < min then
+                        min = distance; minV1 = v1; minV2 = v2
+                    end
+                end
+            end
+        end
+
+        if minV1 and minV2 then
+            self[selectedThis] = minV1
+            self[selectedOther] = minV2
+        elseif self:hasButtons() then
+            -- no suitable button found - wrap around and search again
+            if relMove > 0 then
+                self[selectedThis] = 0
+            else
+                self[selectedThis] = self[limitThis] + 1
+            end
+            self:moveSelection(relMove, selectedThis, selectedOther, limitThis, limitOther, isRow)
+        end
+    end
+
+    self:setSelectedButtonsStateToSelected()
+end
+
+-- Resets the selection
+function P:resetSelection()
+    self:setSelectedButtonsStateToNormal()
+
+    self.selectedRow = 0
+    self.selectedColumn = 0
+end
+
+-- Checks if there's at least one button in the table
+function P:hasButtons()
+    local count = 0
+    for r = 1, self.rows do
+        for c = 1, self.columns do
+            if self:getButton(r, c) then
+                count = count + 1
+            end
+        end
+    end
+
+    return (count > 0)
+end
+
+-- Determines if a button is selected
+function P:hasSelection()
+    if self.selectedRow and self.selectedRow > 0 and self.selectedColumn and self.selectedColumn > 0 then
+        return true
+    else
+        return false
+    end
+end
+
+-- Sets the selected button's state to normal
+function P:setSelectedButtonsStateToNormal()
+    self:setSelectedButtonsState("Normal")
+end
+
+-- Sets the selected button's state to selected
+function P:setSelectedButtonsStateToSelected()
+    self:setSelectedButtonsState("Selected")
+end
+
+-- Sets the selected button's state to pushed
+function P:setSelectedButtonsStateToPushed()
+    self:setSelectedButtonsState("Pushed")
+end
+
+-- Sets the selected button's state
+function P:setSelectedButtonsState(state)
+    if self:getSelectedButton() then
+        local element = self:getSelectedButton().button
+        local offset = getElementStateOffset(element)
+
+        if offset then
+            element:setProperty("NormalImageRightEdge",  string.sub(element:getProperty("NormalImageRightEdge"),  1, offset) .. state)
+            element:setProperty("NormalImageLeftEdge",   string.sub(element:getProperty("NormalImageLeftEdge"),   1, offset) .. state)
+            element:setProperty("NormalImageBackground", string.sub(element:getProperty("NormalImageBackground"), 1, offset) .. state)
+        end
+    end
+end
+
+-- Gets the offset of the button's current state
+function getElementStateOffset(element)
+    local property = element:getProperty("NormalImageRightEdge")
+
+    if string.sub(property, string.len(property) - 5, string.len(property)) == "Normal" then
+        return -7
+    elseif string.sub(property, string.len(property) - 7, string.len(property)) == "Selected" then
+        return -9
+    elseif string.sub(property, string.len(property) - 5, string.len(property)) == "Pushed" then
+        return -7
+    else
+        return nil
+    end
 end
 
Index: code/trunk/data/gui/scripts/GUITools.lua
===================================================================
--- code/trunk/data/gui/scripts/GUITools.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/GUITools.lua	(revision 8079)
@@ -54,283 +54,2 @@
     return height
 end
-
---function to iterate through a menu sheet by using arrowkeys
-
---@arguments:
---  list: 2-dimensional table, arguments are items that contain a button and its function
---        !!note: each button can only be in the list once!!
---  code: code of any key on the keyboard
---  P: menusheet
---  n: number of rows of the buttontable
---  m: number of colums of the buttontable
-
-function buttonIteratorHelper(list, code, P, n, m)
-
-    --after a key (down,up,left,right) is pressed the index of the current button has to be updated    
-
-    --key down
-    if code == "208" then
-        if P.index < 0 then     -- initial status
-            P.index = 0
-            P.oldindex = -1
-        else
-            P.oldindex = P.index
-            P.index = (P.index + m) % (m*n)     --modulo operation works as a "wrap around" in the button menu
-                                                
-            while list[P.index+1] == nil do     
-                P.oldindex = P.index
-                P.index = (P.index + m) % (m*n)
-            end
-        end
-
-    --key up
-    elseif code == "200" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif(P.index == 0) then
-            P.oldindex = P.index
-            P.index = m*n-m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index-m)%(m*n)
-            end
-        else
-            P.oldindex = P.index
-            P.index = (P.index -m) % (m*n)
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index-m)%(m*n)
-            end
-        end
-
-    --key right
-    elseif code == "205" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif (P.index+1) % m == 0 then     -- we are at the right-end of a row
-            P.oldindex = P.index
-            P.index = P.index + 1 -m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index + 1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index + 1
-
-            while list[P.index+1] == nil do
-                if (P.index+1) % m == 0 then     -- we are at the right-end of a row
-                    P.oldindex = P.index
-                    P.index = P.index + 1-m
-
-                else    
-                    P.oldindex = P.index
-                    P.index = P.index + 1
-                end
-            end
-        end    
-
-    --key left
-    elseif code == "203" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif P.index % m == 0 then         -- we are at the left-end of a row 
-            P.oldindex = P.index
-            P.index = P.index +m-1
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index -1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index -1
-
-            while list[P.index+1] == nil do
-                if P.index % m == 0 then     -- we are at the left-end of a row 
-                    P.oldindex = P.index
-                    P.index = P.index -1 + m
-                else                
-                    P.oldindex = P.index
-                    P.index = P.index -1
-                end
-            end   
-        end
-    end
-       
-    --to update the new current button
-    if (code == "208" or code == "200" or code == "203" or code == "205") and P.oldindex~= P.index then
-
-        local system = CEGUI.System:getSingleton()
-        local window = winMgr:getWindow("orxonox/MainMenuBackground")
-
-        local item = list[P.index+1]
-        local child = item["button"]
-        local s = child:getProperty("NormalImageRightEdge") 
-
-        --teste ob der Button nicht schon gehighlightet ist
-        if string.sub(s,string.len(s)-8,string.len(s)) == "Highlight" then
-            --nop
-        else
-            child:setProperty("NormalImageRightEdge", string.sub(child:getProperty("NormalImageRightEdge"),1,-7) .. "Highlight")
-            child:setProperty("NormalImageLeftEdge", string.sub(child:getProperty("NormalImageLeftEdge"),1,-7) .. "Highlight")
-            child:setProperty("NormalImageBackground", string.sub(child:getProperty("NormalImageBackground"),1,-7) .. "Highlight")
-            if P.oldindex >= 0 then
-                if list[P.oldindex+1] ~= nil then
-                    local item = list[P.oldindex+1]
-                    local oldChild = item["button"]
-                    oldChild:setProperty("NormalImageRightEdge", string.sub(oldChild:getProperty("NormalImageRightEdge"),1,-10) .. "Normal")
-                    oldChild:setProperty("NormalImageLeftEdge", string.sub(oldChild:getProperty("NormalImageLeftEdge"),1,-10) .. "Normal")
-                    oldChild:setProperty("NormalImageBackground", string.sub(oldChild:getProperty("NormalImageBackground"),1,-10) .. "Normal")
-                end
-            end
-        end
-
-        --for every highlighted button check if index is on its position. If not, set imageproperty on "normal"
-        local i = 1
-        while i < (n*m) do
-            if i == P.index +1 then 
-                i = i+1
-            else
-                if list[i] ~= nil then 
-                local item = list[i]
-                local child = item["button"]
-                local s = child:getProperty("NormalImageRightEdge")
-                    if string.sub(s,string.len(s)-8,string.len(s)) == "Highlight" then
-                        child:setProperty("NormalImageRightEdge", string.sub(child:getProperty("NormalImageRightEdge"),1,-10) .. "Normal")
-                        child:setProperty("NormalImageLeftEdge", string.sub(child:getProperty("NormalImageLeftEdge"),1,-10) .. "Normal")
-                        child:setProperty("NormalImageBackground", string.sub(child:getProperty("NormalImageBackground"),1,-10) .. "Normal")
-                    end
-                end
-            end
-                i=i+1
-        end
-    end  
-
-    --enter
-    if code == "28" and P.index >= 0 then
-        local item = list[P.index+1]
-        local child = item["button"] 
-        child:setProperty("NormalImageRightEdge", string.sub(child:getProperty("NormalImageRightEdge"),1,-10) .. "Normal")
-        child:setProperty("NormalImageLeftEdge", string.sub(child:getProperty("NormalImageLeftEdge"),1,-10) .. "Normal")
-        child:setProperty("NormalImageBackground", string.sub(child:getProperty("NormalImageBackground"),1,-10) .. "Normal")
-
-        local foo = item["function"]
-        foo()
-    end
-
-end
-
---write index and oldindex on the console
---works like buttonIteratorHelper
-function indexTester(list,code,P,n,m)
-    --key down
-    if code == "208" then
-        if P.index < 0 then     -- initial status
-            P.index = 0
-            P.oldindex = -1
-        else
-            P.oldindex = P.index
-            P.index = (P.index + m) % (m*n)
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index + m) % (m*n)
-            end
-        end
-
-    --key up
-    elseif code == "200" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif(P.index == 0) then
-            P.oldindex = P.index
-            P.index = m*n-m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = (P.index-m)%(m*n)
-            end
-        else
-            P.oldindex = P.index
-            P.index = (P.index -m) % (m*n)
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index -m
-            end
-        end
-
-    --key right
-    elseif code == "205" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif (P.index+1) % m == 0 then     -- we are at the right-end of a row
-            P.oldindex = P.index
-            P.index = P.index + 1 -m
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index + 1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index + 1
-
-            while list[P.index+1] == nil do
-                if (P.index+1) % m == 0 then     -- we are at the right-end of a row
-                    P.oldindex = P.index
-                    P.index = P.index + 1-m
-
-                else    
-                    P.oldindex = P.index
-                    P.index = P.index + 1
-                end
-            end
-        end    
-
-    --key left
-    elseif code == "203" then
-        if P.index < 0 then
-            P.index = 0
-            P.oldindex = -1
-        elseif P.index % m == 0 then         -- we are at the left-end of a row 
-            P.oldindex = P.index
-            P.index = P.index +m-1
-
-            while list[P.index+1] == nil do
-                P.oldindex = P.index
-                P.index = P.index -1
-            end
-        else
-            P.oldindex = P.index
-            P.index = P.index -1
-
-            while list[P.index+1] == nil do
-                if P.index % m == 0 then     -- we are at the left-end of a row 
-                    P.oldindex = P.index
-                    P.index = P.index -1 + m
-                else                
-                    P.oldindex = P.index
-                    P.index = P.index -1
-                end
-            end   
-        end
-    end    
-
-    cout(0, P.oldindex)
-    cout(0, P.index)
-
-end
-
-
-
-
Index: code/trunk/data/gui/scripts/GraphicsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/GraphicsMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/GraphicsMenu.lua	(revision 8079)
@@ -3,236 +3,417 @@
 local P = createMenuSheet("GraphicsMenu")
 
-P.buttonList = {}
+P.resolutionList = {"custom", "640 x 480", "720 x 480", "720 x 576", "800 x 600", "1024 x 600", "1024 x 768", "1152 x 864", "1280 x 720", "1280 x 800", "1280 x 960", "1280 x 1024", "1360 x 768", "1440 x 900", "1600 x 900", "1600 x 1200", "1680 x 1050"}
 P.schemeList = {"TaharezGreen", "Orxonox"}
-
-function P.onShow()
-    --indices to iterate through buttonlist (trivial in this menu sheet)
-    P.oldindex = -2
-    P.index = -1
-end
-
-function P.onLoad()
-    block = true
-    file = orxonox.PathConfig:getConfigPathString() .. orxonox.getConfig("GraphicsManager", "ogreConfigFile_")
-    search_mode = 0
-    f = io.open(file, "r")
-    firstline = f:read("*line")
-    rendersystem = string.sub(firstline, 15)
-    for line in f:lines() do
-        if search_mode == 0 then
-            if string.find(line, rendersystem) ~= nil then
-                search_mode = 1
-            end
+P.fsaaList = {"0", "2", "4", "8", "8 [Quality]"}
+P.particleLodList = {"None", "Low", "Normal", "High"}
+
+function P:onLoad()
+    -------------------
+    -- Button matrix --
+    -------------------
+
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/GraphicsOkButton"),
+            ["callback"]  = P.callback_Ok_Clicked
+    })
+
+    P:setButton(1, 2, {
+            ["button"] = winMgr:getWindow("orxonox/GraphicsCancelButton"),
+            ["callback"]  = P.callback_Cancel_Clicked
+    })
+
+    -- place apply button at the bottom in the matrix, even though it's in fact at the top, to make the OK button highlighted by default
+    P:setButton(2, 1, {
+            ["button"] = winMgr:getWindow("orxonox/Display/Resolution/Apply"),
+            ["callback"]  = P.callback_Apply_Clicked
+    })
+
+    -----------------
+    -- Combo boxes --
+    -----------------
+
+    -- resolution combobox
+    local resolutionCombobox = winMgr:getWindow("orxonox/Display/Resolution/Combobox")
+    CEGUI.toCombobox(resolutionCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.resolutionList) do
+        local item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        resolutionCombobox:addItem(item)
+    end
+
+    -- themes combobox
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    CEGUI.toCombobox(themeCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.schemeList) do
+        local item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        themeCombobox:addItem(item)
+    end
+
+    -- fsaa combobox
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    CEGUI.toCombobox(fsaaCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.fsaaList) do
+        local item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        fsaaCombobox:addItem(item)
+    end
+
+    -- particle lod combobox
+    local particleLodCombobox = winMgr:getWindow("orxonox/Settings/ParticleLodCombobox")
+    CEGUI.toCombobox(particleLodCombobox):setReadOnly(true)
+
+    for k,v in pairs(P.particleLodList) do
+        local item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        particleLodCombobox:addItem(item)
+    end
+end
+
+function P:onShow()
+    -----------------
+    -- Display tab --
+    -----------------
+
+    -- fullscreen checkbox / resolution combobox / resolution editboxes
+    self:onWindowResized()
+
+    -- apply button
+    self.updateApplyButton()
+
+    -- aspect ratio editbox
+    local aspectRatioEditbox = winMgr:getWindow("orxonox/Display/Resolution/AspectRatio")
+    local currentAspectRatio = orxonox.CommandExecutor:query("getConfig Camera aspectRatio_")
+    aspectRatioEditbox:setText(currentAspectRatio)
+
+    -- themes combobox
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    local currentTheme = orxonox.CommandExecutor:query("getConfig GUIManager guiScheme_")
+
+    for i = 0, themeCombobox:getDropList():getItemCount() - 1 do
+        local item = themeCombobox:getListboxItemFromIndex(i)
+        themeCombobox:setItemSelectState(item, (item:getText() == currentTheme))
+    end
+
+    -- vsync checkbox
+    local vsyncCheckbox = winMgr:getWindow("orxonox/Display/More/VSync")
+    local hasVSync = orxonox.GraphicsManager:getInstance():hasVSyncEnabled()
+    CEGUI.toCheckbox(vsyncCheckbox):setSelected(hasVSync)
+
+    -- fsaa combobox
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    local currentFSAAMode = orxonox.GraphicsManager:getInstance():getFSAAMode()
+
+    for i = 0, fsaaCombobox:getDropList():getItemCount() - 1 do
+        local item = fsaaCombobox:getListboxItemFromIndex(i)
+        fsaaCombobox:setItemSelectState(item, (item:getText() == currentFSAAMode))
+    end
+
+    -- notice
+    self:updateRedLabel()
+
+    ------------------
+    -- Settings tab --
+    ------------------
+
+    -- fov editbox
+    local fovEditbox = winMgr:getWindow("orxonox/Settings/Fov")
+    local currentFov = orxonox.CommandExecutor:query("getConfig Camera fov_")
+    fovEditbox:setText(currentFov)
+
+    -- fps limit editbox
+    local fpsEditbox = winMgr:getWindow("orxonox/Settings/FpsLimit")
+    local currentFpsLimit = orxonox.CommandExecutor:query("getConfig GraphicsSettings fpsLimit")
+    fpsEditbox:setText(currentFpsLimit)
+
+    -- particle lod combobox
+    local particleLodCombobox = winMgr:getWindow("orxonox/Settings/ParticleLodCombobox")
+    local currentParticleLod = orxonox.CommandExecutor:query("getConfig GraphicsSettings particlesDetailLevel")
+
+    if currentParticleLod == "" then
+        particleLodCombobox:disable()
+    else
+        particleLodCombobox:enable()
+
+        for i = 0, particleLodCombobox:getDropList():getItemCount() - 1 do
+            local item = particleLodCombobox:getListboxItemFromIndex(i)
+            particleLodCombobox:setItemSelectState(item, (tostring(i) == currentParticleLod))
         end
-        if search_mode == 1 then
-            if string.sub(line, 1, 11) == "Full Screen" then
-                if string.sub(line, 13) == "Yes" then
-                    fullscreen = true
-                else
-                    fullscreen = false
-                end
-            end
-            if string.sub(line, 1, 10) == "Video Mode" then
-                if string.match(line, "@") == "@" then
-                    resolution = string.sub(line, 12, string.find(line, "@")-2)
-                else
-                    resolution = string.sub(line, 12)
-                end
-                break
-            end
+    end
+
+    -- mesh lod checkbox
+    local meshLodCheckbox = winMgr:getWindow("orxonox/Settings/MeshLodCheckbox")
+    local hasMeshLod = orxonox.CommandExecutor:query("getConfig GraphicsSettings enableMeshLoD")
+    if hasMeshLod == "true" then
+        hasMeshLod = true
+    elseif hasMeshLod == "false" then
+        hasMeshLod = false
+    end
+    CEGUI.toCheckbox(meshLodCheckbox):setSelected(hasMeshLod)
+
+    -- motion blur checkbox
+    local motionBlurCheckbox = winMgr:getWindow("orxonox/Settings/MotionBlurCheckbox")
+    local hasMotionBlur = orxonox.CommandExecutor:query("getConfig GraphicsSettings enableMotionBlur")
+    if hasMotionBlur == "true" then
+        hasMotionBlur = true
+    elseif hasMotionBlur == "false" then
+        hasMotionBlur = false
+    end
+    CEGUI.toCheckbox(motionBlurCheckbox):setSelected(hasMotionBlur)
+end
+
+function P:onWindowResized()
+    -- fullscreen checkbox
+    local fullscreenCheckbox = winMgr:getWindow("orxonox/Display/Resolution/Fullscreen")
+    local isFullscreen = orxonox.GraphicsManager:getInstance():isFullScreen()
+    CEGUI.toCheckbox(fullscreenCheckbox):setSelected(isFullscreen)
+
+    -- resolution combobox
+    local resolutionCombobox = winMgr:getWindow("orxonox/Display/Resolution/Combobox")
+
+    local currentWidth = orxonox.GraphicsManager:getInstance():getWindowWidth()
+    local currentHeight = orxonox.GraphicsManager:getInstance():getWindowHeight()
+
+    if P.forceResolutionEditboxes then
+        currentWidth = P.newWidth
+        currentHeight = P.newHeight
+        P.forceResolutionEditboxes = false
+    end
+
+    local currentResolution = currentWidth .. " x " .. currentHeight
+
+    for i = 0, resolutionCombobox:getDropList():getItemCount() - 1 do
+        local item = resolutionCombobox:getListboxItemFromIndex(i)
+        resolutionCombobox:setItemSelectState(item, item:getText() == currentResolution)
+    end
+
+    -- resolution editboxes
+    self.updateResolutionEditboxes()
+end
+
+----------------------
+-- Helper functions --
+----------------------
+
+-- updates the text of the resolution checkboxes and checks if they should be enabled (only if the "custom" resolution was selected)
+function P.updateResolutionEditboxes()
+    -- resolution combobox
+    local resolutionCombobox = winMgr:getWindow("orxonox/Display/Resolution/Combobox")
+
+    local currentWidth = orxonox.GraphicsManager:getInstance():getWindowWidth()
+    local currentHeight = orxonox.GraphicsManager:getInstance():getWindowHeight()
+
+    -- resolution editboxes
+    local widthEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxWidth")
+    local heightEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxHeight")
+    widthEditbox:disable()
+    heightEditbox:disable()
+
+    -- selected combobox item
+    local item = resolutionCombobox:getSelectedItem()
+    if item then
+        local itemText = item:getText()
+        if itemText ~= "custom" then
+            currentWidth = string.sub(itemText, 1, string.find(itemText, "x") - 2)
+            currentHeight = string.sub(itemText, string.find(itemText, "x") + 2)
+        else
+            widthEditbox:enable()
+            heightEditbox:enable()
         end
     end
-    f:close()
-    local fullscreenwindow = tolua.cast(winMgr:getWindow("orxonox/FullscreenCheckbox"),"CEGUI::Checkbox")
-    fullscreenwindow:setSelected(fullscreen)
-    listboxwindow = winMgr:getWindow("orxonox/ResolutionListbox")
-    local resolutionList = {}
-    table.insert(resolutionList, "640 x 480")
-    table.insert(resolutionList, "720 x 480")
-    table.insert(resolutionList, "720 x 576")
-    table.insert(resolutionList, "800 x 480")
-    table.insert(resolutionList, "800 x 600")
-    table.insert(resolutionList, "1024 x 480")
-    table.insert(resolutionList, "1024 x 600")
-    table.insert(resolutionList, "1024 x 768")
-    table.insert(resolutionList, "1152 x 864")
-    table.insert(resolutionList, "1280 x 720")
-    table.insert(resolutionList, "1280 x 768")
-    table.insert(resolutionList, "1440 x 900")
-    for k,v in pairs(resolutionList) do
-        item = CEGUI.createListboxTextItem(v)
-        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-        CEGUI.toListbox(listboxwindow):addItem(item)
-    end
-    if resolution == "640 x 480" then
-        listboxwindow:setItemSelectState(0,true)
-    elseif resolution == "720 x 480" then
-        listboxwindow:setItemSelectState(1,true)
-    elseif resolution == "720 x 576" then
-        listboxwindow:setItemSelectState(2,true)
-    elseif resolution == "800 x 480" then
-        listboxwindow:setItemSelectState(3,true)
-    elseif resolution == "800 x 600" then
-        listboxwindow:setItemSelectState(4,true)
-    elseif resolution == "1024 x 480" then
-        listboxwindow:setItemSelectState(5,true)
-    elseif resolution == "1024 x 600" then
-        listboxwindow:setItemSelectState(6,true)
-    elseif resolution == "1024 x 768" then
-        listboxwindow:setItemSelectState(7,true)
-    elseif resolution == "1152 x 864" then
-        listboxwindow:setItemSelectState(8,true)
-    elseif resolution == "1280 x 720" then
-        listboxwindow:setItemSelectState(9,true)
-    elseif resolution == "1280 x 768" then
-        listboxwindow:setItemSelectState(10,true)
-    elseif resolution == "1440 x 900" then
-        listboxwindow:setItemSelectState(11,true)
-    end
-    scrollbar_active = false
-    block = false
-
-    local item = {
-            ["button"] = winMgr:getWindow("orxonox/GraphicsBackButton"),
-            ["function"]  = P.GraphicsBackButton_clicked
-    }
-    P.buttonList[1] = item
-
-    local dropbox = winMgr:getWindow("orxonox/ThemeDropBox")
-    local scheme = orxonox.CommandExecutor:query("getConfig GUIManager guiScheme_")
-    for k,v in pairs(P.schemeList) do
-        local item = CEGUI.createListboxTextItem(P.schemeList[k])
-        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-        CEGUI.toListbox(dropbox):addItem(item)
-        if v == scheme then
-            dropbox:setItemSelectState(item, true)
-        end
-    end
-
-end
-
-function P.ThemeDropBox_changed(e)
-    local dropbox = winMgr:getWindow("orxonox/ThemeDropBox")
-    local listbox = CEGUI.toListbox(dropbox)
-    local choice = listbox:getFirstSelectedItem()
-    local index = 0
-    if choice ~= nil then
-        index = listbox:getItemIndex(choice)
-    end
-    orxonox.CommandExecutor:execute("config GUIManager guiScheme_ " .. P.schemeList[index+1])
-end
-
-function P.GraphicsResolutionListbox_changed(e)
-    if listboxwindow:isItemSelected(0) then
-        resolution = "640 x 480"
-    elseif listboxwindow:isItemSelected(1) then
-        resolution = "720 x 480"
-    elseif listboxwindow:isItemSelected(2) then
-        resolution = "720 x 576"
-    elseif listboxwindow:isItemSelected(3) then
-        resolution = "800 x 480"
-    elseif listboxwindow:isItemSelected(4) then
-        resolution = "800 x 600"
-    elseif listboxwindow:isItemSelected(5) then
-        resolution = "1024 x 480"
-    elseif listboxwindow:isItemSelected(6) then
-        resolution = "1024 x 600"
-    elseif listboxwindow:isItemSelected(7) then
-        resolution = "1024 x 768"
-    elseif listboxwindow:isItemSelected(8) then
-        resolution = "1152 x 864"
-    elseif listboxwindow:isItemSelected(9) then
-        resolution = "1280 x 720"
-    elseif listboxwindow:isItemSelected(10) then
-        resolution = "1280 x 768"
-    elseif listboxwindow:isItemSelected(11) then
-        resolution = "1440 x 900"
-    end
-    search_mode = 0
-    f = io.open(file, "r")
-    firstline = f:read("*line")
-    text = firstline .. "\n"
-    rendersystem = string.sub(firstline, 15)
-    for line in f:lines() do
-        if search_mode == 0 then
-            if string.find(line, rendersystem) ~= nil then
-                search_mode = 1
-            end
-        end
-        if search_mode == 1 then
-            if string.sub(line, 1, 10) == "Video Mode" then
-                if string.match(line, "@") == "@" then
-                    line = "Video Mode=" .. resolution .. string.sub(line, string.find(line, "@")-1)
-                else
-                    line = "Video Mode=" .. resolution
-                end
-                search_mode = 2
-            end
-        end
-        text = text .. line .. "\n"
-    end
-    f:close()
-    f = io.open(file, "w")
-    f:write(text)
-    f:close()
-end
-
-function P.GraphicsBrightnessScrollbar_changed(e)
-    if scrollbar_active == false then
-        -- brightness
-        logMessage(0, "event: brightness")
-    end
-end
-
-function P.GraphicsBrightnessScrollbar_started(e)
-    scrollbar_active = true
-end
-
-function P.GraphicsBrightnessScrollbar_ended(e)
-    -- brightness
-    logMessage(0, "event: brightness")
-    scrollbar_active = false
-end
-
-function P.GraphicsFullscreenCheckbox_clicked(e)
-    if block == false then
-        search_mode = 0
-        f = io.open(file, "r")
-        firstline = f:read("*line")
-        text = firstline .. "\n"
-        rendersystem = string.sub(firstline, 15)
-        for line in f:lines() do
-            if search_mode == 0 then
-                if string.find(line, rendersystem) ~= nil then
-                    search_mode = 1
-                end
-            end
-            if search_mode == 1 then
-                if string.sub(line, 1, 11) == "Full Screen" then
-                    if fullscreen == true then
-                        line = "Full Screen=No"
-                        fullscreen = false
-                    else
-                        line = "Full Screen=Yes"
-                        fullscreen = true
-                    end
-                    search_mode = 2
-                end
-            end
-            text = text .. line .. "\n"
-        end
-        f:close()
-        f = io.open(file, "w")
-        f:write(text)
-        f:close()
-    end
-end
-
-function P.GraphicsBackButton_clicked(e)
+
+    widthEditbox:setText(currentWidth)
+    heightEditbox:setText(currentHeight)
+end
+
+-- checks if the apply button should be enabled or disabled (only enabled if the current settings are different from the selected values)
+function P.updateApplyButton()
+    -- fullscreen checkbox
+    local fullscreenCheckbox = winMgr:getWindow("orxonox/Display/Resolution/Fullscreen")
+    local isFullscreen = orxonox.GraphicsManager:getInstance():isFullScreen()
+    local fullscreenChanged = (isFullscreen ~= CEGUI.toCheckbox(fullscreenCheckbox):isSelected())
+
+    -- resolution editboxes
+    local widthEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxWidth")
+    local heightEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxHeight")
+    local currentWidth = tostring(orxonox.GraphicsManager:getInstance():getWindowWidth())
+    local currentHeight = tostring(orxonox.GraphicsManager:getInstance():getWindowHeight())
+    local widthChanged = (currentWidth ~= widthEditbox:getText())
+    local heightChanged = (currentHeight ~= heightEditbox:getText())
+    local resolutionEditboxesEnabled = not widthEditbox:isDisabled()
+
+    -- apply button
+    local applyButton = winMgr:getWindow("orxonox/Display/Resolution/Apply")
+
+    if fullscreenChanged or widthChanged or heightChanged or resolutionEditboxesEnabled then
+        applyButton:enable()
+    else
+        applyButton:disable()
+    end
+end
+
+function P.updateRedLabel()
+    -- theme
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    local currentTheme = orxonox.CommandExecutor:query("getConfig GUIManager guiScheme_")
+    local themeChanged = (currentTheme ~= themeCombobox:getText())
+
+    -- vsync
+    local vsyncCheckbox = winMgr:getWindow("orxonox/Display/More/VSync")
+    local hasVSync = orxonox.GraphicsManager:getInstance():hasVSyncEnabled()
+    local vsyncChanged = (hasVSync ~= CEGUI.toCheckbox(vsyncCheckbox):isSelected())
+
+    -- fsaa
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    local currentFSAAMode = orxonox.GraphicsManager:getInstance():getFSAAMode()
+    local fsaaChanged = (currentFSAAMode ~= fsaaCombobox:getText())
+
+    local needRestart = themeChanged or vsyncChanged or fsaaChanged
+
+    local notice = winMgr:getWindow("orxonox/Display/Notice")
+    notice:setVisible(not needRestart)
+    local noticeRed = winMgr:getWindow("orxonox/Display/NoticeRed")
+    noticeRed:setVisible(needRestart)
+end
+
+---------------------
+-- Event callbacks --
+---------------------
+
+-- resolution
+
+function P.callback_FullscreenCheckbox_CheckStateChanged(e)
+    P.updateApplyButton()
+end
+
+function P.callback_ResolutionCombobox_ListSelectionAccepted(e)
+    P.updateResolutionEditboxes()
+end
+
+function P.callback_ResolutionEditboxWidth_TextChanged(e)
+    P.updateApplyButton()
+end
+
+function P.callback_ResolutionEditboxHeight_TextChanged(e)
+    P.updateApplyButton()
+end
+
+-- theme
+
+function P.callback_ThemeCombobox_ListSelectionAccepted(e)
+    P.updateRedLabel()
+end
+
+-- vsync
+
+function P.callback_VSyncCheckbox_CheckStateChanged(e)
+    P.updateRedLabel()
+end
+
+-- fsaa
+
+function P.callback_FSAACombobox_ListSelectionAccepted(e)
+    P.updateRedLabel()
+end
+
+-- buttons
+
+function P.callback_Apply_Clicked(e)
+    -- resolution
+    local fullscreenCheckbox = winMgr:getWindow("orxonox/Display/Resolution/Fullscreen")
+    local checkedFullscreen = tostring(CEGUI.toCheckbox(fullscreenCheckbox):isSelected())
+
+    local widthEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxWidth")
+    local heightEditbox = winMgr:getWindow("orxonox/Display/Resolution/EditboxHeight")
+
+    P.newWidth = widthEditbox:getText()
+    P.newHeight = heightEditbox:getText()
+    P.forceResolutionEditboxes = true
+
+    -- start revert timer
+    P.oldWidth = orxonox.GraphicsManager:getInstance():getWindowWidth()
+    P.oldHeight = orxonox.GraphicsManager:getInstance():getWindowHeight()
+    P.oldFullscreen = orxonox.GraphicsManager:getInstance():isFullScreen()
+
+    P.revertTimerHandle = orxonox.CommandExecutor:query("delayreal 10 {hideGUI DecisionPopup; GraphicsManager setScreenResolution " .. P.oldWidth .. " " .. P.oldHeight .. " " .. tostring(P.oldFullscreen) .. "; config Core lastLevelTimestamp_ [expr [getConfig Core ogreConfigTimestamp_] + 1]}")
+
+    -- change settings
+    orxonox.CommandExecutor:execute("GraphicsManager setScreenResolution " .. P.newWidth .. " " .. P.newHeight .. " " .. checkedFullscreen)
+
+    P.updateApplyButton()
+
+    -- prompt for confirmation
+    openDecisionPopup("Do you want to keep these settings? (Settings will be reverted in 10 seconds if not accepted)", GraphicsMenu.callback_ApplyDecisionPopup)
+    if checkedFullscreen then
+        showCursor()
+    end
+end
+
+function P.callback_ApplyDecisionPopup(pressedOK)
+    orxonox.CommandExecutor:execute("killdelay " .. P.revertTimerHandle)
+
+    if not pressedOK then
+        orxonox.CommandExecutor:execute("GraphicsManager setScreenResolution " .. P.oldWidth .. " " .. P.oldHeight .. " " .. tostring(P.oldFullscreen))
+        P:onShow()
+    end
+
+    -- update timestamp to avoid showing the ogre config dialog again after the user accepted or reverted the resolution
+    orxonox.CommandExecutor:execute("config Core lastLevelTimestamp_ [expr [getConfig Core ogreConfigTimestamp_] + 1]")
+end
+
+function P.callback_Ok_Clicked(e)
+    -- aspect ratio
+    local aspectRatioEditbox = winMgr:getWindow("orxonox/Display/Resolution/AspectRatio")
+    orxonox.CommandExecutor:execute("config Camera aspectRatio_ " .. aspectRatioEditbox:getText())
+
+    -- theme
+    local themeCombobox = winMgr:getWindow("orxonox/Display/Theme/Combobox")
+    orxonox.CommandExecutor:execute("config GUIManager guiScheme_ " .. themeCombobox:getText())
+
+    -- vsync
+    local vsyncCheckbox = winMgr:getWindow("orxonox/Display/More/VSync")
+    local hasVSync = orxonox.GraphicsManager:getInstance():hasVSyncEnabled()
+    if hasVSync ~= CEGUI.toCheckbox(vsyncCheckbox):isSelected() then
+        orxonox.CommandExecutor:execute("GraphicsManager setVSync " .. tostring(CEGUI.toCheckbox(vsyncCheckbox):isSelected()))
+    end
+
+    -- fsaa
+    local fsaaCombobox = winMgr:getWindow("orxonox/Display/More/FSAA")
+    local currentFSAAMode = orxonox.GraphicsManager:getInstance():getFSAAMode()
+    if currentFSAAMode ~= fsaaCombobox:getText() then
+        orxonox.CommandExecutor:execute("GraphicsManager setFSAA {" .. fsaaCombobox:getText() .. "}") -- enclose argument in { ... } because it can contain [brackets] (conflicts with tcl)
+    end
+
+    -- fov
+    local fovEditbox = winMgr:getWindow("orxonox/Settings/Fov")
+    orxonox.CommandExecutor:execute("config Camera fov_ " .. fovEditbox:getText())
+
+    -- fps limit
+    local fpsEditbox = winMgr:getWindow("orxonox/Settings/FpsLimit")
+    orxonox.CommandExecutor:execute("config GraphicsSettings fpsLimit " .. fpsEditbox:getText())
+
+    -- particle lod
+    local particleLodCombobox = winMgr:getWindow("orxonox/Settings/ParticleLodCombobox")
+    local item = particleLodCombobox:getSelectedItem()
+    if item then
+        orxonox.CommandExecutor:execute("config GraphicsSettings particlesDetailLevel " .. particleLodCombobox:getItemIndex(item))
+    end
+
+    -- mesh lod
+    local meshLodCheckbox = winMgr:getWindow("orxonox/Settings/MeshLodCheckbox")
+    orxonox.CommandExecutor:execute("config GraphicsSettings enableMeshLoD " .. tostring(CEGUI.toCheckbox(meshLodCheckbox):isSelected()))
+
+    -- motion blur
+    local motionBlurCheckbox = winMgr:getWindow("orxonox/Settings/MotionBlurCheckbox")
+    orxonox.CommandExecutor:execute("config GraphicsSettings enableMotionBlur " .. tostring(CEGUI.toCheckbox(motionBlurCheckbox):isSelected()))
+
     hideMenuSheet(P.name)
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 1)
+function P.callback_Cancel_Clicked(e)
+    hideMenuSheet(P.name)
 end
 
Index: code/trunk/data/gui/scripts/HostMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/HostMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/HostMenu.lua	(revision 8079)
@@ -5,5 +5,4 @@
 P.multiplayerMode = "startServer"
 
-P.buttonList = {}
 P.levelList = {}
 P.itemList = {}
@@ -11,5 +10,5 @@
 
 function P.onLoad()
-    P.multiplayerMode = "startServer" 
+    P.multiplayerMode = "startServer"
     local window = winMgr:getWindow("orxonox/MultiplayerShowAllCheckbox")
     local button = tolua.cast(window,"CEGUI::Checkbox")
@@ -17,18 +16,23 @@
     P.createLevelList()
 
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/HostMenuStartButton"),
-            ["function"]  = P.HostMenuStartButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.HostMenuStartButton_clicked
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/HostMenuBackButton"),
-            ["function"]  = P.HostMenuBackButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.HostMenuBackButton_clicked
+    })
 end
 
 function P.onShow()
+    if P.showAll ~= orxonox.GUIManager:inDevMode() then
+        local window = winMgr:getWindow("orxonox/MultiplayerShowAllCheckbox")
+        local button = tolua.cast(window,"CEGUI::Checkbox")
+        P.showAll = not P.showAll
+        button:setSelected(P.showAll)
+    end
+
     if P.multiplayerMode == "startServer" then
         local window = winMgr:getWindow("orxonox/HostMenuHostButton")
@@ -44,8 +48,4 @@
         P.createLevelList()
     end
-
-    P.oldindex = -2
-    P.index = -1
-
 end
 
@@ -97,5 +97,5 @@
 end
 
-function P.HostMenuStartButton_clicked(e)    
+function P.HostMenuStartButton_clicked(e)
     local listbox = CEGUI.toListbox(winMgr:getWindow("orxonox/HostMenuListbox"))
     local choice = listbox:getFirstSelectedItem()
@@ -119,7 +119,3 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 2)
-end
-
 return P
Index: code/trunk/data/gui/scripts/InGameMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/InGameMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/InGameMenu.lua	(revision 8079)
@@ -4,40 +4,39 @@
 P.loadAlong = { "DecisionPopup" }
 
-P.buttonList = {}
-
 function P.onLoad()
-    P.multiplayerMode = "startClient" 
+    P.multiplayerMode = "startClient"
 
     --button are arranged in a 4x1 matrix, the left lower item is nil
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_ReturnButton"),
-            ["function"]  = P.button_settings_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.button_return_clicked
+    })
 
-    local item = {
+    P:setButton(2, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_MainMenuButton"),
-            ["function"]  = P.button_mainmenu_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.button_mainmenu_clicked
+    })
 
-    local item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_SettingsButton"),
-            ["function"]  = P.button_settings_clicked
-    }
-    P.buttonList[3] = item
+            ["callback"]  = P.button_settings_clicked
+    })
 
-    local item = {
+    P:setButton(4, 1, {
             ["button"] = winMgr:getWindow("orxonox/InGameMenu_QuitButton"),
-            ["function"]  = P.button_quit_clicked
-    }
-    P.buttonList[4] = item
-
+            ["callback"]  = P.button_quit_clicked
+    })
 end
 
 function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
+    if P:hasSelection() == false then
+        P:setSelection(1, 1)
+    end
+
+    orxonox.execute("setPause 1")
+end
+
+function P.onQuit()
+    orxonox.execute("setPause 0")
 end
 
@@ -64,13 +63,9 @@
         hideMenuSheet("InGameMenu")
         orxonox.execute("exit")
-    else 
+    else
         P.onShow()
     end
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 4, 1)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/KeyBindMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/KeyBindMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/KeyBindMenu.lua	(revision 8079)
@@ -26,5 +26,5 @@
     table.insert(commandList, "NewHumanController changeMode")
     table.insert(commandList, "switchCamera")
-    table.insert(commandList, "openConsole")
+    table.insert(commandList, "InGameConsole openConsole")
     table.insert(commandList, "OverlayGroup toggleVisibility Debug")
     table.insert(commandList, "OverlayGroup toggleVisibility Stats")
@@ -35,4 +35,8 @@
     table.insert(commandList, "mouseLook")
     table.insert(commandList, "pause")
+    table.insert(commandList, "printScreen")
+    if orxonox.GUIManager:inDevMode() then
+        table.insert(commandList, "printScreenHD 3")
+    end
 
     nameList = {}
@@ -65,4 +69,8 @@
     table.insert(nameList, "Look Around")
     table.insert(nameList, "Pause")
+    table.insert(nameList, "Screenshot")
+    if orxonox.GUIManager:inDevMode() then
+        table.insert(nameList, "HD screenshot")
+    end
 
     linesList = {}
@@ -100,4 +108,9 @@
     local funct = luaState:createLuaFunctor("KeyBindMenu.callback()")
     orxonox.KeyBinderManager:getInstance():registerKeybindCallback(funct)
+
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/KeyBindBackButton"),
+            ["callback"]  = P.KeyBindBackButton_clicked
+    })
 end
 
Index: code/trunk/data/gui/scripts/MainMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MainMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/MainMenu.lua	(revision 8079)
@@ -4,49 +4,35 @@
 P.loadAlong = { "SingleplayerMenu", "MultiplayerMenu", "SettingsMenu", "CreditsMenu" }
 
-P.buttonList = {}
-
 function P.onLoad()
     --buttons are arranged in a 6x1 Matrix (list)
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/QuickGameTestButton"),
-            ["function"]  = P.QuickGameTestButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.QuickGameTestButton_clicked
+    })
 
-    item = {
+    P:setButton(2, 1, {
             ["button"] = winMgr:getWindow("orxonox/SingleplayerButton"),
-            ["function"]  = P.SingleplayerButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.SingleplayerButton_clicked
+    })
 
-    item = {
+    P:setButton(3, 1, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerButton"),
-            ["function"]  = P.MultiplayerButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.MultiplayerButton_clicked
+    })
 
-    item = {
+    P:setButton(4, 1, {
             ["button"] = winMgr:getWindow("orxonox/SettingsButton"),
-            ["function"]  = P.SettingsButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.SettingsButton_clicked
+    })
 
-    item = {
+    P:setButton(5, 1, {
             ["button"] = winMgr:getWindow("orxonox/CreditsButton"),
-            ["function"]  = P.CreditsButton_clicked
-    }
-    table.insert(P.buttonList,item)
+            ["callback"]  = P.CreditsButton_clicked
+    })
 
-    item = {
+    P:setButton(6, 1, {
             ["button"] = winMgr:getWindow("orxonox/ExitButton"),
-            ["function"]  = P.ExitButton_clicked
-    }
-    table.insert(P.buttonList,item) 
-end
-
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
+            ["callback"]  = P.ExitButton_clicked
+    })
 end
 
@@ -77,8 +63,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 6, 1)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/MiscConfigMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MiscConfigMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/MiscConfigMenu.lua	(revision 8079)
@@ -35,4 +35,5 @@
     table.insert(P.commandList, "HumanPlayer nick_")
     table.insert(P.commandList, "ChatOverlay displayTime_")
+    table.insert(P.commandList, "Core bDevMode_")
 
     P.nameList = {}
@@ -54,4 +55,5 @@
     table.insert(P.nameList, "Playername")
     table.insert(P.nameList, "Chat: display time")
+    table.insert(P.nameList, "Developer's Mode")
 
     P.linesList = {}
@@ -85,4 +87,8 @@
     P.createLines()
 
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/MiscConfigMenu/MiscConfigBackButton"),
+            ["callback"]  = P.MiscConfigBackButton_clicked
+    })
 end
 
Index: code/trunk/data/gui/scripts/MouseControlsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MouseControlsMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/MouseControlsMenu.lua	(revision 8079)
@@ -32,4 +32,9 @@
         invert_active = false
     end
+
+    P:setButton(1, 1, {
+            ["button"] = winMgr:getWindow("orxonox/MouseControlsBackButton"),
+            ["callback"]  = P.MouseControlsBackButton_clicked
+    })
 end
 
Index: code/trunk/data/gui/scripts/MultiplayerMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/MultiplayerMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/MultiplayerMenu.lua	(revision 8079)
@@ -2,6 +2,4 @@
 
 local P = createMenuSheet("MultiplayerMenu")
-
-P.buttonList = {}
 
 --joinMode is 1 for choice "LAN" and 2 for "Internet"
@@ -10,24 +8,21 @@
 
 function P.onLoad()
-    P.multiplayerMode = "startClient" 
+    P.multiplayerMode = "startClient"
 
-    --button are arranged in a 2x2 matrix, the left lower item is nil
-    local item = {
+    --button are arranged in a 3x2 matrix, Join and Host buttons are in the upper left and middle, the back button in the lower right of the table
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerJoinButton"),
-            ["function"]  = P.MultiplayerJoinButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.MultiplayerJoinButton_clicked
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerHostButton"),
-            ["function"]  = P.MultiplayerHostButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.MultiplayerHostButton_clicked
+    })
 
-    local item = {
+    P:setButton(2, 3, {
             ["button"] = winMgr:getWindow("orxonox/MultiplayerBackButton"),
-            ["function"]  = P.MultiplayerBackButton_clicked
-    }
-    P.buttonList[4] = item
+            ["callback"]  = P.MultiplayerBackButton_clicked
+    })
 end
 
@@ -35,8 +30,4 @@
     --P.showServerList()
 
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
-    
     if P.joinMode == 1 then
         local window = winMgr:getWindow("orxonox/MultiplayerLanButton")
@@ -56,5 +47,5 @@
     P.joinMode = 1
     if button:isSelected() == true then
-	    P.showServerList()
+        P.showServerList()
     end
 end
@@ -65,6 +56,6 @@
     P.joinMode = 2
     if button:isSelected() == true then
-	    P.showServerList()
-	end
+        P.showServerList()
+    end
 end
 
@@ -92,72 +83,68 @@
 
 function P.showServerList()
-	-- LAN Discovery
-	if P.joinMode == 1 then
-		local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
-		CEGUI.toListbox(listbox):resetList()
-		local discovery = orxonox.LANDiscovery:getInstance()
-		discovery:discover()
-		P.serverList = {}
-		local index = 0
-		local servername = ""
-		local serverip = ""
-		while true do
-		    servername = discovery:getServerListItemName(index)
-		    if servername == "" then
-		        break
-		    end
-		    serverip = discovery:getServerListItemIP(index)
-		    if serverip == "" then
-		      break
-		    end
-		    table.insert(P.serverList, {servername, serverip})
-		    index = index + 1
-		end
-		index = 1
-		for k,v in pairs(P.serverList) do
-		    local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
-		    item:setID(index)
-		    index = index + 1
-		    item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-		    CEGUI.toListbox(listbox):addItem(item)
-		end
-	-- WAN Discovery
-	elseif P.joinMode == 2 then
-		local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
-		CEGUI.toListbox(listbox):resetList()
-		local discovery = orxonox.WANDiscovery:getInstance()
-		cout(0, "discovering.\n" )
-		discovery:discover()
-		cout(0, "discovered.\n" )
-		P.serverList = {}
-		local index = 0
-		local servername = ""
-		local serverip = ""
-		while true do
-		    servername = discovery:getServerListItemName(index)
-		    if servername == "" then
-		        break
-		    end
-		    serverip = discovery:getServerListItemIP(index)
-		    if serverip == "" then
-		      break
-		    end
-		    table.insert(P.serverList, {servername, serverip})
-		    index = index + 1
-		end
-		index = 1
-		for k,v in pairs(P.serverList) do
-		    local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
-		    item:setID(index)
-		    index = index + 1
-		    item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
-		    CEGUI.toListbox(listbox):addItem(item)
-		end
-	end
-	
-end
+    -- LAN Discovery
+    if P.joinMode == 1 then
+        local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
+        CEGUI.toListbox(listbox):resetList()
+        local discovery = orxonox.LANDiscovery:getInstance()
+        discovery:discover()
+        P.serverList = {}
+        local index = 0
+        local servername = ""
+        local serverip = ""
+        while true do
+            servername = discovery:getServerListItemName(index)
+            if servername == "" then
+                break
+            end
+            serverip = discovery:getServerListItemIP(index)
+            if serverip == "" then
+                break
+            end
+            table.insert(P.serverList, {servername, serverip})
+            index = index + 1
+        end
+        index = 1
+        for k,v in pairs(P.serverList) do
+            local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
+            item:setID(index)
+            index = index + 1
+            item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+            CEGUI.toListbox(listbox):addItem(item)
+        end
+    -- WAN Discovery
+    elseif P.joinMode == 2 then
+        local listbox = winMgr:getWindow("orxonox/MultiplayerListbox")
+        CEGUI.toListbox(listbox):resetList()
+        local discovery = orxonox.WANDiscovery:getInstance()
+        cout(0, "discovering.\n" )
+        discovery:discover()
+        cout(0, "discovered.\n" )
+        P.serverList = {}
+        local index = 0
+        local servername = ""
+        local serverip = ""
+        while true do
+            servername = discovery:getServerListItemName(index)
+            if servername == "" then
+                break
+            end
+            serverip = discovery:getServerListItemIP(index)
+            if serverip == "" then
+                break
+            end
+            table.insert(P.serverList, {servername, serverip})
+            index = index + 1
+        end
+        index = 1
+        for k,v in pairs(P.serverList) do
+            local item = CEGUI.createListboxTextItem( v[1] .. ": " .. v[2] )
+            item:setID(index)
+            index = index + 1
+            item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+            CEGUI.toListbox(listbox):addItem(item)
+        end
+    end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 2, 2)
 end
 
Index: code/trunk/data/gui/scripts/NotificationLayer.lua
===================================================================
--- code/trunk/data/gui/scripts/NotificationLayer.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/NotificationLayer.lua	(revision 8079)
@@ -46,5 +46,5 @@
 end
 
--- Pushes an input notification to the input queue. 
+-- Pushes an input notification to the input queue.
 function P.pushNotification(queueName, notification)
     local queue = P.queueList[queueName]
@@ -333,5 +333,5 @@
 
 -- Is called after the sheet has been hidden.
-function P.afterHide()
+function P.onQuit()
     -- If we leave the edit mode we show the sheet again.
     if P.editMode then
Index: code/trunk/data/gui/scripts/SettingsMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/SettingsMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/SettingsMenu.lua	(revision 8079)
@@ -4,46 +4,33 @@
 P.loadAlong = { "ControlsMenu", "AudioMenu", "GraphicsMenu" }
 
-P.buttonList = {}
-
 function P.onLoad()
     --"Gameplay" and "Multiplayer Options" are not integrated in the list
-    --buttons are arranged in a 4x2 matrix. The lower-right element is not in the matrix!
-    local item = {
+    --buttons are arranged in a 4x2 matrix.
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/GraphicsButton"),
-            ["function"]  = P.SettingsGraphicsButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.SettingsGraphicsButton_clicked
+    })
 
-    local item = {
+    P:setButton(2, 2, {
             ["button"] = winMgr:getWindow("orxonox/SettingsMenu/AudioButton"),
-            ["function"]  = P.SettingsAudioButton_clicked
-    }
-    P.buttonList[4] = item
+            ["callback"]  = P.SettingsAudioButton_clicked
+    })
 
+    P:setButton(3, 1, {
+            ["button"] = winMgr:getWindow("orxonox/SettingsMenu/ControlsButton"),
+            ["callback"]  = P.SettingsControlsButton_clicked
+    })
 
-    local item = {
-            ["button"] = winMgr:getWindow("orxonox/SettingsMenu/ControlsButton"),
-            ["function"]  = P.SettingsControlsButton_clicked
-    }
-    P.buttonList[5] = item
+    P:setButton(3, 2, {
+            ["button"] = winMgr:getWindow("orxonox/SettingsMenu/MiscellaneousButton"),
+            ["callback"]  = P.SettingsMiscellaneousButton_clicked
+    })
 
-    local item = {
-            ["button"] = winMgr:getWindow("orxonox/SettingsMenu/MiscellaneousButton"),
-            ["function"]  = P.SettingsMiscellaneousButton_clicked
-    }
-    P.buttonList[6] = item
+    P:setButton(4, 1, {
+            ["button"] = winMgr:getWindow("orxonox/SettingsMenu/SettingsBackButton"),
+            ["callback"]  = P.SettingsBackButton_clicked
+    })
 
-    local item = {
-            ["button"] = winMgr:getWindow("orxonox/SettingsMenu/SettingsBackButton"),
-            ["function"]  = P.SettingsBackButton_clicked
-    }
-    P.buttonList[7] = item
-
-end
-
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = 3
-    P.index = 2
+    P:setButton(4, 2, P:getButton(4, 1))
 end
 
@@ -76,8 +63,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 4, 2)
-end
-
 return P
 
Index: code/trunk/data/gui/scripts/SheetManager.lua
===================================================================
--- code/trunk/data/gui/scripts/SheetManager.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/SheetManager.lua	(revision 8079)
@@ -8,25 +8,21 @@
 local mainMenuLoaded = false
 orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "KeyDown", "keyPressed")
-
------------------------
---- Local functions ---
------------------------
-
-local function hideCursor()
-    if cursor:isVisible() then
-        cursor:hide()
-    end
-end
-
-local function showCursor()
-    if not cursor:isVisible() and inputMgr:isMouseExclusive() then
-        cursor:show()
-    end
-end
-
+orxonox.GUIManager:subscribeEventHelper(menuSheetsRoot, "Sized", "windowResized")
 
 ------------------------
 --- Global functions ---
 ------------------------
+
+function hideCursor()
+    if cursor:isVisible() then
+        cursor:hide()
+    end
+end
+
+function showCursor()
+    if not cursor:isVisible() and inputMgr:isMouseExclusive() then
+        cursor:show()
+    end
+end
 
 -- Loads the GUI with the specified name
@@ -93,5 +89,6 @@
         ["sheet"]          = menuSheet,
         ["bHidePrevious"]  = bHidePrevious,
-        ["bNoInput"]       = bNoInput
+        ["bNoInput"]       = bNoInput,
+        ["name"]           = name
     }
     table.insert(activeMenuSheets, sheetTuple) -- indexed array access
@@ -121,12 +118,19 @@
 
     -- Hide all previous sheets if necessary
+    local previous
     if bHidePrevious then
         for i = 1, activeMenuSheets.size - 1 do
-            activeMenuSheets[i].sheet:hide()
-        end
-    end
-    
+            previous = activeMenuSheets[i].sheet
+            previous:hide()
+        end
+    end
+
     menuSheet:show()
     menuSheetsRoot:activate()
+
+    -- select first button if the menu was opened with the keyboard
+    if previous and previous.pressedEnter and menuSheet:hasSelection() == false then
+        menuSheet:setSelectionNear(1, 1)
+    end
 
     return menuSheet
@@ -179,5 +183,5 @@
         inputMgr:leaveState(sheetTuple.sheet.inputState)
     end
-    
+
     -- CURSOR SHOWING
     local i = activeMenuSheets.size
@@ -200,5 +204,5 @@
     end
 
-    sheetTuple.sheet:afterHide()
+    sheetTuple.sheet:quit()
 end
 
@@ -242,8 +246,27 @@
             keyESC()
         elseif code == "0"then
-            orxonox.CommandExecutor:execute("openConsole")
-        end
-    end
-    sheet.sheet:onKeyPressed()
+            orxonox.CommandExecutor:execute("InGameConsole openConsole")
+        end
+    end
+    sheet.sheet:keyPressed()
+end
+
+function windowResized(e)
+    for name, sheet in pairs(loadedSheets) do
+        if orxonox.GraphicsManager:getInstance():isFullScreen() or sheet.tShowCursor == TriBool.False then
+            inputMgr:setMouseExclusive(sheet.inputState, TriBool.True)
+        else
+            inputMgr:setMouseExclusive(sheet.inputState, TriBool.False)
+        end
+    end
+    local sheetTuple = activeMenuSheets[activeMenuSheets.size]
+    if sheetTuple then
+        if orxonox.GraphicsManager:getInstance():isFullScreen() and sheetTuple.sheet.tShowCursor ~= TriBool.False then
+            showCursor()
+        else
+            hideCursor()
+        end
+        sheetTuple.sheet:windowResized()
+    end
 end
 
@@ -276,4 +299,14 @@
 end
 
+function getGUIFirstActive(name, bHidePrevious, bNoInput)
+    local sheet = activeMenuSheets.topSheetTuple
+    -- If the topmost gui sheet has the input name
+    if sheet ~= nil and sheet.name == name then
+        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, false);
+    else
+        guiMgr:toggleGUIHelper(name, bHidePrevious, bNoInput, true);
+    end
+end
+
 ----------------------
 --- Initialisation ---
Index: code/trunk/data/gui/scripts/SingleplayerMenu.lua
===================================================================
--- code/trunk/data/gui/scripts/SingleplayerMenu.lua	(revision 8078)
+++ code/trunk/data/gui/scripts/SingleplayerMenu.lua	(revision 8079)
@@ -3,5 +3,4 @@
 local P = createMenuSheet("SingleplayerMenu")
 
-P.buttonList = {}
 P.levelList = {}
 P.itemList = {}
@@ -15,15 +14,23 @@
 
     --buttons are arranged in a 1x2 matrix
-    local item = {
+    P:setButton(1, 1, {
             ["button"] = winMgr:getWindow("orxonox/SingleplayerStartButton"),
-            ["function"]  = P.SingleplayerStartButton_clicked
-    }
-    P.buttonList[1] = item
+            ["callback"]  = P.SingleplayerStartButton_clicked
+    })
 
-    local item = {
+    P:setButton(1, 2, {
             ["button"] = winMgr:getWindow("orxonox/SingleplayerBackButton"),
-            ["function"]  = P.SingleplayerBackButton_clicked
-    }
-    P.buttonList[2] = item
+            ["callback"]  = P.SingleplayerBackButton_clicked
+    })
+end
+
+function P.onShow()
+    if P.showAll ~= orxonox.GUIManager:inDevMode() then
+        local window = winMgr:getWindow("orxonox/SingleplayerShowAllCheckbox")
+        local button = tolua.cast(window,"CEGUI::Checkbox")
+        P.showAll = not P.showAll
+        button:setSelected(P.showAll)
+        P.createLevelList()
+    end
 end
 
@@ -47,6 +54,4 @@
         index = index + 1
     end
-    --TODO: Reintroduce sorting, if needed. At the moment it's sorted by filename.
-    --table.sort(levelList)
     for k,v in pairs(P.levelList) do
         local item = CEGUI.createListboxTextItem(v:getName())
@@ -59,10 +64,4 @@
         orxonox.GUIManager:setTooltipTextHelper(P.itemList[k], v:getDescription())
     end
-end
-
-function P.onShow()
-    --indices to iterate through buttonlist
-    P.oldindex = -2
-    P.index = -1
 end
 
@@ -93,8 +92,4 @@
 end
 
-function P.onKeyPressed() 
-    buttonIteratorHelper(P.buttonList, code, P, 1, 2)
-end
-
 return P
 
Index: code/trunk/data/levels/FPSTest.oxw
===================================================================
--- code/trunk/data/levels/FPSTest.oxw	(revision 8078)
+++ code/trunk/data/levels/FPSTest.oxw	(revision 8079)
@@ -57,5 +57,5 @@
   <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 100) ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>" >
       <attached>
-        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+        <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
       </attached>
       <collisionShapes>
Index: code/trunk/data/levels/asteroids.oxw
===================================================================
--- code/trunk/data/levels/asteroids.oxw	(revision 8078)
+++ code/trunk/data/levels/asteroids.oxw	(revision 8079)
@@ -35,10 +35,10 @@
       linearDamping = 0.8
       angularDamping = 0
-      scale = <?lua print(j * 150)?>
+      scale = "<?lua print(j * 150)?>"
       collisiondamage = 1
       enablecollisiondamage = true
     >
       <attached>
-        <Model mass=<?lua print(j * 1000) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+        <Model mass="<?lua print(j * 1000) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
       </attached>
       <collisionShapes>
Index: code/trunk/data/levels/dynamicMatch.oxw
===================================================================
--- code/trunk/data/levels/dynamicMatch.oxw	(revision 8078)
+++ code/trunk/data/levels/dynamicMatch.oxw	(revision 8079)
@@ -80,7 +80,7 @@
 ?>
 
-    <StaticEntity position="<?lua print(x + math.random() * 1000-500) ?>,<?lua print(y + math.random() * 1000-500) ?>,<?lua print(z + math.random() * 5000-2500) ?>" scale=<?lua print(j * 5) ?> >
+    <StaticEntity position="<?lua print(x + math.random() * 1000-500) ?>,<?lua print(y + math.random() * 1000-500) ?>,<?lua print(z + math.random() * 5000-2500) ?>" scale="<?lua print(j * 5) ?>" >
       <attached>
-        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh">
+        <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh">
 	  <attached><!-- ---------asteroid fog----- -->
             <ParticleEmitter position="0,0,0" source="Orxonox/Steam" />
Index: code/trunk/data/levels/fightInOurBack.oxw
===================================================================
--- code/trunk/data/levels/fightInOurBack.oxw	(revision 8078)
+++ code/trunk/data/levels/fightInOurBack.oxw	(revision 8079)
@@ -172,5 +172,5 @@
     <events>
     <trigger>
-        <SpaceShip position="<?lua print(3800-i*x) ?>,0,3000" lookat="<?lua print(4800-i*x) ?>,0,4000" health=<?lua print(health) ?> maxhealth=<?lua print(health) ?> initialhealth=<?lua print(health) ?> >
+        <SpaceShip position="<?lua print(3800-i*x) ?>,0,3000" lookat="<?lua print(4800-i*x) ?>,0,4000" health="<?lua print(health) ?>" maxhealth="<?lua print(health) ?>" initialhealth="<?lua print(health) ?>" >
             <templates>
                    <Template link=spaceshipTransporter />
@@ -199,5 +199,5 @@
     <events>
     <trigger>
-        <SpaceShip position="<?lua print(2600+x) ?>,0,<?lua print(3150-z) ?>" lookat="<?lua print(3500+x) ?>,0,<?lua print(4150-z) ?>" health=<?lua print(health) ?> maxhealth=<?lua print(health) ?> initialhealth=<?lua print(health) ?> >
+        <SpaceShip position="<?lua print(2600+x) ?>,0,<?lua print(3150-z) ?>" lookat="<?lua print(3500+x) ?>,0,<?lua print(4150-z) ?>" health="<?lua print(health) ?>" maxhealth="<?lua print(health) ?>" initialhealth="<?lua print(health) ?>" >
             <templates>
                    <Template link=spaceshipTransporter />
@@ -284,5 +284,5 @@
 <MovableEntity collisionType=kinematic linearDamping=0.8 angularDamping=0 mass="<?lua print(scale * 5) ?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" rotationaxis="<?lua print(math.random()) ?>,<?lua print(math.random()) ?>,<?lua print(math.random()) ?>" rotationrate="<?lua print(math.random()*15) ?>">
     <attached>
-        <Model scale=<?lua print(scale) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
+        <Model scale="<?lua print(scale) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
     </attached>
     <collisionShapes>
@@ -303,5 +303,5 @@
 <MovableEntity collisionType=kinematic linearDamping=0.8 angularDamping=0 mass="<?lua print(scale * 5) ?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" rotationaxis="<?lua print(math.random()) ?>,<?lua print(math.random()) ?>,<?lua print(math.random()) ?>" rotationrate="<?lua print(math.random()*15) ?>" >
     <attached>
-        <Model scale=<?lua print(math.random(20,70)) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
+        <Model scale="<?lua print(math.random(20,70)) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
     </attached>
     <collisionShapes>
Index: code/trunk/data/levels/lastManStanding.oxw
===================================================================
--- code/trunk/data/levels/lastManStanding.oxw	(revision 8078)
+++ code/trunk/data/levels/lastManStanding.oxw	(revision 8079)
@@ -76,5 +76,5 @@
     <SpawnPoint team=0 position="<?lua print(y*1.4+z*0.2) ?>,0,<?lua print(z*1.4-y*0.2) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
 
-    <StaticEntity position="<?lua print(y) ?>,0,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,0,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh">
@@ -86,5 +86,5 @@
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,100,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,100,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i+3,6) + 1) ?>.mesh">
@@ -96,5 +96,5 @@
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,200,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,200,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i*5,6) + 1) ?>.mesh">
@@ -106,5 +106,5 @@
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,-100,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,-100,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i*13+1,6) + 1) ?>.mesh">
@@ -116,5 +116,5 @@
     </StaticEntity>
 
-    <StaticEntity position="<?lua print(y) ?>,-200,<?lua print(z) ?>" scale=<?lua print(j * 2) ?> collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,-200,<?lua print(z) ?>" scale="<?lua print(j * 2) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=15 mesh="ast<?lua print( math.mod(i*17,6) + 1) ?>.mesh">
@@ -127,5 +127,5 @@
 
 <!-- ---------Top Asteroid----------- -->
-    <StaticEntity position="<?lua print(y) ?>,300,<?lua print(z) ?>" scale=<?lua print(j * 2.1) ?> pitch="90" roll="180" yaw="<?lua print(-90+i*360/max) ?>" collisionType=static >
+    <StaticEntity position="<?lua print(y) ?>,300,<?lua print(z) ?>" scale="<?lua print(j * 2.1) ?>" pitch="90" roll="180" yaw="<?lua print(-90+i*360/max) ?>" collisionType=static >
       <attached>
         <Model position="0,0,0" scale=25 mesh="ast6.mesh">
Index: code/trunk/data/levels/presentation09.oxw
===================================================================
--- code/trunk/data/levels/presentation09.oxw	(revision 8078)
+++ code/trunk/data/levels/presentation09.oxw	(revision 8079)
@@ -1,5 +1,5 @@
 <LevelInfo
- name = "Presentation X"
- description = "1st Presentation level for Orxonox Convention X"
+ name = "Presentation X 3rd"
+ description = "3rd Presentation level for Orxonox Convention X"
  tags = "presentation"
 />
@@ -47,7 +47,7 @@
       ?>
 
-      <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass="<?lua print(j * 50) ?>" <?lua end ?> scale="<?lua print(j * 5) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+          <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
         </attached>
         <?lua if i == 5 then ?><collisionShapes>
Index: code/trunk/data/levels/presentation09b.oxw
===================================================================
--- code/trunk/data/levels/presentation09b.oxw	(revision 8078)
+++ code/trunk/data/levels/presentation09b.oxw	(revision 8079)
@@ -281,5 +281,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -291,5 +291,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -357,5 +357,5 @@
       <MovableEntity position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
         </attached>
       </MovableEntity>
Index: code/trunk/data/levels/presentationDM.oxw
===================================================================
--- code/trunk/data/levels/presentationDM.oxw	(revision 8078)
+++ code/trunk/data/levels/presentationDM.oxw	(revision 8079)
@@ -46,7 +46,7 @@
         j = math.random()
     ?>
-      <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass="<?lua print(j * 50) ?>" scale="<?lua print(j * 5) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+          <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
         </attached>
         <collisionShapes>
Index: code/trunk/data/levels/presentationFS102.oxw
===================================================================
--- code/trunk/data/levels/presentationFS102.oxw	(revision 8078)
+++ code/trunk/data/levels/presentationFS102.oxw	(revision 8079)
@@ -1,4 +1,4 @@
 <LevelInfo
- name = "Presentation XI FPS"
+ name = "Presentation XI FPS 1st"
  description = "2nd Presentation level for Orxonox Convention XI, FPS"
  tags = "presentation"
Index: code/trunk/data/levels/presentationFS10Ed.oxw
===================================================================
--- code/trunk/data/levels/presentationFS10Ed.oxw	(revision 8078)
+++ code/trunk/data/levels/presentationFS10Ed.oxw	(revision 8079)
@@ -1,4 +1,4 @@
 <LevelInfo
- name = "Presentation XI FPS"
+ name = "Presentation XI FPS 2nd"
  description = "3rd Presentation level for Orxonox Convention XI, FPS"
  tags = "presentation"
Index: code/trunk/data/levels/presentationHS09.oxw
===================================================================
--- code/trunk/data/levels/presentationHS09.oxw	(revision 8078)
+++ code/trunk/data/levels/presentationHS09.oxw	(revision 8079)
@@ -1,4 +1,4 @@
 <LevelInfo
- name = "Presentation X"
+ name = "Presentation X 1st"
  description = "1st Presentation level for Orxonox Convention X"
  tags = "presentation"
@@ -193,5 +193,5 @@
         </templates>
         <controller>
-          <WaypointPatrolController name=attacker alertnessradius=<?lua print(math.random() * 2000) ?> team=0 active=false>
+          <WaypointPatrolController name=attacker alertnessradius="<?lua print(math.random() * 2000) ?>" team=0 active=false>
             <waypoints>
               <StaticEntity position="<?lua print(2800 + math.random() * 500 - 250) ?>,<?lua print(2500 + math.random() * 500 - 250) ?>,<?lua print(1500 + math.random() * 500 - 250) ?>" />
@@ -284,5 +284,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -294,5 +294,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -368,5 +368,5 @@
       <MovableEntity mass=90000 position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="<?lua print(elements[e])?>" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="<?lua print(elements[e])?>" />
         </attached>
       </MovableEntity>
Index: code/trunk/data/levels/presentationHS09b.oxw
===================================================================
--- code/trunk/data/levels/presentationHS09b.oxw	(revision 8078)
+++ code/trunk/data/levels/presentationHS09b.oxw	(revision 8079)
@@ -1,4 +1,4 @@
 <LevelInfo
- name = "Presentation X"
+ name = "Presentation X 2nd"
  description = "2nd Presentation level for Orxonox Convention X"
  tags = "presentation"
@@ -46,7 +46,7 @@
         s = math.random() * 100
     ?>
-      <MovableEntity collisiontype=dynamic mass=<?lua print(s*10)?> position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <MovableEntity collisiontype=dynamic mass="<?lua print(s*10)?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="asteroid_UV.mesh" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="asteroid_UV.mesh" />
         </attached>
         <collisionShapes>
@@ -145,5 +145,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -155,5 +155,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -203,7 +203,7 @@
         s = math.random() * 100
     ?>
-      <MovableEntity collisiontype=dynamic mass=<?lua print(s*10)?> position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <MovableEntity collisiontype=dynamic mass="<?lua print(s*10)?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
         <attached>
-          <Model position="0,0,0" scale=<?lua print(s) ?> mesh="asteroid_ice.mesh" />
+          <Model position="0,0,0" scale="<?lua print(s) ?>" mesh="asteroid_ice.mesh" />
         </attached>
         <collisionShapes>
Index: code/trunk/data/levels/teamBaseMatch.oxw
===================================================================
--- code/trunk/data/levels/teamBaseMatch.oxw	(revision 8078)
+++ code/trunk/data/levels/teamBaseMatch.oxw	(revision 8079)
@@ -56,5 +56,5 @@
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
@@ -97,5 +97,5 @@
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
@@ -138,5 +138,5 @@
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
@@ -178,5 +178,5 @@
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
@@ -219,5 +219,5 @@
           for i = 1, 10, 1 do
         ?>
-          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay="<?lua print(math.random()) ?>" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
             <events>
               <spawn>
Index: code/trunk/data/levels/testSwallow.oxw
===================================================================
--- code/trunk/data/levels/testSwallow.oxw	(revision 8078)
+++ code/trunk/data/levels/testSwallow.oxw	(revision 8079)
@@ -46,7 +46,7 @@
 ?>
 
-    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass="<?lua print(j * 50) ?>" <?lua end ?> scale="<?lua print(j * 5) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
       <attached>
-        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+        <Model position="0,0,0" scale="<?lua print(j * 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
       </attached>
       <?lua if i == 5 then ?><collisionShapes>
Index: code/trunk/data/levels/underAttack.oxw
===================================================================
--- code/trunk/data/levels/underAttack.oxw	(revision 8078)
+++ code/trunk/data/levels/underAttack.oxw	(revision 8079)
@@ -36,5 +36,5 @@
         </attached>
           <collisionShapes>
-            <SphereCollisionShape radius=<?lua print(x) ?> position="0,0,0" />
+            <SphereCollisionShape radius="<?lua print(x) ?>" position="0,0,0" />
           </collisionShapes>
       </MovableEntity>
@@ -99,5 +99,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
@@ -109,5 +109,5 @@
             material="Examples/Flare"
             colour="1.0, 0.5, 0.3"
-            phase=<?lua print(-360/8*i)?>
+            phase="<?lua print(-360/8*i)?>"
             amplitude=0.1
             frequency=0.5
Index: code/trunk/data/overlays/debug.oxo
===================================================================
--- code/trunk/data/overlays/debug.oxo	(revision 8078)
+++ code/trunk/data/overlays/debug.oxo	(revision 8079)
@@ -66,4 +66,13 @@
     />
 
+    <PauseNotice
+     name     = "pausenotice"
+     position = "0.5, 0.1"
+     font     = "VeraMono"
+     textsize = 0.03
+     colour   = "1.0, 1.0, 1.0, 1.0"
+     align    = "center"
+    />
+
     <AnnounceMessage
      name     = "announcemessage"
Index: code/trunk/src/CMakeLists.txt
===================================================================
--- code/trunk/src/CMakeLists.txt	(revision 8078)
+++ code/trunk/src/CMakeLists.txt	(revision 8079)
@@ -119,4 +119,5 @@
 ADD_SUBDIRECTORY(libraries)
 ADD_SUBDIRECTORY(orxonox)
+SET(ORXONOX_MODULES CACHE INTERNAL "")
 ADD_SUBDIRECTORY(modules)
 
Index: code/trunk/src/external/enet/win32.c
===================================================================
--- code/trunk/src/external/enet/win32.c	(revision 8078)
+++ code/trunk/src/external/enet/win32.c	(revision 8079)
@@ -11,4 +11,5 @@
 #define ENET_BUILDING_LIB 1
 #include "enet/enet.h"
+#include <ws2tcpip.h>
 
 static enet_uint32 timeBase = 0;
Index: code/trunk/src/libraries/core/CMakeLists.txt
===================================================================
--- code/trunk/src/libraries/core/CMakeLists.txt	(revision 8078)
+++ code/trunk/src/libraries/core/CMakeLists.txt	(revision 8079)
@@ -35,5 +35,4 @@
   OrxonoxClass.cc
   Resource.cc
-  WindowEventListener.cc
 
   # hierarchy
@@ -49,5 +48,10 @@
   Template.cc
   XMLPort.cc
+
+COMPILATION_BEGIN ListenerCompilation.cc
+  ViewportEventListener.cc
+  WindowEventListener.cc
   XMLNameListener.cc
+COMPILATION_END
 
 COMPILATION_BEGIN FilesystemCompilation.cc
@@ -76,4 +80,5 @@
     Game.h
     GameMode.h
+    GraphicsManager.h
     GUIManager.h
     Loader.h
Index: code/trunk/src/libraries/core/Core.cc
===================================================================
--- code/trunk/src/libraries/core/Core.cc	(revision 8078)
+++ code/trunk/src/libraries/core/Core.cc	(revision 8079)
@@ -208,6 +208,10 @@
 #ifdef ORXONOX_RELEASE
         const unsigned int defaultLevelLogFile = 3;
+        SetConfigValue(bDevMode_, false)
+            .description("Developer mode. If not set, hides some things from the user to not confuse him.");
 #else
         const unsigned int defaultLevelLogFile = 4;
+        SetConfigValue(bDevMode_, true)
+            .description("Developer mode. If not set, hides some things from the user to not confuse him.");
 #endif
         SetConfigValueExternal(softDebugLevelLogFile_, "OutputHandler", "softDebugLevelLogFile", defaultLevelLogFile)
Index: code/trunk/src/libraries/core/Core.h
===================================================================
--- code/trunk/src/libraries/core/Core.h	(revision 8078)
+++ code/trunk/src/libraries/core/Core.h	(revision 8079)
@@ -91,4 +91,7 @@
                 { return this->ogreConfigTimestamp_; }
 
+            inline bool inDevMode(void) const
+                { return this->bDevMode_; }
+
         private:
             Core(const Core&); //!< Don't use (undefined symbol)
@@ -130,4 +133,5 @@
             long long                     lastLevelTimestamp_;         ///< Timestamp when the last level was started
             long long                     ogreConfigTimestamp_;        ///< Timestamp wehen the ogre config level was modified
+            bool                          bDevMode_;                   //!< Developers bit. If set to false, some options are not available as to not confuse the normal user.
 
             static Core*                  singletonPtr_s;
Index: code/trunk/src/libraries/core/CorePrereqs.h
===================================================================
--- code/trunk/src/libraries/core/CorePrereqs.h	(revision 8078)
+++ code/trunk/src/libraries/core/CorePrereqs.h	(revision 8079)
@@ -182,4 +182,5 @@
     class Thread;
     class ThreadPool;
+    class ViewportEventListener;
     template <class T>
     class WeakPtr;
Index: code/trunk/src/libraries/core/GUIManager.cc
===================================================================
--- code/trunk/src/libraries/core/GUIManager.cc	(revision 8078)
+++ code/trunk/src/libraries/core/GUIManager.cc	(revision 8079)
@@ -32,7 +32,5 @@
 #include <boost/bind.hpp>
 #include <memory>
-extern "C" {
-#include <lua.h>
-}
+
 #include <CEGUIDefaultLogger.h>
 #include <CEGUIExceptions.h>
@@ -107,4 +105,5 @@
     SetConsoleCommand("showGUI", &GUIManager::showGUI).defaultValue(1, false).defaultValue(2, false);
     SetConsoleCommand("hideGUI", &GUIManager::hideGUI);
+    SetConsoleCommand("toggleGUI", &GUIManager::toggleGUI).defaultValue(1, false).defaultValue(2, false);
 
     /**
@@ -284,4 +283,27 @@
     {
         GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")");
+    }
+
+    /**
+    @brief
+        Toggles specified GUI.
+        If the GUI with the input name is already shown and on the top, it is hidden, else it is shown.
+    */
+    /*static*/ void GUIManager::toggleGUI(const std::string& name, bool bHidePrevious, bool bNoInput)
+    {
+        GUIManager::getInstance().executeCode("getGUIFirstActive(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + multi_cast<std::string>(bNoInput) + ")");
+    }
+
+    /**
+    @brief
+        Helper method to toggle a specified GUI.
+        Is called by lua.
+    */
+    void GUIManager::toggleGUIHelper(const std::string& name, bool bHidePrevious, bool bNoInput, bool show)
+    {
+        if(show)
+            GUIManager::showGUI(name, bHidePrevious, bNoInput);
+        else
+            GUIManager::hideGUI(name);
     }
 
@@ -512,9 +534,9 @@
     void GUIManager::windowResized(unsigned int newWidth, unsigned int newHeight)
     {
-        this->guiRenderer_->setDisplaySize(CEGUI::Size(newWidth, newHeight));
-    }
-
-    /**
-        @brief Notify CEGUI if the windows loses the focus (stops higlight of menu items, etc).
+        this->guiRenderer_->setDisplaySize(CEGUI::Size((float)newWidth, (float)newHeight));
+    }
+
+    /**
+        @brief Notify CEGUI if the windows loses the focus (stops highlighting of menu items, etc).
     */
     void GUIManager::windowFocusChanged(bool bFocus)
Index: code/trunk/src/libraries/core/GUIManager.h
===================================================================
--- code/trunk/src/libraries/core/GUIManager.h	(revision 8078)
+++ code/trunk/src/libraries/core/GUIManager.h	(revision 8079)
@@ -49,4 +49,5 @@
 #include "util/Singleton.h"
 #include "input/InputHandler.h"
+#include "Core.h"
 #include "OrxonoxClass.h"
 #include "WindowEventListener.h"
@@ -88,7 +89,15 @@
         void showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious = false, bool bNoInput = false);
         static void hideGUI(const std::string& name);
+        static void toggleGUI(const std::string& name, bool bHidePrevious = false, bool bNoInput = false);
+        void toggleGUIHelper(const std::string& name, bool bHidePrevious, bool bNoInput, bool show); // tolua_export
         void keyESC();
         void setBackgroundImage(const std::string& imageSet, const std::string imageName); // tolua_export
         void setBackgroundImage(const std::string& image);
+
+        /**
+        @brief Helper method to get the developer's mode without having to export Core.h.
+        @see Core::inDevMode
+        */
+        static bool inDevMode(void) { return Core::getInstance().inDevMode(); } // tolua_export
 
         //! Creates a new InputState to be used with a GUI Sheet
Index: code/trunk/src/libraries/core/Game.cc
===================================================================
--- code/trunk/src/libraries/core/Game.cc	(revision 8078)
+++ code/trunk/src/libraries/core/Game.cc	(revision 8079)
@@ -50,4 +50,5 @@
 #include "GameMode.h"
 #include "GameState.h"
+#include "GraphicsManager.h"
 #include "GUIManager.h"
 #include "command/ConsoleCommand.h"
@@ -60,8 +61,8 @@
     static void printFPS()
         { COUT(0) << Game::getInstance().getAvgFPS() << std::endl; }
-    SetConsoleCommand("printFPS", &printFPS);
+    SetConsoleCommand("Stats", "printFPS", &printFPS);
     static void printTickTime()
         { COUT(0) << Game::getInstance().getAvgTickTime() << std::endl; }
-    SetConsoleCommand("printTickTime", &printTickTime);
+    SetConsoleCommand("Stats", "printTickTime", &printTickTime);
 
     std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
@@ -142,5 +143,6 @@
         SetConfigValue(statisticsAvgLength_, 1000000)
             .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
-        SetConfigValue(fpsLimit_, 50)
+
+        SetConfigValueExternal(fpsLimit_, "GraphicsSettings", "fpsLimit", 50)
             .description("Sets the desired frame rate (0 for no limit).");
     }
@@ -207,5 +209,7 @@
 
             // Limit frame rate
-            this->updateFPSLimiter();
+            static bool hasVSync = GraphicsManager::getInstance().hasVSyncEnabled(); // can be static since changes of VSync currently require a restart
+            if (this->fpsLimit_ > 0 && !hasVSync)
+                this->updateFPSLimiter();
         }
 
Index: code/trunk/src/libraries/core/GraphicsManager.cc
===================================================================
--- code/trunk/src/libraries/core/GraphicsManager.cc	(revision 8078)
+++ code/trunk/src/libraries/core/GraphicsManager.cc	(revision 8079)
@@ -49,4 +49,5 @@
 #include "SpecialConfig.h"
 #include "util/Clock.h"
+#include "util/Convert.h"
 #include "util/Exception.h"
 #include "util/StringUtils.h"
@@ -57,13 +58,24 @@
 #include "Game.h"
 #include "GameMode.h"
+#include "GUIManager.h"
 #include "Loader.h"
 #include "MemoryArchive.h"
 #include "PathConfig.h"
+#include "ViewportEventListener.h"
 #include "WindowEventListener.h"
 #include "XMLFile.h"
 #include "command/ConsoleCommand.h"
+#include "input/InputManager.h"
 
 namespace orxonox
 {
+    static const std::string __CC_GraphicsManager_group = "GraphicsManager";
+    static const std::string __CC_setScreenResolution_name = "setScreenResolution";
+    static const std::string __CC_setFSAA_name = "setFSAA";
+    static const std::string __CC_setVSync_name = "setVSync";
+    DeclareConsoleCommand(__CC_GraphicsManager_group, __CC_setScreenResolution_name, &prototype::string__uint_uint_bool);
+    DeclareConsoleCommand(__CC_GraphicsManager_group, __CC_setFSAA_name, &prototype::string__string);
+    DeclareConsoleCommand(__CC_GraphicsManager_group, __CC_setVSync_name, &prototype::string__bool);
+
     static const std::string __CC_printScreen_name = "printScreen";
     DeclareConsoleCommand(__CC_printScreen_name, &prototype::void__void);
@@ -95,4 +107,6 @@
         , renderWindow_(0)
         , viewport_(0)
+        , lastFrameStartTime_(0.0f)
+        , lastFrameEndTime_(0.0f)
     {
         RegisterObject(GraphicsManager);
@@ -136,4 +150,7 @@
         Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_.get());
         ModifyConsoleCommand(__CC_printScreen_name).resetFunction();
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setScreenResolution_name).resetFunction();
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setFSAA_name).resetFunction();
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setVSync_name).resetFunction();
 
         // Undeclare the resources
@@ -304,5 +321,9 @@
         CCOUT(4) << "Configuring Renderer" << std::endl;
 
-        if (!ogreRoot_->restoreConfig() || Core::getInstance().getOgreConfigTimestamp() > Core::getInstance().getLastLevelTimestamp())
+        bool updatedConfig = Core::getInstance().getOgreConfigTimestamp() > Core::getInstance().getLastLevelTimestamp();
+        if (updatedConfig)
+            COUT(2) << "Ogre config file has changed, but no level was started since then. Displaying config dialogue again to verify the changes." << std::endl;
+
+        if (!ogreRoot_->restoreConfig() || updatedConfig)
         {
             if (!ogreRoot_->showConfigDialog())
@@ -330,4 +351,7 @@
         // add console commands
         ModifyConsoleCommand(__CC_printScreen_name).setFunction(&GraphicsManager::printScreen, this);
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setScreenResolution_name).setFunction(&GraphicsManager::setScreenResolution, this);
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setFSAA_name).setFunction(&GraphicsManager::setFSAA, this);
+        ModifyConsoleCommand(__CC_GraphicsManager_group, __CC_setVSync_name).setFunction(&GraphicsManager::setVSync, this);
     }
 
@@ -343,17 +367,21 @@
     @note
         A note about the Ogre::FrameListener: Even though we don't use them,
-        they still get called. However, the delta times are not correct (except
-        for timeSinceLastFrame, which is the most important). A little research
-        as shown that there is probably only one FrameListener that doesn't even
-        need the time. So we shouldn't run into problems.
+        they still get called.
     */
     void GraphicsManager::postUpdate(const Clock& time)
     {
+        // Time before rendering
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
+        // Ogre's time keeping object
         Ogre::FrameEvent evt;
-        evt.timeSinceLastFrame = time.getDeltaTime();
-        evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
-
-        // don't forget to call _fireFrameStarted to OGRE to make sure
-        // everything goes smoothly
+
+        // Translate to Ogre float times before the update
+        float temp = lastFrameStartTime_;
+        lastFrameStartTime_ = (float)timeBeforeTick * 0.000001f;
+        evt.timeSinceLastFrame = lastFrameStartTime_ - temp;
+        evt.timeSinceLastEvent = lastFrameStartTime_ - lastFrameEndTime_;
+
+        // Ogre requires the time too
         ogreRoot_->_fireFrameStarted(evt);
 
@@ -361,10 +389,7 @@
         // This calls the WindowEventListener objects.
         Ogre::WindowEventUtilities::messagePump();
-        // make sure the window stays active even when not focused
+        // Make sure the window stays active even when not focused
         // (probably only necessary on windows)
         this->renderWindow_->setActive(true);
-
-        // Time before rendering
-        uint64_t timeBeforeTick = time.getRealMicroseconds();
 
         // Render frame
@@ -375,11 +400,23 @@
         Game::getInstance().subtractTickTime((int32_t)(timeAfterTick - timeBeforeTick));
 
-        // again, just to be sure OGRE works fine
-        ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+        // Translate to Ogre float times after the update
+        temp = lastFrameEndTime_;
+        lastFrameEndTime_ = (float)timeBeforeTick * 0.000001f;
+        evt.timeSinceLastFrame = lastFrameEndTime_ - temp;
+        evt.timeSinceLastEvent = lastFrameEndTime_ - lastFrameStartTime_;
+
+        // Ogre also needs the time after the frame finished
+        ogreRoot_->_fireFrameEnded(evt);
     }
 
     void GraphicsManager::setCamera(Ogre::Camera* camera)
     {
+        Ogre::Camera* oldCamera = this->viewport_->getCamera();
+
         this->viewport_->setCamera(camera);
+        GUIManager::getInstance().setCamera(camera);
+
+        for (ObjectList<ViewportEventListener>::iterator it = ObjectList<ViewportEventListener>::begin(); it != ObjectList<ViewportEventListener>::end(); ++it)
+            it->cameraChanged(this->viewport_, oldCamera);
     }
 
@@ -440,17 +477,104 @@
     bool GraphicsManager::isFullScreen() const
     {
+        return this->renderWindow_->isFullScreen();
+    }
+
+    unsigned int GraphicsManager::getWindowWidth() const
+    {
+        return this->renderWindow_->getWidth();
+    }
+
+    unsigned int GraphicsManager::getWindowHeight() const
+    {
+        return this->renderWindow_->getHeight();
+    }
+
+    bool GraphicsManager::hasVSyncEnabled() const
+    {
         Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
-        if (options.find("Full Screen") != options.end())
-        {
-            if (options["Full Screen"].currentValue == "Yes")
-                return true;
-            else
-                return false;
-        }
+        Ogre::ConfigOptionMap::iterator it = options.find("VSync");
+        if (it != options.end())
+            return (it->second.currentValue == "Yes");
         else
-        {
-            COUT(0) << "Could not find 'Full Screen' render system option. Fix This!!!" << std::endl;
             return false;
-        }
+    }
+
+    std::string GraphicsManager::getFSAAMode() const
+    {
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        Ogre::ConfigOptionMap::iterator it = options.find("FSAA");
+        if (it != options.end())
+            return it->second.currentValue;
+        else
+            return "";
+    }
+
+    std::string GraphicsManager::setScreenResolution(unsigned int width, unsigned int height, bool fullscreen)
+    {
+        // workaround to detect if the colour depth should be written to the config file
+        bool bWriteColourDepth = false;
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        Ogre::ConfigOptionMap::iterator it = options.find("Video Mode");
+        if (it != options.end())
+            bWriteColourDepth = (it->second.currentValue.find('@') != std::string::npos);
+
+        if (bWriteColourDepth)
+        {
+            this->ogreRoot_->getRenderSystem()->setConfigOption("Video Mode", multi_cast<std::string>(width)
+                                                                    + " x " + multi_cast<std::string>(height)
+                                                                    + " @ " + multi_cast<std::string>(this->getRenderWindow()->getColourDepth()) + "-bit colour");
+        }
+        else
+        {
+            this->ogreRoot_->getRenderSystem()->setConfigOption("Video Mode", multi_cast<std::string>(width)
+                                                                    + " x " + multi_cast<std::string>(height));
+        }
+
+        this->ogreRoot_->getRenderSystem()->setConfigOption("Full Screen", fullscreen ? "Yes" : "No");
+
+        std::string validate = this->ogreRoot_->getRenderSystem()->validateConfigOptions();
+
+        if (validate == "")
+        {
+            GraphicsManager::getInstance().getRenderWindow()->setFullscreen(fullscreen, width, height);
+            this->ogreRoot_->saveConfig();
+            Core::getInstance().updateOgreConfigTimestamp();
+            // Also reload the input devices
+            InputManager::getInstance().reload();
+        }
+
+        return validate;
+    }
+
+    std::string GraphicsManager::setFSAA(const std::string& mode)
+    {
+        this->ogreRoot_->getRenderSystem()->setConfigOption("FSAA", mode);
+
+        std::string validate = this->ogreRoot_->getRenderSystem()->validateConfigOptions();
+
+        if (validate == "")
+        {
+            //this->ogreRoot_->getRenderSystem()->reinitialise(); // can't use this that easily, because it recreates the render window, invalidating renderWindow_
+            this->ogreRoot_->saveConfig();
+            Core::getInstance().updateOgreConfigTimestamp();
+        }
+
+        return validate;
+    }
+
+    std::string GraphicsManager::setVSync(bool vsync)
+    {
+        this->ogreRoot_->getRenderSystem()->setConfigOption("VSync", vsync ? "Yes" : "No");
+
+        std::string validate = this->ogreRoot_->getRenderSystem()->validateConfigOptions();
+
+        if (validate == "")
+        {
+            //this->ogreRoot_->getRenderSystem()->reinitialise(); // can't use this that easily, because it recreates the render window, invalidating renderWindow_
+            this->ogreRoot_->saveConfig();
+            Core::getInstance().updateOgreConfigTimestamp();
+        }
+
+        return validate;
     }
 
Index: code/trunk/src/libraries/core/GraphicsManager.h
===================================================================
--- code/trunk/src/libraries/core/GraphicsManager.h	(revision 8078)
+++ code/trunk/src/libraries/core/GraphicsManager.h	(revision 8079)
@@ -54,4 +54,5 @@
 #include "OrxonoxClass.h"
 
+// tolua_begin
 namespace orxonox
 {
@@ -60,6 +61,8 @@
         Graphics engine manager class
     */
-    class _CoreExport GraphicsManager : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
-    {
+    class _CoreExport GraphicsManager
+// tolua_end
+        : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
+    { // tolua_export
         friend class Singleton<GraphicsManager>;
     public:
@@ -74,5 +77,15 @@
         Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
         size_t getRenderWindowHandle();
+
+// tolua_begin
+        static GraphicsManager& getInstance() { return Singleton<GraphicsManager>::getInstance(); } // tolua_export
+
         bool isFullScreen() const;
+        unsigned int getWindowWidth() const;
+        unsigned int getWindowHeight() const;
+
+        bool hasVSyncEnabled() const;
+        std::string getFSAAMode() const;
+// tolua_end
 
         void upgradeToGraphics();
@@ -96,4 +109,7 @@
         // console commands
         void printScreen();
+        std::string setScreenResolution(unsigned int width, unsigned int height, bool fullscreen);
+        std::string setFSAA(const std::string& mode);
+        std::string setVSync(bool vsync);
 
         scoped_ptr<OgreWindowEventListener> ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
@@ -105,4 +121,6 @@
         Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
         Ogre::Viewport*     viewport_;                 //!< default full size viewport
+        float               lastFrameStartTime_;       //!< Time stamp of the beginning of the last frame
+        float               lastFrameEndTime_;         //!< Time stamp of the end of the last frame
 
         // XML files for the resources and the debug overlay
@@ -121,6 +139,8 @@
 
         static GraphicsManager* singletonPtr_s;        //!< Pointer to the Singleton
+// tolua_begin
     };
 }
+// tolua_end
 
 #endif /* _GraphicsManager_H__ */
Index: code/trunk/src/libraries/core/Loader.cc
===================================================================
--- code/trunk/src/libraries/core/Loader.cc	(revision 8078)
+++ code/trunk/src/libraries/core/Loader.cc	(revision 8079)
@@ -147,5 +147,5 @@
         Returns true if successful.
     */
-    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask, bool verbose)
+    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask, bool verbose, bool bRemoveLuaTags)
     {
         if (!file)
@@ -155,5 +155,5 @@
 
         std::string xmlInput;
-        if (file->getLuaSupport())
+        if (file->getLuaSupport() && !bRemoveLuaTags)
         {
             // Use the LuaState to replace the XML tags (calls our function)
@@ -172,4 +172,13 @@
             }
             xmlInput = Resource::open(file->getFilename())->getAsString();
+
+            if (bRemoveLuaTags)
+            {
+                // Remove all Lua code.
+                // Note: we only need this to speed up parsing of level files at the
+                // start of the program.
+                // Assumption: the LevelInfo tag does not use Lua scripting
+                xmlInput = removeLuaTags(xmlInput);
+            }
         }
 
@@ -271,8 +280,7 @@
     }
 
-    std::string Loader::replaceLuaTags(const std::string& text)
-    {
-        // create map with all Lua tags
-        std::map<size_t, bool> luaTags;
+    bool Loader::getLuaTags(const std::string& text, std::map<size_t, bool>& luaTags)
+    {
+        // fill map with all Lua tags
         {
             size_t pos = 0;
@@ -328,8 +336,18 @@
             {
                 COUT(2) << "Warning: Error in level file" << std::endl;
-                // todo: errorhandling
-                return "";
-            }
-        }
+                // TODO: error handling
+                return false; 
+            }
+        }
+
+        return true;
+    }
+
+    std::string Loader::replaceLuaTags(const std::string& text)
+    {
+        // create a map with all lua tags
+        std::map<size_t, bool> luaTags;
+        if (!getLuaTags(text, luaTags))
+            return "";
 
         // Use a stringstream object to speed up the parsing
@@ -421,3 +439,41 @@
         return output.str();
     }
+
+    std::string Loader::removeLuaTags(const std::string& text)
+    {
+        // create a map with all lua tags
+        std::map<size_t, bool> luaTags;
+        if (!getLuaTags(text, luaTags))
+            return "";
+
+        // Use a stringstream object to speed up the concatenation
+        std::ostringstream output;
+
+        // cut the original string into pieces and only write the non Lua parts
+        std::map<size_t, bool>::iterator it = luaTags.begin();
+        bool bLuaCode = false;
+        size_t start = 0;
+        size_t end = 0;
+
+        do
+        {
+            if (it != luaTags.end())
+                end = (it++)->first;
+            else
+                end = std::string::npos;
+
+            if (!bLuaCode)
+            {
+                output << text.substr(start, end - start);
+                start = end + 5;
+            }
+            else
+                start = end + 2;
+
+            bLuaCode = !bLuaCode;
+        }
+        while (end != std::string::npos);
+
+        return output.str();
+    }
 }
Index: code/trunk/src/libraries/core/Loader.h
===================================================================
--- code/trunk/src/libraries/core/Loader.h	(revision 8078)
+++ code/trunk/src/libraries/core/Loader.h	(revision 8079)
@@ -42,4 +42,5 @@
 #include "CorePrereqs.h"
 
+#include <map>
 #include <vector>
 #include "ClassTreeMask.h"
@@ -61,13 +62,17 @@
             static bool reload(const ClassTreeMask& mask = ClassTreeMask(), bool verbose = true);
 
-            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), bool verbose = true);
+            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(),
+                             bool verbose = true, bool bRemoveLuaTags = false);
             static void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
             static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask(), bool verbose = true);
 
             static std::string replaceLuaTags(const std::string& text);
+            static std::string removeLuaTags(const std::string& text);
 
             static ClassTreeMask currentMask_s;
 
         private:
+            static bool getLuaTags(const std::string& text, std::map<size_t, bool>& luaTags);
+
             static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s;
     };
Index: code/trunk/src/libraries/core/OrxonoxClass.h
===================================================================
--- code/trunk/src/libraries/core/OrxonoxClass.h	(revision 8078)
+++ code/trunk/src/libraries/core/OrxonoxClass.h	(revision 8079)
@@ -194,4 +194,6 @@
 
         protected:
+            virtual ~DestructionListener() {}
+
             inline void registerAsDestructionListener(OrxonoxClass* object)
                 { if (object) { object->registerDestructionListener(this); } }
Index: code/trunk/src/libraries/core/ViewportEventListener.cc
===================================================================
--- code/trunk/src/libraries/core/ViewportEventListener.cc	(revision 8079)
+++ code/trunk/src/libraries/core/ViewportEventListener.cc	(revision 8079)
@@ -0,0 +1,38 @@
+/*
+ *   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 "ViewportEventListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    ViewportEventListener::ViewportEventListener()
+    {
+        RegisterRootObject(ViewportEventListener);
+    }
+}
Index: code/trunk/src/libraries/core/ViewportEventListener.h
===================================================================
--- code/trunk/src/libraries/core/ViewportEventListener.h	(revision 8079)
+++ code/trunk/src/libraries/core/ViewportEventListener.h	(revision 8079)
@@ -0,0 +1,50 @@
+/*
+ *   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 _ViewportEventListener_H__
+#define _ViewportEventListener_H__
+
+#include "util/OgreForwardRefs.h"
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport ViewportEventListener : virtual public OrxonoxClass
+    {
+        public:
+            virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera) {}
+
+        protected:
+            ViewportEventListener();
+            virtual ~ViewportEventListener() {}
+    };
+}
+
+#endif /* _ViewportEventListener_H__ */
Index: code/trunk/src/libraries/core/WeakPtr.h
===================================================================
--- code/trunk/src/libraries/core/WeakPtr.h	(revision 8078)
+++ code/trunk/src/libraries/core/WeakPtr.h	(revision 8079)
@@ -129,5 +129,5 @@
 
             /// Destructor
-            inline ~WeakPtr()
+            inline virtual ~WeakPtr()
             {
                 this->unregisterAsDestructionListener(this->base_);
Index: code/trunk/src/libraries/core/command/CommandEvaluation.h
===================================================================
--- code/trunk/src/libraries/core/command/CommandEvaluation.h	(revision 8078)
+++ code/trunk/src/libraries/core/command/CommandEvaluation.h	(revision 8079)
@@ -70,9 +70,9 @@
 
         @remarks execCommand_ and hintCommand_ can be different in this case: There are multiple
-        commands avaliable, let's say "tcl", "tclexecute", and "tclquery". The user enters
-        "tcl", which is already a valid command. Now execCommand_ points to the "tcl"-command,
-        but hintCommand_ still points to the autocompletion command of CommandExecutor, because
-        the auto-completion list must still return the three possible commands, "tcl tclexecute tclquery"
-        because the user may want to execute "tclquery" and needs auto-completion.
+        commands avaliable, let's say "tcl" and "TclThreadManager". The user enters "tcl", which
+        is already a valid command. Now execCommand_ points to the "tcl"-command, but hintCommand_
+        still points to the autocompletion command of CommandExecutor, because the auto-completion
+        list must still return the two possible commands, "tcl TclThreadManager" because the user
+        may want to write "TclThreadManager ..." and needs auto-completion.
 
         @see See @ref CommandExecutorExample "this description" for an example.
Index: code/trunk/src/libraries/core/command/ConsoleCommand.h
===================================================================
--- code/trunk/src/libraries/core/command/ConsoleCommand.h	(revision 8078)
+++ code/trunk/src/libraries/core/command/ConsoleCommand.h	(revision 8079)
@@ -317,4 +317,8 @@
         inline void void__void(void) {}
         inline void void__string(const std::string&) {}
+
+        inline std::string string__bool(bool) { return ""; }
+        inline std::string string__string(const std::string&) { return ""; }
+        inline std::string string__uint_uint_bool(unsigned int, unsigned int, bool) { return ""; }
     }
 
Index: code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc
===================================================================
--- code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc	(revision 8078)
+++ code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc	(revision 8079)
@@ -46,11 +46,11 @@
 namespace orxonox
 {
-    SetConsoleCommand("source", source).argumentCompleter(0, autocompletion::files());
+//    SetConsoleCommand("source", source).argumentCompleter(0, autocompletion::files());  // disabled because we use the implementation in Tcl
     SetConsoleCommand("echo", echo);
-    SetConsoleCommand("puts", puts);
-
-    SetConsoleCommand("read", read).argumentCompleter(0, autocompletion::files());
-    SetConsoleCommand("append", append).argumentCompleter(0, autocompletion::files());
-    SetConsoleCommand("write", write).argumentCompleter(0, autocompletion::files());
+//    SetConsoleCommand("puts", puts);                                                    // disabled because we use the implementation in Tcl
+
+//    SetConsoleCommand("read", read).argumentCompleter(0, autocompletion::files());      // disabled because we use the implementation in Tcl
+//    SetConsoleCommand("append", append).argumentCompleter(0, autocompletion::files());  // disabled because we use the implementation in Tcl
+//    SetConsoleCommand("write", write).argumentCompleter(0, autocompletion::files());    // disabled because we use the implementation in Tcl
 
     SetConsoleCommand("calculate", calculate);
Index: code/trunk/src/libraries/core/command/Shell.cc
===================================================================
--- code/trunk/src/libraries/core/command/Shell.cc	(revision 8078)
+++ code/trunk/src/libraries/core/command/Shell.cc	(revision 8079)
@@ -46,8 +46,8 @@
 {
     SetConsoleCommand("log",     OutputHandler::log    );
-    SetConsoleCommand("error",   OutputHandler::error  );
-    SetConsoleCommand("warning", OutputHandler::warning);
-    SetConsoleCommand("info",    OutputHandler::info   );
-    SetConsoleCommand("debug",   OutputHandler::debug  );
+    SetConsoleCommand("error",   OutputHandler::error  ).hide();
+    SetConsoleCommand("warning", OutputHandler::warning).hide();
+    SetConsoleCommand("info",    OutputHandler::info   ).hide();
+    SetConsoleCommand("debug",   OutputHandler::debug  ).hide();
 
     unsigned int Shell::cacheSize_s;
Index: code/trunk/src/libraries/core/command/TclBind.cc
===================================================================
--- code/trunk/src/libraries/core/command/TclBind.cc	(revision 8078)
+++ code/trunk/src/libraries/core/command/TclBind.cc	(revision 8079)
@@ -45,5 +45,5 @@
 {
     SetConsoleCommand("tcl", &TclBind::tcl);
-    SetConsoleCommand("bgerror", &TclBind::bgerror);
+    SetConsoleCommand("bgerror", &TclBind::bgerror).hide();
 
     TclBind* TclBind::singletonPtr_s = 0;
@@ -91,13 +91,14 @@
 
             this->interpreter_->def("::orxonox::query", TclBind::tcl_query, Tcl::variadic());
+            this->interpreter_->def("::orxonox::execute", TclBind::tcl_execute, Tcl::variadic());
             this->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
-            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
             this->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
 
             try
             {
-                this->interpreter_->eval("proc query        {args}    { ::orxonox::query $args }");
+                this->interpreter_->def("query", TclBind::tcl_query, Tcl::variadic());
+                this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
                 this->interpreter_->eval("proc crossquery   {id args} { ::orxonox::crossquery 0 $id $args }");
-                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossquery 0 $id $args }");
+                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossexecute 0 $id $args }");
                 this->interpreter_->eval("proc running      {}        { return 1 }");
                 this->interpreter_->eval("set id 0");
@@ -154,10 +155,33 @@
     {
         COUT(4) << "Tcl_query: " << args.get() << std::endl;
-
+        return TclBind::tcl_helper(args, true);
+    }
+
+    /**
+        @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor.
+    */
+    void TclBind::tcl_execute(Tcl::object const &args)
+    {
+        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
+        TclBind::tcl_helper(args, false);
+    }
+
+    /**
+        @brief Helper function, used by tcl_query() and tcl_execute().
+    */
+    std::string TclBind::tcl_helper(Tcl::object const &args, bool bQuery)
+    {
         const std::string& command = stripEnclosingBraces(args.get());
 
         int error;
+        std::string result;
+
         CommandEvaluation evaluation = CommandExecutor::evaluate(command);
-        const std::string& result = evaluation.query(&error);
+
+        if (bQuery)
+            result = evaluation.query(&error).getString();
+        else
+            error = evaluation.execute();
+
         switch (error)
         {
@@ -175,18 +199,4 @@
 
     /**
-        @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor.
-    */
-    void TclBind::tcl_execute(Tcl::object const &args)
-    {
-        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
-        const std::string& command = stripEnclosingBraces(args.get());
-
-        if (CommandExecutor::execute(command, false))
-        {
-            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
-        }
-    }
-
-    /**
         @brief Console command, executes Tcl code. Can be used to bind Tcl-commands to a key, because native
         Tcl-commands can not be evaluated and are thus not supported by the key-binder.
@@ -198,13 +208,8 @@
             try
             {
-                const std::string& output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
-                if (!output.empty())
-                {
-                    COUT(0) << "tcl> " << output << std::endl;
-                }
-                return output;
+                return TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
             }
             catch (Tcl::tcl_error const &e)
-            {   COUT(1) << "tcl> Error: " << e.what() << std::endl;   }
+            {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
         }
 
Index: code/trunk/src/libraries/core/command/TclBind.h
===================================================================
--- code/trunk/src/libraries/core/command/TclBind.h	(revision 8078)
+++ code/trunk/src/libraries/core/command/TclBind.h	(revision 8079)
@@ -126,4 +126,6 @@
             TclBind(const TclBind& other);      ///< Copy-constructor, not implemented
 
+            static std::string tcl_helper(Tcl::object const &args, bool bQuery);
+
             Tcl::interpreter* interpreter_;     ///< The wrapped Tcl interpreter
             std::string tclDataPath_;           ///< The path to the directory that contains the Orxonox-specific Tcl-files
Index: code/trunk/src/libraries/core/command/TclThreadManager.cc
===================================================================
--- code/trunk/src/libraries/core/command/TclThreadManager.cc	(revision 8078)
+++ code/trunk/src/libraries/core/command/TclThreadManager.cc	(revision 8079)
@@ -55,6 +55,4 @@
     const float TCLTHREADMANAGER_MAX_CPU_USAGE = 0.50f;
 
-    SetConsoleCommand("tclexecute", &TclThreadManager::execute).argumentCompleter(0, autocompletion::tclthreads());
-    SetConsoleCommand("tclquery",   &TclThreadManager::query  ).argumentCompleter(0, autocompletion::tclthreads());
     SetConsoleCommand("TclThreadManager", "create",  &TclThreadManager::create);
     SetConsoleCommand("TclThreadManager", "destroy", &TclThreadManager::destroy).argumentCompleter(0, autocompletion::tclthreads());
Index: code/trunk/src/libraries/core/input/InputManager.cc
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.cc	(revision 8078)
+++ code/trunk/src/libraries/core/input/InputManager.cc	(revision 8079)
@@ -641,3 +641,19 @@
         state->destroy();
     }
+
+    bool InputManager::setMouseExclusive(const std::string& name, TriBool::Value value)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Changing the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+        {
+            it->second->setMouseExclusive(value);
+            return true;
+        }
+        return false;
+    }
 }
Index: code/trunk/src/libraries/core/input/InputManager.h
===================================================================
--- code/trunk/src/libraries/core/input/InputManager.h	(revision 8078)
+++ code/trunk/src/libraries/core/input/InputManager.h	(revision 8079)
@@ -163,4 +163,11 @@
         */
         bool destroyState(const std::string& name); // tolua_export
+        /**
+        @brief
+            Changes the mouse mode of an input state.
+        @return
+            True if the call was successful, fals if the name was not found
+        */
+        bool setMouseExclusive(const std::string& name, TriBool::Value value); // tolua_export
 
         //-------------------------------
Index: code/trunk/src/libraries/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/libraries/core/input/KeyBinder.cc	(revision 8078)
+++ code/trunk/src/libraries/core/input/KeyBinder.cc	(revision 8079)
@@ -431,5 +431,11 @@
                         // decrease counter
                         button->nCommands_[mode_index]--;
-                        // note: we don't replace the old array - it's not one element too large, but no one cares since nCommands_ defines the size
+                        // old array would not get deleted if nCommands_ is now 0
+                        // otherwise: nobody cares about an array that is one element too large - nCommands_ defines the size
+                        if (button->nCommands_[mode_index] == 0)
+                        {
+                            delete[] button->commands_[mode_index];
+                            button->commands_[mode_index] = 0;
+                        }
 
                         // decrement the index since we shifted the array and continue searching for more occurrences of the command
Index: code/trunk/src/libraries/core/input/Keyboard.cc
===================================================================
--- code/trunk/src/libraries/core/input/Keyboard.cc	(revision 8078)
+++ code/trunk/src/libraries/core/input/Keyboard.cc	(revision 8079)
@@ -36,16 +36,26 @@
     {
         // update modifiers
-        if (arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
-            modifiers_ |= KeyboardModifier::Alt;   // alt key
-        if (arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
-            modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
-        if (arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
-            modifiers_ |= KeyboardModifier::Shift; // shift key
+        switch (arg.key)
+        {
+            case OIS::KC_RMENU:
+            case OIS::KC_LMENU:
+                modifiers_ |= KeyboardModifier::Alt;   // alt key
+                break;
+            case OIS::KC_RCONTROL:
+            case OIS::KC_LCONTROL:
+                modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
+                break;
+            case OIS::KC_RSHIFT:
+            case OIS::KC_LSHIFT:
+                modifiers_ |= KeyboardModifier::Shift; // shift key
+                break;
+            case OIS::KC_TAB:
+                // Do not distribute the alt+tab event (messes with the operating system)
+                if ((modifiers_ & KeyboardModifier::Alt) != 0)
+                    return true;
+            default:;
+        }
 
-        // Do not distribute the alt+tab event (messes with the operating system)
-        if ((modifiers_ & KeyboardModifier::Alt) != 0 && arg.key == OIS::KC_TAB)
-            return true;
-
-        KeyEvent evt(arg);
+        KeyEvent evt(static_cast<KeyCode::ByEnum>(arg.key), Keyboard::getKeyText(arg), 0);
         super::buttonPressed(evt);
         return true;
@@ -56,14 +66,46 @@
     {
         // update modifiers
-        if (arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
-            modifiers_ &= ~KeyboardModifier::Alt;   // alt key
-        if (arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
-            modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
-        if (arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
-            modifiers_ &= ~KeyboardModifier::Shift; // shift key
+        switch (arg.key)
+        {
+            case OIS::KC_RMENU:
+            case OIS::KC_LMENU:
+                modifiers_ &= ~KeyboardModifier::Alt;   // alt key
+                break;
+            case OIS::KC_RCONTROL:
+            case OIS::KC_LCONTROL:
+                modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
+                break;
+            case OIS::KC_RSHIFT:
+            case OIS::KC_LSHIFT:
+                modifiers_ &= ~KeyboardModifier::Shift; // shift key
+                break;
+            default:;
+        }
 
-        KeyEvent evt(arg);
+        KeyEvent evt(static_cast<KeyCode::ByEnum>(arg.key), Keyboard::getKeyText(arg), 0);
         super::buttonReleased(evt);
         return true;
     }
+
+    /// A map which returns the corresponding chars for some key codes
+    unsigned int Keyboard::getKeyText(const OIS::KeyEvent& arg)
+    {
+        switch (arg.key)
+        {
+            case OIS::KC_NUMPAD0:     return static_cast<unsigned int>('0');
+            case OIS::KC_NUMPAD1:     return static_cast<unsigned int>('1');
+            case OIS::KC_NUMPAD2:     return static_cast<unsigned int>('2');
+            case OIS::KC_NUMPAD3:     return static_cast<unsigned int>('3');
+            case OIS::KC_NUMPAD4:     return static_cast<unsigned int>('4');
+            case OIS::KC_NUMPAD5:     return static_cast<unsigned int>('5');
+            case OIS::KC_NUMPAD6:     return static_cast<unsigned int>('6');
+            case OIS::KC_NUMPAD7:     return static_cast<unsigned int>('7');
+            case OIS::KC_NUMPAD8:     return static_cast<unsigned int>('8');
+            case OIS::KC_NUMPAD9:     return static_cast<unsigned int>('9');
+            case OIS::KC_DECIMAL:     return static_cast<unsigned int>('.');
+            case OIS::KC_DIVIDE:      return static_cast<unsigned int>('/');
+            case OIS::KC_NUMPADENTER: return static_cast<unsigned int>('\n');
+            default:                  return arg.text;
+        }
+    }
 }
Index: code/trunk/src/libraries/core/input/Keyboard.h
===================================================================
--- code/trunk/src/libraries/core/input/Keyboard.h	(revision 8078)
+++ code/trunk/src/libraries/core/input/Keyboard.h	(revision 8079)
@@ -83,4 +83,6 @@
         static std::string getClassNameImpl() { return "Keyboard"; }
 
+        static unsigned int getKeyText(const OIS::KeyEvent& arg);
+
         //! Bit mask representing keyboard modifiers
         int modifiers_;
Index: code/trunk/src/libraries/network/Host.cc
===================================================================
--- code/trunk/src/libraries/network/Host.cc	(revision 8078)
+++ code/trunk/src/libraries/network/Host.cc	(revision 8079)
@@ -38,8 +38,9 @@
 namespace orxonox {
 
+  static const std::string __CC_printRTT_group = "Stats";
   static const std::string __CC_printRTT_name = "printRTT";
 
   SetConsoleCommand("chat", &Host::Chat);
-  SetConsoleCommand(__CC_printRTT_name, &Host::printRTT);
+  SetConsoleCommand(__CC_printRTT_group, __CC_printRTT_name, &Host::printRTT);
 
   // Host*               Host::instance_=0;
@@ -55,5 +56,5 @@
   //   assert(instance_==0);
     instances_s.push_back(this);
-    ModifyConsoleCommand(__CC_printRTT_name).setObject(this);
+    ModifyConsoleCommand(__CC_printRTT_group, __CC_printRTT_name).setObject(this);
     this->bIsActive_ = false;
   }
@@ -67,5 +68,5 @@
     assert( std::find( instances_s.begin(), instances_s.end(), this )!=instances_s.end() );
     instances_s.erase(std::find( instances_s.begin(), instances_s.end(), this ));
-    ModifyConsoleCommand(__CC_printRTT_name).setObject(0);
+    ModifyConsoleCommand(__CC_printRTT_group, __CC_printRTT_name).setObject(0);
   }
 
Index: code/trunk/src/libraries/tools/ResourceLocation.cc
===================================================================
--- code/trunk/src/libraries/tools/ResourceLocation.cc	(revision 8078)
+++ code/trunk/src/libraries/tools/ResourceLocation.cc	(revision 8079)
@@ -30,4 +30,5 @@
 
 #include <OgreResourceGroupManager.h>
+#include <OgreException.h>
 #include <boost/filesystem.hpp>
 
Index: code/trunk/src/libraries/tools/Shader.cc
===================================================================
--- code/trunk/src/libraries/tools/Shader.cc	(revision 8078)
+++ code/trunk/src/libraries/tools/Shader.cc	(revision 8079)
@@ -30,12 +30,6 @@
 
 #include <OgreCompositorManager.h>
-#include <OgreCompositorInstance.h>
-#include <OgreSceneManager.h>
 #include <OgreRoot.h>
 #include <OgrePlugin.h>
-#include <OgreMaterial.h>
-#include <OgreTechnique.h>
-#include <OgrePass.h>
-#include <OgreMaterialManager.h>
 
 #include "core/CoreIncludes.h"
@@ -45,7 +39,7 @@
 namespace orxonox
 {
-    bool Shader::bLoadedCgPlugin_s = false;
-    Shader::MaterialMap Shader::parameters_s;
-
+    /**
+        @brief Initializes the values and sets the scene manager.
+    */
     Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
     {
@@ -53,277 +47,195 @@
 
         this->scenemanager_ = scenemanager;
-        this->compositorInstance_ = 0;
         this->bVisible_ = true;
         this->bLoadCompositor_ = GameMode::showsGraphics();
-        this->bViewportInitialized_ = false;
-
-        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
-        {
-            Shader::bLoadedCgPlugin_s = false;
+        this->registeredAsListener_ = false;
+
+        static bool hasCgProgramManager = Shader::hasCgProgramManager();
+
+        this->bLoadCompositor_ &= hasCgProgramManager;
+    }
+
+    /**
+        @brief Removes the compositor and frees the resources.
+    */
+    Shader::~Shader()
+    {
+        if (this->compositorInstance_ && GraphicsManager::getInstance().getViewport())
+            Ogre::CompositorManager::getSingleton().removeCompositor(GraphicsManager::getInstance().getViewport(), this->compositorName_);
+    }
+
+    /**
+        @brief Inherited from ViewportEventListener - called if the camera changes.
+
+        Since the new camera could be in a different scene, the shader has to make sure
+        it deactivates or activates itself accordingly.
+
+        Additionally the shader has to be turned off and on even if the camera stays in
+        the same scene to fix a weird behavior of Ogre.
+    */
+    void Shader::cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera)
+    {
+        if (!this->bLoadCompositor_ || !this->scenemanager_)
+            return;
+
+        // load the compositor if not already done
+        if (!this->compositorName_.empty() && !this->compositorInstance_)
+            this->changedCompositorName(viewport);
+
+        // update compositor in viewport (shader should only be active if the current camera is in the same scene as the shader)
+
+        // Note:
+        // The shader needs also to be switched off and on after changing the camera in the
+        // same scene to avoid weird behaviour with active compositors while switching the
+        // camera (like freezing the image)
+        //
+        // Last known Ogre version needing this workaround:
+        // 1.4.8
+        // 1.7.2
+
+        if (oldCamera && this->scenemanager_ == oldCamera->getSceneManager())
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, false);
+
+        if (viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager())
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible());
+    }
+
+    /**
+        @brief Changes the compositor - default viewport.
+    */
+    void Shader::changedCompositorName()
+    {
+        // For the moment, we get the viewport always from the graphics manager
+        // TODO: Try to support multiple viewports - note however that scenemanager_->getCurrentViewport() returns NULL
+        //       after switching to a camera in a different scene (only for the first time this scene is displayed though)
+        this->changedCompositorName(GraphicsManager::getInstance().getViewport());
+    }
+
+    /**
+        @brief Changes the compositor.
+    */
+    void Shader::changedCompositorName(Ogre::Viewport* viewport)
+    {
+        if (this->bLoadCompositor_)
+        {
+            assert(viewport);
+            if (this->compositorInstance_)
+            {
+                // remove the old compositor, remove the listener
+                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositorName_);
+                this->compositorInstance_->removeListener(this);
+                this->compositorInstance_ = 0;
+            }
+            if (!this->compositorName_.empty())
+            {
+                // add the new compositor
+                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositorName_);
+                if (this->compositorInstance_)
+                {
+                    // register as listener if required
+                    if (this->registeredAsListener_)
+                        this->compositorInstance_->addListener(this);
+                    // set visibility according to the isVisible() and the camera/viewport
+                    if (viewport->getCamera())
+                        Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager());
+                }
+                else
+                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositorName_ << "\"." << std::endl;
+            }
+            this->oldcompositorName_ = this->compositorName_;
+        }
+    }
+
+    /**
+        @brief Changes the visibility of the shader. Doesn't free any resources if set to invisible.
+    */
+    void Shader::updateVisibility()
+    {
+        if (this->compositorInstance_)
+            Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, this->isVisible());
+    }
+
+    /**
+        @brief Defines a new integer value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+    */
+    void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, int value)
+    {
+        ParameterContainer container = {technique, pass, parameter, value, 0.0f, MT_Type::Int};
+        this->parameters_.push_back(container);
+        this->addAsListener();
+    }
+
+    /**
+        @brief Defines a new float value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+    */
+    void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, float value)
+    {
+        ParameterContainer container = {technique, pass, parameter, 0, value, MT_Type::Float};
+        this->parameters_.push_back(container);
+        this->addAsListener();
+    }
+
+    /**
+        @brief Registers the shader as CompositorInstance::Listener at the compositor. Used to change parameters.
+    */
+    void Shader::addAsListener()
+    {
+        if (!this->registeredAsListener_)
+        {
+            this->registeredAsListener_ = true;
+            if (this->compositorInstance_)
+                this->compositorInstance_->addListener(this);
+        }
+    }
+
+    /**
+        @brief Inherited by Ogre::CompositorInstance::Listener, called whenever the material is rendered. Used to change parameters.
+    */
+    void Shader::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr)
+    {
+        // iterate through the list of parameters
+        for (std::list<ParameterContainer>::iterator it = this->parameters_.begin(); it != this->parameters_.end(); ++it)
+        {
+            Ogre::Technique* techniquePtr = materialPtr->getTechnique(it->technique_);
+            if (techniquePtr)
+            {
+                Ogre::Pass* passPtr = techniquePtr->getPass(it->pass_);
+                if (passPtr)
+                {
+                    // change the value of the parameter depending on its type
+                    switch (it->valueType_)
+                    {
+                        case MT_Type::Int:
+                            passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueInt_);
+                            break;
+                        case MT_Type::Float:
+                            passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueFloat_);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                else
+                    COUT(2) << "Warning: No pass " << it->pass_ << " in technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or pass has no shader." << std::endl;
+            }
+            else
+                COUT(2) << "Warning: No technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or technique has no pass with shader." << std::endl;
+        }
+        this->parameters_.clear();
+    }
+
+    /**
+        @brief Detects if the Cg program manager plugin is active.
+    */
+    /* static */ bool Shader::hasCgProgramManager()
+    {
+        if (Ogre::Root::getSingletonPtr())
+        {
             const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
             for (size_t i = 0; i < plugins.size(); ++i)
-            {
                 if (plugins[i]->getName() == "Cg Program Manager")
-                {
-                    Shader::bLoadedCgPlugin_s = true;
-                    break;
-                }
-            }
-        }
-
-        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
-    }
-
-    Shader::~Shader()
-    {
-        if (this->compositorInstance_ && this->bLoadCompositor_)
-        {
-            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
-            assert(viewport);
-            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
-        }
-
-    }
-
-    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
-    {
-        this->scenemanager_ = scenemanager;
-        this->bViewportInitialized_ = false;
-    }
-
-    void Shader::tick(float dt)
-    {
-        SUPER(Shader, tick, dt);
-
-        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
-        {
-            this->bViewportInitialized_ = true;
-            this->updateVisibility();
-        }
-    }
-
-    void Shader::changedCompositor()
-    {
-        if (this->bLoadCompositor_)
-        {
-            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
-            assert(viewport);
-            if (!this->oldcompositor_.empty())
-            {
-                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
-                this->compositorInstance_ = 0;
-            }
-            if (!this->compositor_.empty())
-            {
-                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
-                if (!this->compositorInstance_)
-                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
-                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
-            }
-            this->oldcompositor_ = this->compositor_;
-        }
-    }
-
-    void Shader::updateVisibility()
-    {
-        if (this->compositorInstance_ && this->scenemanager_)
-            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
-    }
-
-    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
-    {
-        if (Shader::_setParameter(material, technique, pass, parameter, value))
-        {
-            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
-            {
-                this->compositorInstance_->setEnabled(false);
-                this->compositorInstance_->setEnabled(true);
-            }
-        }
-    }
-
-    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
-    {
-        if (Shader::_setParameter(material, technique, pass, parameter, value))
-        {
-            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
-            {
-                this->compositorInstance_->setEnabled(false);
-                this->compositorInstance_->setEnabled(true);
-            }
-        }
-    }
-
-    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-        {
-            if (pointer->first)
-            {
-                if ((*static_cast<float*>(pointer->second)) != value)
-                {
-                    (*static_cast<float*>(pointer->second)) = value;
                     return true;
-                }
-            }
-            else
-            {
-                if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
-                {
-                    (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
-                    return true;
-                }
-            }
         }
         return false;
     }
-
-    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-        {
-            if (pointer->first)
-            {
-                if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
-                {
-                    (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
-                    return true;
-                }
-            }
-            else
-            {
-                if ((*static_cast<int*>(pointer->second)) != value)
-                {
-                    (*static_cast<int*>(pointer->second)) = value;
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-        {
-            if (pointer->first)
-                return (*static_cast<float*>(pointer->second));
-            else
-                return static_cast<float>(*static_cast<int*>(pointer->second));
-        }
-        else
-            return 0;
-    }
-
-    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-            return pointer->first;
-        else
-            return false;
-    }
-
-    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
-        if (pointer)
-            return (!pointer->first);
-        else
-            return false;
-    }
-
-    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
-    {
-        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
-            return 0;
-
-        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
-        if (material_iterator != Shader::parameters_s.end())
-        {
-            TechniqueVector& technique_vector = material_iterator->second;
-            if (technique < technique_vector.size())
-            {
-                PassVector& pass_vector = technique_vector[technique];
-                if (pass < pass_vector.size())
-                {
-                    ParameterMap& parameter_map = pass_vector[pass];
-                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
-
-                    if (parameter_iterator != parameter_map.end())
-                        return (&parameter_iterator->second);
-                    else
-                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
-                }
-                else
-                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
-            }
-            else
-                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
-        }
-        else
-        {
-            bool foundAtLeastOneShaderParameter = false;
-            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
-            Ogre::Material* material_pointer = 0;
-
-            while (iterator.hasMoreElements())
-            {
-                Ogre::Resource* resource = iterator.getNext().get();
-                if (resource->getName() == material)
-                    material_pointer = (Ogre::Material*)resource;
-            }
-
-            if (!material_pointer)
-            {
-                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
-                return 0;
-            }
-
-            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
-            {
-                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
-                if (!technique_pointer)
-                    continue;
-
-                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
-                {
-                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
-                    if (!pass_pointer)
-                        continue;
-
-                    if (!pass_pointer->getFragmentProgramName().empty())
-                    {
-                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
-                        if (!parameter_pointer)
-                            continue;
-
-                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
-                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
-                        {
-                            void* temp = (definition_iterator->second.isFloat())
-                                            ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
-                                            : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
-                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
-
-                            TechniqueVector& technique_vector = Shader::parameters_s[material];
-                            technique_vector.resize(technique + 1);
-                            PassVector& pass_vector = technique_vector[technique];
-                            pass_vector.resize(pass + 1);
-                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
-                            foundAtLeastOneShaderParameter = true;
-                        }
-                    }
-                }
-            }
-
-            // recursive call if the material was added to the map
-            if (foundAtLeastOneShaderParameter)
-                return Shader::getParameterPointer(material, technique, pass, parameter);
-        }
-        return 0;
-    }
 }
Index: code/trunk/src/libraries/tools/Shader.h
===================================================================
--- code/trunk/src/libraries/tools/Shader.h	(revision 8078)
+++ code/trunk/src/libraries/tools/Shader.h	(revision 8079)
@@ -36,23 +36,23 @@
 #include <vector>
 
+#include <OgreCompositorInstance.h>
+
+#include "util/MultiType.h"
 #include "util/OgreForwardRefs.h"
-#include "tools/interfaces/Tickable.h"
+#include "core/ViewportEventListener.h"
 
 namespace orxonox
 {
-    class _ToolsExport Shader : public Tickable
+    /**
+        @brief Shader is a wrapper class around Ogre::CompositorInstance. It provides some
+        functions to easily change the visibility and parameters for shader programs.
+    */
+    class _ToolsExport Shader : public ViewportEventListener, public Ogre::CompositorInstance::Listener
     {
-        typedef std::pair<bool, void*>                  ParameterPointer;
-        typedef std::map<std::string, ParameterPointer> ParameterMap;
-        typedef std::vector<ParameterMap>               PassVector;
-        typedef std::vector<PassVector>                 TechniqueVector;
-        typedef std::map<std::string, TechniqueVector>  MaterialMap;
-
         public:
             Shader(Ogre::SceneManager* scenemanager = 0);
             virtual ~Shader();
 
-            virtual void tick(float dt);
-
+            /// Defines if the shader is visible or not.
             inline void setVisible(bool bVisible)
             {
@@ -63,45 +63,66 @@
                 }
             }
+            /// Returns whether or not the shader is visible.
             inline bool isVisible() const
                 { return this->bVisible_; }
             void updateVisibility();
 
-            inline void setCompositor(const std::string& compositor)
+            /// Defines the compositor's name (located in a .compositor file).
+            inline void setCompositorName(const std::string& name)
             {
-                if (this->compositor_ != compositor)
+                if (this->compositorName_ != name)
                 {
-                    this->compositor_ = compositor;
-                    this->changedCompositor();
+                    this->compositorName_ = name;
+                    this->changedCompositorName();
                 }
             }
-            inline const std::string& getCompositor() const
-                { return this->compositor_; }
-            void changedCompositor();
+            /// Returns the compositor's name.
+            inline const std::string& getCompositorName() const
+                { return this->compositorName_; }
+            void changedCompositorName();
+            void changedCompositorName(Ogre::Viewport* viewport);
 
-            void setSceneManager(Ogre::SceneManager* scenemanager);
+            /// Sets the scenemanager (usually provided in the constructor, but can be set later). Shouldn't be changed once it's set.
+            inline void setSceneManager(Ogre::SceneManager* scenemanager)
+                { this->scenemanager_ = scenemanager; }
+            /// Returns the scene manager.
             inline Ogre::SceneManager* getSceneManager() const
                 { return this->scenemanager_; }
 
-            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
-            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+            virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera);
 
-            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
-            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
-            static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static bool  getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static bool  getParameterIsInt  (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
-            static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            void setParameter(size_t technique, size_t pass, const std::string& parameter, float value);
+            void setParameter(size_t technique, size_t pass, const std::string& parameter, int value);
+
+            virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr);
 
         private:
-            Ogre::SceneManager* scenemanager_;
-            Ogre::CompositorInstance* compositorInstance_;
-            bool bVisible_;
-            bool bLoadCompositor_;
-            bool bViewportInitialized_;
-            std::string compositor_;
-            std::string oldcompositor_;
+            static bool hasCgProgramManager();
 
-            static MaterialMap parameters_s;
-            static bool bLoadedCgPlugin_s;
+            Ogre::SceneManager* scenemanager_;              ///< The scenemanager for which the shader is active
+            Ogre::CompositorInstance* compositorInstance_;  ///< The compositor instance representing the wrapped compositor
+            bool bVisible_;                                 ///< True if the shader should be visible
+            bool bLoadCompositor_;                          ///< True if the compositor should be loaded (usually false if no graphics)
+            std::string compositorName_;                    ///< The name of the current compositor
+            std::string oldcompositorName_;                 ///< The name of the previous compositor (used to unregister)
+
+        private:
+            void addAsListener();
+
+            /// Helper struct to store parameters for shader programs.
+            struct ParameterContainer
+            {
+                size_t technique_;          ///< The ID of the technique
+                size_t pass_;               ///< The ID of the pass
+                std::string parameter_;     ///< The name of the parameter
+
+                int valueInt_;              ///< The desired int value of the parameter
+                float valueFloat_;          ///< The desired float value of the parameter
+
+                MT_Type::Value valueType_;  ///< The type of the parameter (currently only int or float)
+            };
+
+            std::list<ParameterContainer> parameters_;  ///< The list of parameters that should be set on the next update
+            bool registeredAsListener_;                 ///< True if the shader should register itself as listener at the compositor
     };
 }
Index: code/trunk/src/libraries/tools/Timer.cc
===================================================================
--- code/trunk/src/libraries/tools/Timer.cc	(revision 8078)
+++ code/trunk/src/libraries/tools/Timer.cc	(revision 8079)
@@ -35,4 +35,6 @@
 
 #include <set>
+
+#include <boost/bimap.hpp>
 
 #include "util/Clock.h"
@@ -41,25 +43,54 @@
 #include "core/command/CommandExecutor.h"
 #include "core/command/Functor.h"
+#include "tools/interfaces/TimeFactorListener.h"
 
 namespace orxonox
 {
     SetConsoleCommand("delay", &delay).argumentCompleter(1, autocompletion::command());
+    SetConsoleCommand("delayreal", &delayreal).argumentCompleter(1, autocompletion::command());
+    SetConsoleCommand("killdelay", &killdelay);
     SetConsoleCommand("killdelays", &killdelays);
 
-    static std::set<Timer*> delaytimerset;
-
-    /**
-        @brief Console-command: Calls another console command after @a delay seconds.
+    static boost::bimap<unsigned int, Timer*> delaytimers;
+    static unsigned int delayHandleCounter = 0;
+
+    /**
+        @brief Console-command: Calls another console command after @a delay seconds (game time).
         @param delay The delay in seconds
         @param command The console command
-    */
-    void delay(float delay, const std::string& command)
-    {
-        Timer* delaytimer = new Timer();
-        delaytimerset.insert(delaytimer);
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int delay(float delay, const std::string& command)
+    {
+        return addDelayedCommand(new Timer(), delay, command);
+    }
+
+    /**
+        @brief Console-command: Calls another console command after @a delay seconds (real time)
+        @param delay The delay in seconds
+        @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int delayreal(float delay, const std::string& command)
+    {
+        return addDelayedCommand(new RealTimer(), delay, command);
+    }
+
+    /**
+        @brief Helper function, used by delay() and delayreal() to add a delayed command.
+        @param timer The timer which will execute the command
+        @param delay The delay in seconds
+        @param command The console command
+        @return The handle of the delayed command, can be used as argument for killdelay()
+    */
+    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command)
+    {
+        delaytimers.insert(boost::bimap<unsigned int, Timer*>::value_type(++delayHandleCounter, timer));
 
         const ExecutorStaticPtr& delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
-        delayexecutor->setDefaultValues(delaytimer, command);
-        delaytimer->setTimer(delay, false, delayexecutor);
+        delayexecutor->setDefaultValues(timer, command);
+        timer->setTimer(delay, false, delayexecutor);
+
+        return delayHandleCounter;
     }
 
@@ -73,5 +104,5 @@
         CommandExecutor::execute(command);
         timer->destroy();
-        delaytimerset.erase(timer);
+        delaytimers.right.erase(timer);
     }
 
@@ -81,8 +112,21 @@
     void killdelays()
     {
-        for (std::set<Timer*>::iterator it = delaytimerset.begin(); it != delaytimerset.end(); ++it)
-            (*it)->destroy();
-
-        delaytimerset.clear();
+        for (boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.begin(); it != delaytimers.left.end(); ++it)
+            it->second->destroy();
+
+        delaytimers.clear();
+    }
+
+    /**
+        @brief Console-command: Kills a delayed command with given handle.
+    */
+    void killdelay(unsigned int handle)
+    {
+        boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.find(handle);
+        if (it != delaytimers.left.end())
+        {
+            it->second->destroy();
+            delaytimers.left.erase(it);
+        }
     }
 
@@ -93,5 +137,5 @@
     {
         this->init();
-        RegisterObject(Timer);
+        RegisterRootObject(Timer);
     }
 
@@ -106,5 +150,5 @@
     {
         this->init();
-        RegisterObject(Timer);
+        RegisterRootObject(Timer);
 
         this->setTimer(interval, bLoop, executor, bKillAfterCall);
@@ -123,4 +167,12 @@
 
         this->time_ = 0;
+    }
+
+    /**
+        @brief Returns the current time factor of the game.
+    */
+    float Timer::getTimeFactor()
+    {
+        return TimeFactorListener::getTimeFactor();
     }
 
@@ -168,3 +220,24 @@
         }
     }
+
+    ///////////////
+    // RealTimer //
+    ///////////////
+    /// @copydoc Timer::Timer
+    RealTimer::RealTimer()
+    {
+        RegisterObject(RealTimer);
+    }
+
+    /// @copydoc Timer::Timer(float, bool, const ExecutorPtr&, bool)
+    RealTimer::RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall) : Timer(interval, bLoop, executor, bKillAfterCall)
+    {
+        RegisterObject(RealTimer);
+    }
+
+    /// Returns always 1 because RealTimer doesn't depend on the game time.
+    float RealTimer::getTimeFactor()
+    {
+        return 1;
+    }
 }
Index: code/trunk/src/libraries/tools/Timer.h
===================================================================
--- code/trunk/src/libraries/tools/Timer.h	(revision 8078)
+++ code/trunk/src/libraries/tools/Timer.h	(revision 8079)
@@ -81,18 +81,26 @@
 #include "core/OrxonoxClass.h"
 #include "core/command/Executor.h"
-#include "tools/interfaces/TimeFactorListener.h"
 
 namespace orxonox
 {
-    void delay(float delay, const std::string& command);
-    void killdelays();
+    unsigned int delay(float delay, const std::string& command);
+    unsigned int delayreal(float delay, const std::string& command);
+
+    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command);
     void executeDelayedCommand(Timer* timer, const std::string& command);
 
+    void killdelay(unsigned int handle);
+    void killdelays();
+
     /**
-        @brief Timer is a helper class that executes a function after a given amount of time.
+        @brief Timer is a helper class that executes a function after a given amount of seconds in game-time.
 
         @see See @ref TimerExample "Timer.h" for an example.
+
+        The time interval of Timer depends on the game time, hence it stops if the game is paused or runs
+        slower/faster if the game-speed is modified. See RealTimer for a timer class which doesn't depend
+        on the game time.
     */
-    class _ToolsExport Timer : public TimeFactorListener
+    class _ToolsExport Timer : virtual public OrxonoxClass
     {
         public:
@@ -123,26 +131,26 @@
             void run();
 
-            /// Re-starts the Timer: The executor will be called after @a interval seconds.
+            /// Re-starts the timer: The executor will be called after @a interval seconds.
             inline void startTimer()
                 { this->bActive_ = true; this->time_ = this->interval_; }
-            /// Stops the Timer.
+            /// Stops the timer.
             inline void stopTimer()
                 { this->bActive_ = false; this->time_ = this->interval_; }
-            /// Pauses the Timer - it will continue with the actual state if you call unpauseTimer().
+            /// Pauses the timer - it will continue with the actual state if you call unpauseTimer().
             inline void pauseTimer()
                 { this->bActive_ = false; }
-            /// Unpauses the Timer - continues with the given state.
+            /// Unpauses the timer - continues with the given state.
             inline void unpauseTimer()
                 { this->bActive_ = true; }
-            /// Returns true if the Timer is active (neither stopped nor paused).
+            /// Returns true if the timer is active (neither stopped nor paused).
             inline bool isActive() const
                 { return this->bActive_; }
-            /// Returns the remaining time until the Timer calls the executor.
+            /// Returns the remaining time until the timer calls the executor.
             inline float getRemainingTime() const
                 { return static_cast<float>(this->time_ / 1000000.0f); }
-            /// Increases the remaining time of the Timer by the given amount of time (in seconds).
+            /// Increases the remaining time of the timer by the given amount of time (in seconds).
             inline void addTime(float time)
                 { if (time > 0.0f) this->time_ += static_cast<long long>(time * 1000000.0f); }
-            /// Decreases the remaining time of the Timer by the given amount of time (in seconds)
+            /// Decreases the remaining time of the timer by the given amount of time (in seconds)
             inline void removeTime(float time)
                 { if (time > 0.0f) this->time_ -= static_cast<long long>(time * 1000000.0f); }
@@ -156,4 +164,7 @@
             void tick(const Clock& time);
 
+        protected:
+            virtual float getTimeFactor();
+
         private:
             void init();
@@ -163,9 +174,25 @@
             long long interval_;    //!< The time-interval in micro seconds
             bool bLoop_;            //!< If true, the executor gets called every @a interval seconds
-            bool bActive_;          //!< If true, the Timer ticks and calls the executor if the time's up
+            bool bActive_;          //!< If true, the timer ticks and calls the executor if the time's up
             bool bKillAfterCall_;   //!< If true the timer gets deleted after it expired and called the executor
 
             long long time_;        //!< Internal variable, counting the time untill the next executor-call
     };
+
+    /**
+        @brief RealTimer is a helper class that executes a function after a given amount of seconds in real-time.
+
+        The time interval of RealTimer doesn't depend on the game time, it will also call the function
+        if the game is paused. See Timer for a timer class that depends on the game time.
+    */
+    class _ToolsExport RealTimer : public Timer
+    {
+        public:
+            RealTimer();
+            RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall = false);
+
+        protected:
+            virtual float getTimeFactor();
+    };
 }
 
Index: code/trunk/src/libraries/tools/ToolsPrereqs.h
===================================================================
--- code/trunk/src/libraries/tools/ToolsPrereqs.h	(revision 8078)
+++ code/trunk/src/libraries/tools/ToolsPrereqs.h	(revision 8079)
@@ -85,4 +85,5 @@
     class Mesh;
     class ParticleInterface;
+    class RealTimer;
     class ResourceCollection;
     class ResourceLocation;
Index: code/trunk/src/modules/designtools/ScreenshotManager.cc
===================================================================
--- code/trunk/src/modules/designtools/ScreenshotManager.cc	(revision 8078)
+++ code/trunk/src/modules/designtools/ScreenshotManager.cc	(revision 8079)
@@ -25,31 +25,26 @@
     {
         Ogre::RenderWindow* pRenderWindow = GraphicsManager::getInstance().getRenderWindow();
-        int gridSize = 3;
-        std::string fileExtension = ".png";
-        bool overlayFlag = true;
 
         //set file extension for the Screenshot files
-        mFileExtension   = fileExtension;
+        this->mFileExtension_  = ".png";
         // the gridsize
-        mGridSize        = gridSize;
+        this->mGridSize_ = 3;
         // flag for overlay rendering
-        mDisableOverlays = overlayFlag;
+        this->mDisableOverlays_ = true;
         //get current window size
-        mWindowWidth   = pRenderWindow->getWidth();
-        mWindowHeight  = pRenderWindow->getHeight();
+        this->mWindowWidth_   = pRenderWindow->getWidth();
+        this->mWindowHeight_  = pRenderWindow->getHeight();
         //create temporary texture
-        mTempTex = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex",
-                                                                  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
-                                                                    mWindowWidth, mWindowHeight,0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET);
+        this->mTempTex_ = Ogre::TextureManager::getSingleton().createManual("ScreenShotTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, this->mWindowWidth_, this->mWindowHeight_, 0, Ogre::PF_B8G8R8, Ogre::TU_RENDERTARGET);
 
         //get The current Render Target of the temp Texture
-        mRT = mTempTex->getBuffer()->getRenderTarget();
+        this->mRT_ = this->mTempTex_->getBuffer()->getRenderTarget();
 
         //HardwarePixelBufferSharedPtr to the Buffer of the temp Texture
-        mBuffer = mTempTex->getBuffer();
+        this->mBuffer_ = this->mTempTex_->getBuffer();
 
         //create PixelBox
-            uint8_t* data_ = new uint8_t[(mWindowWidth * mGridSize) * (mWindowHeight * mGridSize) * 3];
-        mFinalPicturePB = Ogre::PixelBox(mWindowWidth * mGridSize,mWindowHeight * mGridSize,1,Ogre::PF_B8G8R8,data_);
+        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
+        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
 
     }
@@ -63,7 +58,11 @@
 
 
-    /* Creates a screenshot with the given camera.
-    * @param camera Pointer to the camera "looking at" the scene of interest
-    * @param fileName the filename of the screenshot file.
+    /**
+    @brief
+        Creates a screenshot with the given camera.
+    @param camera
+        Pointer to the camera "looking at" the scene of interest
+    @param fileName
+        the filename of the screenshot file.
     */
     void ScreenshotManager::makeScreenshot() const
@@ -73,9 +72,9 @@
 
         //Remove all viewports, so the added Viewport(camera) ist the only
-        mRT->removeAllViewports();
-        mRT->addViewport(camera);
+        mRT_->removeAllViewports();
+        mRT_->addViewport(camera);
 
         //set the viewport settings
-        Ogre::Viewport *vp = mRT->getViewport(0);
+        Ogre::Viewport *vp = mRT_->getViewport(0);
         vp->setClearEveryFrame(true);
         vp->setOverlaysEnabled(false);
@@ -85,15 +84,15 @@
 
         // we disable overlay rendering if it is set in config file and the viewport setting is enabled
-        if(mDisableOverlays && enableOverlayFlag)
+        if(mDisableOverlays_ && enableOverlayFlag)
             GraphicsManager::getInstance().getViewport()->setOverlaysEnabled(false);
 
-        if(mGridSize <= 1)
+        if(mGridSize_ <= 1)
         {
             // Simple case where the contents of the screen are taken directly
             // Also used when an invalid value is passed within gridSize (zero or negative grid size)
-            mRT->update();    //render
+            mRT_->update();    //render
 
             //write the file on the Harddisk
-            mRT->writeContentsToFile(fileName + "." + mFileExtension);
+            mRT_->writeContentsToFile(fileName + "." + mFileExtension_);
         }
         else
@@ -105,13 +104,13 @@
 
             // compute the Stepsize for the drid
-            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize;
-            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize;
+            Ogre::Real frustumGridStepHorizontal  = (originalFrustumRight * 2) / mGridSize_;
+            Ogre::Real frustumGridStepVertical  = (originalFrustumTop * 2) / mGridSize_;
 
             // process each grid
             Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
-            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize * mGridSize; nbScreenshots++)
+            for (unsigned int nbScreenshots = 0; nbScreenshots < mGridSize_ * mGridSize_; nbScreenshots++)
             {
-                int y = nbScreenshots / mGridSize;
-                int x = nbScreenshots - y * mGridSize;
+                int y = nbScreenshots / mGridSize_;
+                int x = nbScreenshots - y * mGridSize_;
 
                 // Shoggoth frustum extents setting
@@ -127,11 +126,11 @@
                 // ignore time duration between frames
                 Ogre::Root::getSingletonPtr()->clearEventTimes();
-                mRT->update();    //render
+                mRT_->update();    //render
 
                 //define the current
-                Ogre::Box subBox = Ogre::Box(x* mWindowWidth,y * mWindowHeight,x * mWindowWidth + mWindowWidth, y * mWindowHeight + mWindowHeight);
+                Ogre::Box subBox = Ogre::Box(x* mWindowWidth_,y * mWindowHeight_,x * mWindowWidth_ + mWindowWidth_, y * mWindowHeight_ + mWindowHeight_);
                 //copy the content from the temp buffer into the final picture PixelBox
                 //Place the tempBuffer content at the right position
-                mBuffer->blitToMemory(mFinalPicturePB.getSubVolume(subBox));
+                mBuffer_->blitToMemory(mFinalPicturePB_.getSubVolume(subBox));
 
             }
@@ -142,7 +141,7 @@
             Ogre::Image finalImage; //declare the final Image Object
             //insert the PixelBox data into the Image Object
-            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB.data), mFinalPicturePB.getWidth(),mFinalPicturePB.getHeight(),Ogre::PF_B8G8R8);
+            finalImage = finalImage.loadDynamicImage(static_cast<unsigned char*>(mFinalPicturePB_.data), mFinalPicturePB_.getWidth(), mFinalPicturePB_.getHeight(),Ogre::PF_B8G8R8);
             // Save the Final image to a file
-            finalImage.save(fileName + "." + mFileExtension);
+            finalImage.save(fileName + "." + mFileExtension_);
 
         }
@@ -157,4 +156,27 @@
     }
 
+    /**
+    @brief
+        Set the size of the grid.
+    @param size
+        The size of the grid.
+    */
+    void ScreenshotManager::setGridSize(unsigned int size)
+    {
+        if(size == this->mGridSize_)
+            return;
+
+        this->mGridSize_ = size;
+        // New PixelBox for the changed size.
+        uint8_t* data_ = new uint8_t[(this->mWindowWidth_ * this->mGridSize_) * (this->mWindowHeight_ * this->mGridSize_) * 3];
+        this->mFinalPicturePB_ = Ogre::PixelBox(this->mWindowWidth_ * this->mGridSize_, this->mWindowHeight_ * this->mGridSize_, 1, Ogre::PF_B8G8R8, data_);
+    }
+
+    /**
+    @brief
+        Get a timestamp for the curent time instant.
+    @return
+        Returns a string with the timestamp.
+    */
     std::string ScreenshotManager::getTimestamp()
     {
Index: code/trunk/src/modules/designtools/ScreenshotManager.h
===================================================================
--- code/trunk/src/modules/designtools/ScreenshotManager.h	(revision 8078)
+++ code/trunk/src/modules/designtools/ScreenshotManager.h	(revision 8079)
@@ -20,15 +20,7 @@
 {
 
-
-    /* Class encapsulates Screenshot functionality and provides a method for making multi grid screenshots.
-    *  pRenderWindow:    Pointer to the render window.  This could be "mWindow" from the ExampleApplication,
-    *              the window automatically created obtained when calling
-    *              Ogre::Root::getSingletonPtr()->initialise(false) and retrieved by calling
-    *              "Ogre::Root::getSingletonPtr()->getAutoCreatedWindow()", or the manually created
-    *              window from calling "mRoot->createRenderWindow()".
-    *  gridSize:      The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the
-                screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
-    *  fileExtension:    The extension of the screenshot file name, hence the type of graphics file to generate.
-    *              To generate "MyScreenshot.png" this parameter would contain ".png".
+    /**
+    @brief
+        Class encapsulates Screenshot functionality and provides a method for making multi grid screenshots.
     */
     class ScreenshotManager : public OrxonoxClass, public Singleton<ScreenshotManager>
@@ -36,32 +28,35 @@
         friend class Singleton<ScreenshotManager>;
 
-    public:
-        ScreenshotManager();
-        ~ScreenshotManager();
+        public:
+            ScreenshotManager();
+            virtual ~ScreenshotManager();
 
-      /* Creates a screenshot with the given camera.
-        * @param camera Pointer to the camera "looking at" the scene of interest
-        * @param fileName the filename of the screenshot file.
-      */
-        void makeScreenshot() const;
+            void makeScreenshot() const; //!< Creates a screenshot with the given camera.
 
-        static void makeScreenshot_s()
-            { getInstance().makeScreenshot(); }
+            /**
+            @brief Creates a screenshot with a given size.
+            @param size Size is factor by which the current screen size is scaled.
+            */
+            static void makeScreenshot_s(unsigned int size)
+                { getInstance().setGridSize(size); getInstance().makeScreenshot(); }
 
-    protected:
-        static std::string getTimestamp();
+            void setGridSize(unsigned int size); //!< Set the size of the grid.
 
-        std::string    mFileExtension;
-        unsigned int   mGridSize, mWindowWidth, mWindowHeight;
-        bool           mDisableOverlays;
-        //temp texture with current screensize
-        Ogre::TexturePtr mTempTex;
-        Ogre::RenderTexture* mRT;
-        Ogre::HardwarePixelBufferSharedPtr mBuffer;
-        //PixelBox for a large Screenshot, if grid size is > 1
-        Ogre::PixelBox  mFinalPicturePB;
-        uint8_t* data_;
+        protected:
+            static std::string getTimestamp();
 
-        static ScreenshotManager* singletonPtr_s;
+            std::string mFileExtension_;
+            unsigned int mGridSize_; //!< The magnification factor.  A 2 will create a 2x2 grid, doubling the size of the screenshot.  A 3 will create a 3x3 grid, tripling the size of the screenshot.
+            unsigned int mWindowWidth_, mWindowHeight_;
+            bool mDisableOverlays_;
+            //! temp texture with current screensize
+            Ogre::TexturePtr mTempTex_;
+            Ogre::RenderTexture* mRT_;
+            Ogre::HardwarePixelBufferSharedPtr mBuffer_;
+            //! PixelBox for a large Screenshot, if grid size is > 1
+            Ogre::PixelBox  mFinalPicturePB_;
+            uint8_t* data_;
+
+            static ScreenshotManager* singletonPtr_s;
     };
 
Index: code/trunk/src/modules/designtools/SkyboxGenerator.cc
===================================================================
--- code/trunk/src/modules/designtools/SkyboxGenerator.cc	(revision 8078)
+++ code/trunk/src/modules/designtools/SkyboxGenerator.cc	(revision 8079)
@@ -59,5 +59,5 @@
 
         this->setConfigValues();
-        takeScreenshot_ = false;
+        this->takeScreenshot_ = false;
         this->captionsRemoved_ = false;
     }
Index: code/trunk/src/modules/notifications/NotificationManager.cc
===================================================================
--- code/trunk/src/modules/notifications/NotificationManager.cc	(revision 8078)
+++ code/trunk/src/modules/notifications/NotificationManager.cc	(revision 8079)
@@ -103,6 +103,10 @@
     {
         // Destroys all NotificationQueues that have been registered with the NotificationManager.
-        for(std::map<const std::string, NotificationQueue*>::iterator it = this->queues_.begin(); it != this->queues_.end(); it++)
+        std::map<const std::string, NotificationQueue*>::iterator it = this->queues_.begin();
+        while(it != this->queues_.end())
+        {
             it->second->destroy(true);
+            it = this->queues_.begin();
+        }
 
         this->queues_.clear();
@@ -298,10 +302,10 @@
         }
 
+        COUT(4) << "NotificationListener '" << identifier << "' unregistered with the NotificationManager." << std::endl;
+
         // Remove the NotificationListener from the list of NotificationListeners.
         this->listenerList_.erase(listener);
         // Remove the Notifications list that was associated with the input NotificationListener.
         this->notificationLists_.erase(identifier);
-
-        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
     }
 
@@ -361,4 +365,5 @@
     bool NotificationManager::registerQueue(NotificationQueue* queue)
     {
+        COUT(4) << "NotificationQueue '" << queue->getName() << "' registered with the NotificationManager." << std::endl;
         return this->queues_.insert(std::pair<const std::string, NotificationQueue*>(queue->getName(), queue)).second;
     }
@@ -372,4 +377,5 @@
     void NotificationManager::unregisterQueue(NotificationQueue* queue)
     {
+        COUT(4) << "NotificationQueue '" << queue->getName() << "' unregistered with the NotificationManager." << std::endl;
         this->queues_.erase(queue->getName());
     }
Index: code/trunk/src/modules/notifications/NotificationQueue.cc
===================================================================
--- code/trunk/src/modules/notifications/NotificationQueue.cc	(revision 8078)
+++ code/trunk/src/modules/notifications/NotificationQueue.cc	(revision 8079)
@@ -137,4 +137,6 @@
             GUIManager::getInstance().getLuaState()->doString("NotificationLayer.removeQueue(\"" + this->getName() +  "\")");
 
+        COUT(3) << "NotificationQueue '" << this->getName() << "' destroyed." << std::endl;
+
         this->OrxonoxClass::destroy();
     }
@@ -167,7 +169,6 @@
             while(it != this->ordering_.upper_bound(&this->timeLimit_))
             {
-                std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator temp = it;
-                it++;
-                this->remove(temp); // Remove the Notifications that have expired.
+                this->remove(it); // Remove the Notifications that have expired.
+                it = this->ordering_.begin();
             }
 
@@ -248,4 +249,6 @@
         if(GameMode::showsGraphics())
             GUIManager::getInstance().getLuaState()->doString("NotificationLayer.pushNotification(\"" + this->getName() + "\", \"" + notification->getMessage() + "\")");
+
+        COUT(5) << "Notification \"" << notification->getMessage() << "\" pushed to NotificationQueue '" << this->getName() << "'" << endl;
     }
 
@@ -259,4 +262,5 @@
         // Get all the NotificationContainers that were sent the same time the NotificationContainer we want to pop was sent.
         std::pair<std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator, std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator> iterators = this->ordering_.equal_range(container);
+
         // Iterate through all suspects and remove the container as soon as we find it.
         for(std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator it = iterators.first; it != iterators.second; it++)
@@ -264,4 +268,5 @@
             if(container == *it)
             {
+                COUT(5) << "Notification \"" << (*it)->notification->getMessage() << "\" popped from NotificationQueue '" << this->getName() << "'" << endl;
                 this->ordering_.erase(it);
                 break;
@@ -290,4 +295,7 @@
         // Get the index at which the Notification is.
         std::vector<NotificationContainer*>::difference_type index = it - this->notifications_.begin ();
+
+        COUT(5) << "Notification \"" << (*it)->notification->getMessage() << "\" removed from NotificationQueue '" << this->getName() << "'" << endl;
+
         this->ordering_.erase(containerIterator);
         this->notifications_.erase(it);
@@ -310,4 +318,5 @@
     void NotificationQueue::clear(bool noGraphics)
     {
+        COUT(4) << "Clearing NotificationQueue " << this->getName() << "." << endl;
         this->ordering_.clear();
         // Delete all NotificationContainers in the list.
@@ -372,5 +381,5 @@
     /**
     @brief
-        Produces all targets of the NotificationQueue concatinated as string, with kommas (',') as seperators.
+        Produces all targets of the NotificationQueue concatinated as string, with commas (',') as seperators.
     @return
         Returns the targets as a string.
Index: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 8078)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 8079)
@@ -54,5 +54,5 @@
 
         this->distance_ = 100.0f;
-        this->targetName_ = BLANKSTRING;
+        this->targetName_ = "";
         this->singleTargetMode_ = false;
     }
@@ -181,5 +181,5 @@
     {
         // If the targetname is no blank string single-target mode is enabled.
-        if(targetname.compare(BLANKSTRING) != 0)
+        if(targetname != "")
             this->singleTargetMode_ = true;
         else
Index: code/trunk/src/modules/objects/triggers/DistanceTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceTrigger.cc	(revision 8078)
+++ code/trunk/src/modules/objects/triggers/DistanceTrigger.cc	(revision 8079)
@@ -50,5 +50,5 @@
     this->distance_ = 100;
     this->targetMask_.exclude(Class(BaseObject));
-    this->targetName_ = BLANKSTRING;
+    this->targetName_ = "";
     this->singleTargetMode_ = false;
   }
Index: code/trunk/src/modules/objects/triggers/DistanceTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceTrigger.h	(revision 8078)
+++ code/trunk/src/modules/objects/triggers/DistanceTrigger.h	(revision 8079)
@@ -70,5 +70,5 @@
 
       inline void setTargetName(const std::string& targetname)
-        { if(targetname.compare(BLANKSTRING) != 0) this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
+        { if(targetname != "") this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
       inline const std::string& getTargetName(void)
         { return this->targetName_; }
Index: code/trunk/src/modules/overlays/OverlaysPrereqs.h
===================================================================
--- code/trunk/src/modules/overlays/OverlaysPrereqs.h	(revision 8078)
+++ code/trunk/src/modules/overlays/OverlaysPrereqs.h	(revision 8079)
@@ -89,4 +89,5 @@
     class KillMessage;
     class LastManStandingInfos;
+    class PauseNotice;
     class TeamBaseMatchScore;
     class UnderAttackHealthBar;
Index: code/trunk/src/modules/overlays/hud/CMakeLists.txt
===================================================================
--- code/trunk/src/modules/overlays/hud/CMakeLists.txt	(revision 8078)
+++ code/trunk/src/modules/overlays/hud/CMakeLists.txt	(revision 8079)
@@ -16,3 +16,4 @@
   GametypeFadingMessage.cc
   LastManStandingInfos.cc
+  PauseNotice.cc
 )
Index: code/trunk/src/modules/overlays/hud/PauseNotice.cc
===================================================================
--- code/trunk/src/modules/overlays/hud/PauseNotice.cc	(revision 8079)
+++ code/trunk/src/modules/overlays/hud/PauseNotice.cc	(revision 8079)
@@ -0,0 +1,59 @@
+/*
+ *   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 "PauseNotice.h"
+
+#include "core/CoreIncludes.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(PauseNotice);
+
+    PauseNotice::PauseNotice(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(PauseNotice);
+
+        this->owner_ = 0;
+    }
+
+    void PauseNotice::changedOwner()
+    {
+        SUPER(PauseNotice, changedOwner);
+
+        this->owner_ = orxonox_cast<PlayerInfo*>(this->getOwner());
+    }
+
+    void PauseNotice::changedTimeFactor(float factor_new, float factor_old)
+    {
+        if (factor_new == 0)
+            this->setCaption("Paused");
+        else
+            this->setCaption("");
+    }
+}
Index: code/trunk/src/modules/overlays/hud/PauseNotice.h
===================================================================
--- code/trunk/src/modules/overlays/hud/PauseNotice.h	(revision 8079)
+++ code/trunk/src/modules/overlays/hud/PauseNotice.h	(revision 8079)
@@ -0,0 +1,53 @@
+/*
+ *   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 _PauseNotice_H__
+#define _PauseNotice_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/TimeFactorListener.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport PauseNotice : public OverlayText, public TimeFactorListener
+    {
+        public:
+            PauseNotice(BaseObject* creator);
+
+            virtual void changedOwner();
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old);
+
+        private:
+            PlayerInfo* owner_;
+    };
+}
+#endif /* _PauseNotice_H__ */
Index: code/trunk/src/modules/pickup/PickupRepresentation.cc
===================================================================
--- code/trunk/src/modules/pickup/PickupRepresentation.cc	(revision 8078)
+++ code/trunk/src/modules/pickup/PickupRepresentation.cc	(revision 8079)
@@ -156,5 +156,5 @@
         {
             COUT(4) << "PickupRepresentation: No spawner representation found." << std::endl;
-            if(this->spawnerTemplate_ == BLANKSTRING)
+            if(this->spawnerTemplate_ == "")
             {
                 COUT(4) << "PickupRepresentation: Spawner template is empty." << std::endl;
Index: code/trunk/src/modules/questsystem/QuestItem.cc
===================================================================
--- code/trunk/src/modules/questsystem/QuestItem.cc	(revision 8078)
+++ code/trunk/src/modules/questsystem/QuestItem.cc	(revision 8079)
@@ -87,5 +87,5 @@
     void QuestItem::setId(const std::string & id)
     {
-        if(id.compare(BLANKSTRING) == 0) // Checks whether the id is a valid id.
+        if(id == "") // Checks whether the id is a valid id.
         {
             COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
Index: code/trunk/src/modules/questsystem/QuestManager.cc
===================================================================
--- code/trunk/src/modules/questsystem/QuestManager.cc	(revision 8078)
+++ code/trunk/src/modules/questsystem/QuestManager.cc	(revision 8079)
@@ -91,5 +91,5 @@
     /**
     @brief
-        Registers a Quest with the QuestManager to make it globally accessable.
+        Registers a Quest with the QuestManager to make it globally accessible.
         Uses it's id to make sure to be able to be identify and retrieve it later.
     @param quest
@@ -129,5 +129,5 @@
     /**
     @brief
-        Registers a QuestHint with the QuestManager to make it globally accessable.
+        Registers a QuestHint with the QuestManager to make it globally accessible.
         Uses it's id to make sure to be able to be identify and retrieve it later.
     @param hint
@@ -178,5 +178,5 @@
     Quest* QuestManager::findQuest(const std::string & questId)
     {
-        if(questId.compare(BLANKSTRING) == 1) // Check vor validity of the given id.
+        if(questId == "") // Check for validity of the given id.
             ThrowException(Argument, "Invalid questId.");
 
@@ -207,5 +207,5 @@
     QuestHint* QuestManager::findHint(const std::string & hintId)
     {
-        if(hintId.compare(BLANKSTRING) == 1) // Check vor validity of the given id.
+        if(hintId == "") // Check for validity of the given id.
             ThrowException(Argument, "Invalid hintId.");
 
Index: code/trunk/src/modules/questsystem/effects/AddQuestHint.cc
===================================================================
--- code/trunk/src/modules/questsystem/effects/AddQuestHint.cc	(revision 8078)
+++ code/trunk/src/modules/questsystem/effects/AddQuestHint.cc	(revision 8079)
@@ -86,5 +86,5 @@
     bool AddQuestHint::setHintId(const std::string & id)
     {
-        if(id.compare(BLANKSTRING) == 0)
+        if(id == "")
         {
             COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
Index: code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc
===================================================================
--- code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc	(revision 8078)
+++ code/trunk/src/modules/questsystem/effects/ChangeQuestStatus.cc	(revision 8079)
@@ -81,5 +81,5 @@
     bool ChangeQuestStatus::setQuestId(const std::string & id)
     {
-        if(id.compare(BLANKSTRING) == 0)
+        if(id == "")
         {
             COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
Index: code/trunk/src/orxonox/CameraManager.cc
===================================================================
--- code/trunk/src/orxonox/CameraManager.cc	(revision 8078)
+++ code/trunk/src/orxonox/CameraManager.cc	(revision 8079)
@@ -29,17 +29,16 @@
 #include "CameraManager.h"
 
+#include <cassert>
+
 #include <OgreSceneManager.h>
 #include <OgreViewport.h>
 #include <OgreCompositorManager.h>
 
-#include "util/StringUtils.h"
 #include "util/ScopedSingletonManager.h"
 #include "core/GameMode.h"
 #include "core/GraphicsManager.h"
-#include "core/GUIManager.h"
 #include "core/ObjectList.h"
 #include "tools/Shader.h"
 #include "graphics/Camera.h"
-#include "Scene.h"
 
 namespace orxonox
@@ -48,5 +47,4 @@
 
     CameraManager::CameraManager()
-        : viewport_(GraphicsManager::getInstance().getViewport())
     {
         assert(GameMode::showsGraphics());
@@ -55,5 +53,4 @@
     CameraManager::~CameraManager()
     {
-        GUIManager::getInstance().setCamera(0);
     }
 
@@ -95,4 +92,6 @@
             if (!this->cameraList_.empty())
                 this->cameraList_.front()->setFocus();
+            else
+                this->useCamera(NULL);
         }
         else
@@ -102,26 +101,5 @@
     void CameraManager::useCamera(Ogre::Camera* camera)
     {
-        // This workaround is needed to avoid weird behaviour with active compositors while
-        // switching the camera (like freezing the image)
-        //
-        // Last known Ogre version needing this workaround:
-        // 1.4.8
-        // 1.7.2
-
-        // deactivate all compositors
-        {
-            Ogre::ResourceManager::ResourceMapIterator iterator = Ogre::CompositorManager::getSingleton().getResourceIterator();
-            while (iterator.hasMoreElements())
-                Ogre::CompositorManager::getSingleton().setCompositorEnabled(this->viewport_, iterator.getNext()->getName(), false);
-        }
-
-        this->viewport_->setCamera(camera);
-        GUIManager::getInstance().setCamera(camera);
-
-        // reactivate all visible compositors
-        {
-            for (ObjectList<Shader>::iterator it = ObjectList<Shader>::begin(); it != ObjectList<Shader>::end(); ++it)
-                it->updateVisibility();
-        }
+        GraphicsManager::getInstance().setCamera(camera);
     }
 }
Index: code/trunk/src/orxonox/CameraManager.h
===================================================================
--- code/trunk/src/orxonox/CameraManager.h	(revision 8078)
+++ code/trunk/src/orxonox/CameraManager.h	(revision 8079)
@@ -38,10 +38,8 @@
 #include "OrxonoxPrereqs.h"
 
-#include <cassert>
 #include <list>
 #include "util/OgreForwardRefs.h"
 #include "util/Singleton.h"
 #include "core/OrxonoxClass.h"
-#include "core/SmartPtr.h"
 
 namespace orxonox
@@ -65,5 +63,4 @@
 
             std::list<Camera*>    cameraList_;
-            Ogre::Viewport*       viewport_;
 
             static CameraManager* singletonPtr_s;
Index: code/trunk/src/orxonox/ChatInputHandler.cc
===================================================================
--- code/trunk/src/orxonox/ChatInputHandler.cc	(revision 8078)
+++ code/trunk/src/orxonox/ChatInputHandler.cc	(revision 8079)
@@ -28,15 +28,24 @@
 
 #include "ChatInputHandler.h"
+
+#include <cassert>
+#include <string>
+#include <CEGUIWindow.h>
+#include <CEGUIWindowManager.h>
+#include <elements/CEGUIListbox.h>
+#include <elements/CEGUIListboxItem.h>
+#include <elements/CEGUIListboxTextItem.h>
+
 #include "util/ScopedSingletonManager.h"
 #include "core/CoreIncludes.h"
 #include "core/GUIManager.h"
-#include "core/CorePrereqs.h"
 #include "core/command/ConsoleCommand.h"
-#include <CEGUIWindow.h>
-#include <elements/CEGUIListbox.h>
-#include <elements/CEGUIListboxItem.h>
-#include <elements/CEGUIListboxTextItem.h>
-#include <CEGUIWindowManager.h>
-#include <string>
+#include "core/input/InputBuffer.h"
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+#include "network/Host.h"
+
+#include "PlayerManager.h"
+#include "infos/PlayerInfo.h"
 
 namespace orxonox
@@ -72,4 +81,11 @@
     this->inputState = InputManager::getInstance().createInputState( "chatinput", false, false, InputStatePriority::Dynamic );
     this->inputState->setKeyHandler(this->inpbuf);
+  }
+
+  ChatInputHandler::~ChatInputHandler()
+  {
+    /* Clean up */
+    InputManager::getInstance().destroyState("chatinput");
+    delete this->inpbuf;
   }
 
@@ -125,6 +141,5 @@
     // reds
     for( i = 0; i < NumberOfColors/3; ++i )
-    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
-      assert( this->text_colors[ i ] );
+    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
       green += 0.2f, blue += 0.2f;
     }
@@ -133,6 +148,5 @@
     red = 0.5, green = 1, blue = 0.5;
     for( ; i < NumberOfColors*2/3; ++i )
-    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
-      assert( this->text_colors[ i ] );
+    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
       red += 0.2f, blue += 0.2f;
     }
@@ -141,6 +155,5 @@
     red = 0.5, green = 0.5, blue = 1;
     for( ; i < NumberOfColors; ++i )
-    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
-      assert( this->text_colors[ i ] );
+    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
       red += 0.2f, green += 0.2f;
     }
@@ -196,5 +209,5 @@
 
     /* set the color according to the hash */
-    tocolor->setTextColours( *(this->text_colors[ hash ]) );
+    tocolor->setTextColours( this->text_colors[ hash ] );
   }
 
Index: code/trunk/src/orxonox/ChatInputHandler.h
===================================================================
--- code/trunk/src/orxonox/ChatInputHandler.h	(revision 8078)
+++ code/trunk/src/orxonox/ChatInputHandler.h	(revision 8079)
@@ -30,27 +30,12 @@
 #define _ChatInputHandler_H__
 
-/* std includes */
-#include <deque>
+#include <OrxonoxPrereqs.h>
+
 #include <string>
-#include <fstream>
-#include <iostream>
-#include <cassert>
 #include <CEGUIForwardRefs.h>
+#include <CEGUIcolour.h>
 
-/* project includes */
-#include <OrxonoxPrereqs.h>
-#include <core/BaseObject.h>
-#include <core/PathConfig.h>
-
-#include "core/input/InputBuffer.h"
-#include "core/input/InputManager.h"
-#include "core/input/InputState.h"
-
-#include <network/ChatListener.h>
-#include <PlayerManager.h>
-#include <infos/PlayerInfo.h>
-
-#include "../libraries/network/Host.h"
-#include <util/Singleton.h>
+#include "util/Singleton.h"
+#include "network/ChatListener.h"
 
 namespace orxonox // tolua_export
@@ -70,5 +55,5 @@
       /* colors for nickname coloring */
       static const int NumberOfColors = 10;
-      CEGUI::colour *text_colors[ NumberOfColors ];
+      CEGUI::colour text_colors[ NumberOfColors ];
 
       /** input state */
@@ -110,4 +95,5 @@
       /** constructor */
       ChatInputHandler();
+      ~ChatInputHandler();
       friend class Singleton<ChatInputHandler>;
 
Index: code/trunk/src/orxonox/LevelInfo.h
===================================================================
--- code/trunk/src/orxonox/LevelInfo.h	(revision 8078)
+++ code/trunk/src/orxonox/LevelInfo.h	(revision 8079)
@@ -109,5 +109,5 @@
             @return Returns the XML-filename (including *.oxw extension) of the Level.
             */
-            inline const std::string& getXMLFilename(void) { return this->xmlfilename_; } // tolua_export
+            inline const std::string& getXMLFilename(void) const { return this->xmlfilename_; } // tolua_export
 
         protected:
@@ -212,5 +212,9 @@
     {
         bool operator() (const LevelInfoItem* lhs, const LevelInfoItem* rhs) const
-            { return getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) < 0; }
+            {
+                if(getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) == 0)
+                    return getLowercase(lhs->getXMLFilename()).compare(getLowercase(rhs->getXMLFilename())) < 0;
+                return getLowercase(lhs->getName()).compare(getLowercase(rhs->getName())) < 0;
+            }
     };
     
Index: code/trunk/src/orxonox/LevelManager.cc
===================================================================
--- code/trunk/src/orxonox/LevelManager.cc	(revision 8078)
+++ code/trunk/src/orxonox/LevelManager.cc	(revision 8079)
@@ -75,4 +75,8 @@
     LevelManager::~LevelManager()
     {
+        // Delete all the LevelInfoItem objects because the LevelManager created them
+        std::set<LevelInfoItem*, LevelInfoCompare>::iterator it = availableLevels_.begin();
+        for (; it != availableLevels_.end(); ++it)
+            delete *it;
     }
 
@@ -237,34 +241,54 @@
     void LevelManager::compileAvailableLevelList()
     {
+        // Get all files matching the level criteria
         Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
-        // Iterate over all *.oxw level files.
+
+        // We only want to load as little as possible
+        ClassTreeMask mask;
+        mask.exclude(Class(BaseObject));
+        mask.include(Class(LevelInfo));
+
+        // Iterate over all the found *.oxw files
         COUT(3) << "Loading LevelInfos..." << std::endl;
+        std::set<std::string> names;
         for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
         {
-            //TODO: Replace with tag?
+            // TODO: Replace with tag?
             if (it->find("old/") != 0)
             {
-                size_t pos = it->find(".oxw");
+                LevelInfoItem* info = NULL;
 
                 // Load the LevelInfo object from the level file.
-                bool infoExists = false;
                 XMLFile file = XMLFile(*it);
-                ClassTreeMask mask = ClassTreeMask();
-                mask.exclude(ClassIdentifier<BaseObject>::getIdentifier());
-                mask.include(ClassIdentifier<LevelInfo>::getIdentifier());
-                Loader::load(&file, mask, false);
-                // Iterate over all LevelInfos.
+                Loader::load(&file, mask, false, true);
+
+                // Find the LevelInfo object we've just loaded (if there was one)
                 for(ObjectList<LevelInfo>::iterator item = ObjectList<LevelInfo>::begin(); item != ObjectList<LevelInfo>::end(); ++item)
+                    if(item->getXMLFilename() == *it)
+                        info = item->copy();
+
+                // We don't need the loaded stuff anymore
+                Loader::unload(&file);
+
+                if(info == NULL) 
                 {
-                    LevelInfoItem* info = item->copy();
-                    if(info->getXMLFilename() == *it) // If the LevelInfo for this level exists we insert it into the list of available levels.
-                    {
-                        this->availableLevels_.insert(info);
-                        infoExists = true;
-                    }
+                    // Create a default LevelInfoItem object that merely contains the name
+                    std::string filenameWOExtension = it->substr(0, it->find(".oxw"));
+                    info = new LevelInfoItem(filenameWOExtension, *it);
                 }
-                Loader::unload(&file, mask);
-                if(!infoExists) // If the LevelInfo for this level doesn't exist, we create a new one and insert it into the list of available levels.
-                    this->availableLevels_.insert(new LevelInfoItem(it->substr(0, pos), *it));
+
+                // Warn about levels with the same name.
+                if(!names.insert(info->getName()).second)
+                    COUT(2) << "Warning: Multiple levels (" << info->getXMLFilename() << ") with name '" << info->getName() << "' found!" << std::endl;
+
+                // Warn about multiple items so that it gets fixed quickly
+                if(availableLevels_.find(info) != availableLevels_.end())
+                {
+                    COUT(2) << "Warning: Multiple levels (" << info->getXMLFilename() << ") with same name '" << info->getName() << "' and filename found! Exluding..." << std::endl;
+                    // Delete LevelInfoItem to avoid a dangling pointer
+                    delete info;
+                }
+                else
+                    this->availableLevels_.insert(info);
             }
         }
Index: code/trunk/src/orxonox/LevelManager.h
===================================================================
--- code/trunk/src/orxonox/LevelManager.h	(revision 8078)
+++ code/trunk/src/orxonox/LevelManager.h	(revision 8079)
@@ -112,5 +112,5 @@
             // Helpers to allow fast access to the availableLevels list.
             unsigned int nextIndex_; //! The next expected index to be accessed.
-            std::set<LevelInfoItem*, LevelInfoCompare>::iterator nextLevel_; //! The nex expected Level to be accessed.
+            std::set<LevelInfoItem*, LevelInfoCompare>::iterator nextLevel_; //! The next expected Level to be accessed.
 
             // config values
Index: code/trunk/src/orxonox/controllers/HumanController.cc
===================================================================
--- code/trunk/src/orxonox/controllers/HumanController.cc	(revision 8078)
+++ code/trunk/src/orxonox/controllers/HumanController.cc	(revision 8079)
@@ -61,4 +61,5 @@
     SetConsoleCommand("HumanController", "cycleNavigationFocus",   &HumanController::cycleNavigationFocus).addShortcut();
     SetConsoleCommand("HumanController", "releaseNavigationFocus", &HumanController::releaseNavigationFocus).addShortcut();
+    SetConsoleCommand("HumanController", "myposition",             &HumanController::myposition    ).addShortcut();
 
     CreateUnloadableFactory(HumanController);
@@ -200,5 +201,18 @@
     void HumanController::toggleGodMode()
     {
-        HumanController::getLocalControllerSingleton()->setGodMode( !HumanController::getLocalControllerSingleton()->getGodMode() );
+        if (HumanController::localController_s)
+            HumanController::localController_s->setGodMode(!HumanController::localController_s->getGodMode());
+    }
+
+    void HumanController::myposition()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+        {
+            const Vector3& position = HumanController::localController_s->controllableEntity_->getPosition();
+            const Quaternion& orientation = HumanController::localController_s->controllableEntity_->getOrientation();
+
+            COUT(0) << "position=\"" << position.x << ", " << position.y << ", " << position.z << "\" ";
+            COUT(0) << "orientation=\"" << orientation.w << ", " << orientation.x << ", " << orientation.y << ", " << orientation.z << "\"" << std::endl;
+        }
     }
 
Index: code/trunk/src/orxonox/controllers/HumanController.h
===================================================================
--- code/trunk/src/orxonox/controllers/HumanController.h	(revision 8078)
+++ code/trunk/src/orxonox/controllers/HumanController.h	(revision 8079)
@@ -73,4 +73,5 @@
             static void suicide();
             static void toggleGodMode();
+            static void myposition();
 
             static void addBots(unsigned int amount);
Index: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 8078)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 8079)
@@ -46,4 +46,5 @@
 #include "LevelManager.h"
 #include "PlayerManager.h"
+#include "GSRoot.h"
 
 namespace orxonox
@@ -55,5 +56,5 @@
 
     SetConsoleCommand(__CC_startMainMenu_name, &GSLevel::startMainMenu).deactivate();
-    SetConsoleCommand(__CC_changeGame_name, &GSLevel::changeGame).defaultValues(BLANKSTRING).deactivate();
+    SetConsoleCommand(__CC_changeGame_name, &GSLevel::changeGame).defaultValues("").deactivate();
 
     GSLevel::GSLevel(const GameStateInfo& info)
@@ -156,7 +157,9 @@
         COUT(0) << "Loading level..." << std::endl;
         startFile_ = new XMLFile(LevelManager::getInstance().getDefaultLevel());
-        Loader::open(startFile_);
+        bool loaded = Loader::open(startFile_);
 
         Core::getInstance().updateLastLevelTimestamp();
+        if(!loaded)
+            GSRoot::delayedStartMainMenu();
     }
 
@@ -202,5 +205,5 @@
     /*static*/ void GSLevel::changeGame(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
Index: code/trunk/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.cc	(revision 8078)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.cc	(revision 8079)
@@ -57,8 +57,8 @@
     static const std::string __CC_setMainMenuSoundPath_name = "setMMSoundPath";
 
-    SetConsoleCommand(__CC_startStandalone_name,      &GSMainMenu::startStandalone).defaultValues(BLANKSTRING).deactivate();
-    SetConsoleCommand(__CC_startServer_name,          &GSMainMenu::startServer    ).defaultValues(BLANKSTRING).deactivate();
-    SetConsoleCommand(__CC_startClient_name,          &GSMainMenu::startClient    ).defaultValues(BLANKSTRING).deactivate();
-    SetConsoleCommand(__CC_startDedicated_name,       &GSMainMenu::startDedicated ).defaultValues(BLANKSTRING).deactivate();
+    SetConsoleCommand(__CC_startStandalone_name,      &GSMainMenu::startStandalone).defaultValues("").deactivate();
+    SetConsoleCommand(__CC_startServer_name,          &GSMainMenu::startServer    ).defaultValues("").deactivate();
+    SetConsoleCommand(__CC_startClient_name,          &GSMainMenu::startClient    ).defaultValues("").deactivate();
+    SetConsoleCommand(__CC_startDedicated_name,       &GSMainMenu::startDedicated ).defaultValues("").deactivate();
     SetConsoleCommand(__CC_setMainMenuSoundPath_name, &GSMainMenu::setMainMenuSoundPath).hide();
 
@@ -96,8 +96,7 @@
     {
         // show main menu
+        GraphicsManager::getInstance().setCamera(this->camera_);
         GUIManager::getInstance().showGUI("MainMenu", true);
-        GUIManager::getInstance().setCamera(this->camera_);
         GUIManager::getInstance().setBackgroundImage("MainMenuBackground", "Background");
-        GraphicsManager::getInstance().setCamera(this->camera_);
 
         InputManager::getInstance().enterState("MainMenuHackery");
@@ -129,8 +128,7 @@
         InputManager::getInstance().leaveState("MainMenuHackery");
 
-        GUIManager::getInstance().setCamera(0);
+        GraphicsManager::getInstance().setCamera(0);
         GUIManager::getInstance().setBackgroundImage("");
         GUIManager::hideGUI("MainMenu");
-        GraphicsManager::getInstance().setCamera(0);
 
         ModifyConsoleCommand(__CC_startStandalone_name).deactivate();
@@ -178,5 +176,5 @@
     void GSMainMenu::startStandalone(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
@@ -194,5 +192,5 @@
     void GSMainMenu::startServer(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
@@ -210,5 +208,5 @@
     void GSMainMenu::startClient(const std::string& destination)
     {
-        if(destination != BLANKSTRING)
+        if(destination != "")
             Client::getInstance()->setDestination(destination, NETWORK_PORT);
 
@@ -226,5 +224,5 @@
     void GSMainMenu::startDedicated(const std::string& level)
     {
-        if(level != BLANKSTRING)
+        if(level != "")
             LevelManager::getInstance().setDefaultLevel(level);
 
Index: code/trunk/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.h	(revision 8078)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.h	(revision 8079)
@@ -53,8 +53,8 @@
         void setMainMenuSoundPath(const std::string& path);
 
-        static void startStandalone(const std::string& level = BLANKSTRING); //!< Start a level in standalone mode.
-        static void startServer(const std::string& level = BLANKSTRING); //!< Start a level in server mode.
-        static void startClient(const std::string& destination = BLANKSTRING); //!< Connect to a game as client.
-        static void startDedicated(const std::string& level = BLANKSTRING); //!< Start a level in dedicated mode.
+        static void startStandalone(const std::string& level = ""); //!< Start a level in standalone mode.
+        static void startServer(const std::string& level = ""); //!< Start a level in server mode.
+        static void startClient(const std::string& destination = ""); //!< Connect to a game as client.
+        static void startDedicated(const std::string& level = ""); //!< Start a level in dedicated mode.
         static void startIOConsole();
 
Index: code/trunk/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 8078)
+++ code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 8079)
@@ -38,4 +38,6 @@
 #include "tools/interfaces/Tickable.h"
 
+#include "GSLevel.h"
+
 namespace orxonox
 {
@@ -43,8 +45,12 @@
 
     static const std::string __CC_setTimeFactor_name = "setTimeFactor";
+    static const std::string __CC_setPause_name = "setPause";
     static const std::string __CC_pause_name = "pause";
+
+    /*static*/ bool GSRoot::startMainMenu_s = false;
 
     SetConsoleCommand("printObjects", &GSRoot::printObjects).hide();
     SetConsoleCommand(__CC_setTimeFactor_name, &GSRoot::setTimeFactor).accessLevel(AccessLevel::Master).defaultValues(1.0);
+    SetConsoleCommand(__CC_setPause_name,      &GSRoot::setPause     ).accessLevel(AccessLevel::Master).hide();
     SetConsoleCommand(__CC_pause_name,         &GSRoot::pause        ).accessLevel(AccessLevel::Master);
 
@@ -83,4 +89,5 @@
 
         ModifyConsoleCommand(__CC_setTimeFactor_name).setObject(this);
+        ModifyConsoleCommand(__CC_setPause_name).setObject(this);
         ModifyConsoleCommand(__CC_pause_name).setObject(this);
     }
@@ -89,4 +96,5 @@
     {
         ModifyConsoleCommand(__CC_setTimeFactor_name).setObject(0);
+        ModifyConsoleCommand(__CC_setPause_name).setObject(0);
         ModifyConsoleCommand(__CC_pause_name).setObject(0);
     }
@@ -94,4 +102,10 @@
     void GSRoot::update(const Clock& time)
     {
+        if(startMainMenu_s)
+        {
+            delayedStartMainMenu();
+            startMainMenu_s = false;
+        }
+
         for (ObjectList<Timer>::iterator it = ObjectList<Timer>::begin(); it; )
         {
@@ -157,4 +171,13 @@
     }
 
+    void GSRoot::setPause(bool pause)
+    {
+        if (GameMode::isMaster())
+        {
+            if (pause != this->bPaused_)
+                this->pause();
+        }
+    }
+
     void GSRoot::changedTimeFactor(float factor_new, float factor_old)
     {
@@ -162,3 +185,12 @@
             callStaticNetworkFunction(&TimeFactorListener::setTimeFactor, CLIENTID_UNKNOWN, factor_new);
     }
+
+    /*static*/ void GSRoot::delayedStartMainMenu(void)
+    {
+        if(!startMainMenu_s)
+            startMainMenu_s = true;
+        else
+            GSLevel::startMainMenu();
+    }
+
 }
Index: code/trunk/src/orxonox/gamestates/GSRoot.h
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.h	(revision 8078)
+++ code/trunk/src/orxonox/gamestates/GSRoot.h	(revision 8079)
@@ -51,5 +51,8 @@
         // when taking the function address.
         void setTimeFactor(float factor);
+        void setPause(bool pause);
         void pause();
+
+        static void delayedStartMainMenu(void);
 
     protected:
@@ -59,4 +62,5 @@
         bool                  bPaused_;
         float                 timeFactorPauseBackup_;
+        static bool           startMainMenu_s;
     };
 }
Index: code/trunk/src/orxonox/gametypes/Gametype.cc
===================================================================
--- code/trunk/src/orxonox/gametypes/Gametype.cc	(revision 8078)
+++ code/trunk/src/orxonox/gametypes/Gametype.cc	(revision 8079)
@@ -30,4 +30,5 @@
 
 #include "util/Math.h"
+#include "core/Core.h"
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
@@ -386,5 +387,9 @@
                     if (allplayersready && hashumanplayers)
                     {
-                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
+                        // If in developer's mode, there is no start countdown.
+                        if(Core::getInstance().inDevMode())
+                            this->gtinfo_->startCountdown_ = 0;
+                        else
+                            this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
                         this->gtinfo_->bStartCountdownRunning_ = true;
                     }
Index: code/trunk/src/orxonox/graphics/Camera.cc
===================================================================
--- code/trunk/src/orxonox/graphics/Camera.cc	(revision 8078)
+++ code/trunk/src/orxonox/graphics/Camera.cc	(revision 8079)
@@ -69,5 +69,4 @@
         this->bHasFocus_ = false;
         this->bDrag_ = false;
-        this->nearClipDistance_ = 1;
         this->lastDtLagged_ = false;
 
@@ -75,4 +74,6 @@
 
         this->setConfigValues();
+
+        this->configvaluecallback_changedFovAndAspectRatio();
         this->configvaluecallback_changedNearClipDistance();
     }
@@ -82,6 +83,4 @@
         if (this->isInitialized())
         {
-            if (GUIManager::getInstance().getCamera() == this->camera_)
-                GUIManager::getInstance().setCamera(NULL);
             this->releaseFocus();
 
@@ -99,5 +98,27 @@
     void Camera::setConfigValues()
     {
-        SetConfigValue(nearClipDistance_, 1.0f).callback(this, &Camera::configvaluecallback_changedNearClipDistance);
+        SetConfigValue(fov_, 80.0f)
+            .description("Horizontal field of view in degrees")
+            .callback(this, &Camera::configvaluecallback_changedFovAndAspectRatio);
+        SetConfigValue(aspectRatio_, 1.0f)
+            .description("Aspect ratio of pixels (width / height)")
+            .callback(this, &Camera::configvaluecallback_changedFovAndAspectRatio);
+        SetConfigValue(nearClipDistance_, 1.0f)
+            .description("Distance from the camera where close objects will be clipped")
+            .callback(this, &Camera::configvaluecallback_changedNearClipDistance);
+    }
+
+    /**
+        @brief Update FOV and the aspect ratio of the camera after the config values or the window's size have changed.
+    */
+    void Camera::configvaluecallback_changedFovAndAspectRatio()
+    {
+        // the aspect ratio of the window (width / height) has to be multiplied with the pixels aspect ratio (this->aspectRatio_)
+        float aspectRatio = this->aspectRatio_ * this->getWindowWidth() / this->getWindowHeight();
+        this->camera_->setAspectRatio(aspectRatio);
+
+        // Since we use horizontal FOV, we have to calculate FOVy by dividing by the aspect ratio and using some tangents
+        Radian fovy(2 * atan(tan(Degree(this->fov_).valueRadians() / 2) / aspectRatio));
+        this->camera_->setFOVy(fovy);
     }
 
@@ -105,4 +126,12 @@
     {
         this->camera_->setNearClipDistance(this->nearClipDistance_);
+    }
+
+    /**
+        @brief Inherited from WindowEventListener.
+    */
+    void Camera::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        this->configvaluecallback_changedFovAndAspectRatio();
     }
 
Index: code/trunk/src/orxonox/graphics/Camera.h
===================================================================
--- code/trunk/src/orxonox/graphics/Camera.h	(revision 8078)
+++ code/trunk/src/orxonox/graphics/Camera.h	(revision 8079)
@@ -33,4 +33,5 @@
 
 #include "util/OgreForwardRefs.h"
+#include "core/WindowEventListener.h"
 #include "tools/interfaces/Tickable.h"
 #include "tools/interfaces/TimeFactorListener.h"
@@ -39,5 +40,5 @@
 namespace orxonox
 {
-    class _OrxonoxExport Camera : public StaticEntity, public Tickable, public TimeFactorListener
+    class _OrxonoxExport Camera : public StaticEntity, public Tickable, public TimeFactorListener, public WindowEventListener
     {
         friend class CameraManager;
@@ -66,5 +67,9 @@
             void removeFocus();
             void setFocus();
+
+            void configvaluecallback_changedFovAndAspectRatio();
             void configvaluecallback_changedNearClipDistance();
+
+            void windowResized(unsigned int newWidth, unsigned int newHeight);
 
             Ogre::Camera*    camera_;
@@ -74,4 +79,6 @@
             bool             bDrag_;
             bool             lastDtLagged_;
+            float            fov_;
+            float            aspectRatio_;
     };
 }
Index: code/trunk/src/orxonox/graphics/GlobalShader.cc
===================================================================
--- code/trunk/src/orxonox/graphics/GlobalShader.cc	(revision 8078)
+++ code/trunk/src/orxonox/graphics/GlobalShader.cc	(revision 8079)
@@ -61,5 +61,5 @@
         SUPER(GlobalShader, XMLPort, xmlelement, mode);
 
-        XMLPortParamExtern(GlobalShader, Shader, &this->shader_, "compositor", setCompositor, getCompositor, xmlelement, mode);
+        XMLPortParamExtern(GlobalShader, Shader, &this->shader_, "compositor", setCompositorName, getCompositorName, xmlelement, mode);
     }
 
@@ -67,5 +67,5 @@
     {
         registerVariable(this->bVisible_,                                         VariableDirection::ToClient, new NetworkCallback<GlobalShader>(this, &GlobalShader::changedVisibility));
-        registerVariable(const_cast<std::string&>(this->shader_.getCompositor()), VariableDirection::ToClient, new NetworkCallback<Shader>(&this->shader_, &Shader::changedCompositor));
+        registerVariable(const_cast<std::string&>(this->shader_.getCompositorName()), VariableDirection::ToClient, new NetworkCallback<Shader>(&this->shader_, &Shader::changedCompositorName));
     }
 
Index: code/trunk/src/orxonox/graphics/GlobalShader.h
===================================================================
--- code/trunk/src/orxonox/graphics/GlobalShader.h	(revision 8078)
+++ code/trunk/src/orxonox/graphics/GlobalShader.h	(revision 8079)
@@ -53,5 +53,4 @@
         private:
             void registerVariables();
-            void changedCompositor();
 
             Shader shader_;
Index: code/trunk/src/orxonox/graphics/Model.cc
===================================================================
--- code/trunk/src/orxonox/graphics/Model.cc	(revision 8078)
+++ code/trunk/src/orxonox/graphics/Model.cc	(revision 8079)
@@ -60,5 +60,5 @@
     void Model::setConfigValues()
     {
-        SetConfigValueExternal(bGlobalEnableLod_, "GraphicsSettings", "enableModelLoD", true)
+        SetConfigValueExternal(bGlobalEnableLod_, "GraphicsSettings", "enableMeshLoD", true)
             .description("Enable level of detail for models");
     }
Index: code/trunk/src/orxonox/items/Engine.cc
===================================================================
--- code/trunk/src/orxonox/items/Engine.cc	(revision 8078)
+++ code/trunk/src/orxonox/items/Engine.cc	(revision 8079)
@@ -102,5 +102,9 @@
     void Engine::setConfigValues()
     {
-        SetConfigValue(blurStrength_, 3.0f);
+        SetConfigValueExternal(bEnableMotionBlur_, "GraphicsSettings", "enableMotionBlur", true)
+            .description("Enable or disable the motion blur effect when moving very fast")
+            .callback(this, &Engine::changedEnableMotionBlur);
+        SetConfigValueExternal(blurStrength_, "GraphicsSettings", "blurStrength", 3.0f)
+            .description("Defines the strength of the motion blur effect");
     }
 
@@ -204,12 +208,17 @@
         this->ship_->setSteeringDirection(Vector3::ZERO);
 
-        if (!this->boostBlur_ && this->ship_->hasLocalController() && this->ship_->hasHumanController())
+        if (this->bEnableMotionBlur_ && !this->boostBlur_ && this->ship_->hasLocalController() && this->ship_->hasHumanController())
         {
             this->boostBlur_ = new Shader(this->ship_->getScene()->getSceneManager());
-            this->boostBlur_->setCompositor("Radial Blur");
+            this->boostBlur_->setCompositorName("Radial Blur");
         }
 
         if (this->boostBlur_ && this->maxSpeedFront_ != 0 && this->boostFactor_ != 1)
-            this->boostBlur_->setParameter("Ogre/Compositor/Radial_Blur", 0, 0, "sampleStrength", this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f));
+        {
+            float blur = this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f);
+
+            this->boostBlur_->setVisible(blur > 0);
+            this->boostBlur_->setParameter(0, 0, "sampleStrength", blur);
+        }
     }
 
@@ -257,3 +266,12 @@
         return this->ship_->getWorldPosition();
     }
+
+    void Engine::changedEnableMotionBlur()
+    {
+        if (!this->bEnableMotionBlur_)
+        {
+            this->boostBlur_->destroy();
+            this->boostBlur_ = 0;
+        }
+    }
 }
Index: code/trunk/src/orxonox/items/Engine.h
===================================================================
--- code/trunk/src/orxonox/items/Engine.h	(revision 8078)
+++ code/trunk/src/orxonox/items/Engine.h	(revision 8079)
@@ -127,4 +127,5 @@
             void registerVariables();
             void networkcallback_shipID();
+            void changedEnableMotionBlur();
 
             SpaceShip* ship_;
@@ -150,4 +151,5 @@
             Shader* boostBlur_;
             float blurStrength_;
+            bool bEnableMotionBlur_;
     };
 }
Index: code/trunk/src/orxonox/overlays/InGameConsole.cc
===================================================================
--- code/trunk/src/orxonox/overlays/InGameConsole.cc	(revision 8078)
+++ code/trunk/src/orxonox/overlays/InGameConsole.cc	(revision 8079)
@@ -60,6 +60,6 @@
     const float CHAR_WIDTH = 7.45f; // fix this please - determine the char-width dynamically
 
-    SetConsoleCommand("InGameConsole", "openConsole", &InGameConsole::openConsole).addShortcut();
-    SetConsoleCommand("InGameConsole", "closeConsole", &InGameConsole::closeConsole).addShortcut();
+    SetConsoleCommand("InGameConsole", "openConsole", &InGameConsole::openConsole);
+    SetConsoleCommand("InGameConsole", "closeConsole", &InGameConsole::closeConsole);
 
     ManageScopedSingleton(InGameConsole, ScopeID::Graphics, false);
Index: code/trunk/src/orxonox/sound/AmbientSound.cc
===================================================================
--- code/trunk/src/orxonox/sound/AmbientSound.cc	(revision 8078)
+++ code/trunk/src/orxonox/sound/AmbientSound.cc	(revision 8079)
@@ -29,4 +29,5 @@
 #include "AmbientSound.h"
 
+#include "core/CoreIncludes.h"
 #include "core/GameMode.h"
 #include "core/Resource.h"
@@ -38,4 +39,6 @@
         : bPlayOnLoad_(false)
     {
+        RegisterObject(AmbientSound);
+
         // Ambient sounds always fade in
         this->setVolume(0);
