Index: code/trunk/src/CMakeLists.txt
===================================================================
--- code/trunk/src/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/CMakeLists.txt	(revision 5695)
@@ -17,72 +17,36 @@
  #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  #
+ #
+ #  Author:
+ #    Reto Grieder
+ #  Description:
+ #    Configures the compilers and sets build options.
+ #
 
-################ Various Options ################
-
-# various macro includes
+# Required macros and functions
 INCLUDE(FlagUtilities)
 INCLUDE(TargetUtilities)
 
+# Configure the two headers and set some options
+INCLUDE(OrxonoxConfig.cmake)
+
+################ Library Defines ################
+
+# Disable Boost auto linking completely
+ADD_COMPILER_FLAGS("-DBOOST_ALL_NO_LIB")
+
+# If no defines are specified, these libs get linked statically
+ADD_COMPILER_FLAGS("-DBOOST_ALL_DYN_LINK" WIN32 LINK_BOOST_DYNAMIC)
+ADD_COMPILER_FLAGS("-DENET_DLL"           WIN32 LINK_ENET_DYNAMIC)
+ADD_COMPILER_FLAGS("-DLUA_BUILD_AS_DLL"   WIN32 LINK_LUA_DYNAMIC)
+ADD_COMPILER_FLAGS("-DOIS_DYNAMIC_LIB")
+ADD_COMPILER_FLAGS("-DZLIB_DLL"           WIN32 LINK_ZLIB_DYNAMIC)
+# If no defines are specified, these libs get linked dynamically
+ADD_COMPILER_FLAGS("-DCEGUI_STATIC"       WIN32 NOT LINK_CEGUI_DYNAMIC)
+ADD_COMPILER_FLAGS("-DOGRE_STATIC_LIB"    WIN32 NOT LINK_OGRE_DYNAMIC)
+ADD_COMPILER_FLAGS("-DSTATIC_BUILD"       WIN32 NOT LINK_TCL_DYNAMIC)
+
 # Use TinyXML++
 ADD_COMPILER_FLAGS("-DTIXML_USE_TICPP")
-# OIS dynamic linking requires macro definition, at least for Windows
-ADD_COMPILER_FLAGS("-DOIS_DYNAMIC_LIB")
-
-################ OrxonoxConfig.h ################
-
-# Check endianness
-INCLUDE(TestBigEndian)
-TEST_BIG_ENDIAN(ORXONOX_BIG_ENDIAN)
-IF(NOT ORXONOX_BIG_ENDIAN)
-  SET(ORXONOX_LITTLE_ENDIAN TRUE)
-ENDIF()
-
-# 32/64 bit system check
-IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
-  SET(ORXONOX_ARCH_64 TRUE)
-ELSE()
-  SET(ORXONOX_ARCH_32 TRUE)
-ENDIF()
-
-# Platforms
-SET(ORXONOX_PLATFORM_WINDOWS ${WIN32})
-SET(ORXONOX_PLATFORM_APPLE ${APPLE})
-SET(ORXONOX_PLATFORM_UNIX ${UNIX})
-IF(UNIX AND NOT APPLE)
-  SET(ORXONOX_PLATFORM_LINUX TRUE)
-ENDIF()
-
-# Check __forceinline
-IF(MSVC)
-  INCLUDE(CheckCXXSourceCompiles)
-  SET(_source "int main() { return 0; } __forceinline void test() { return; }")
-  CHECK_CXX_SOURCE_COMPILES("${_source}" HAVE_FORCEINLINE)
-ENDIF(MSVC)
-
-# Check ciso646 include (literal operators)
-INCLUDE(CheckIncludeFileCXX)
-CHECK_INCLUDE_FILE_CXX(iso646.h HAVE_ISO646_H)
-
-# XCode and Visual Studio support multiple configurations. In order to tell the
-# which one we have to define the macros separately for each configuration
-ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=Debug"          Debug)
-ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=Release"        Release)
-ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=RelWithDebInfo" RelWithDebInfo)
-ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=MinSizeRel"     MinSizeRel)
-
-SET(GENERATED_FILE_COMMENT
-   "DO NOT EDIT THIS FILE! <br>
-    It has been automatically generated by CMake from OrxonoxConfig.h.in")
-# Copy and configure OrxonoxConfig which gets included in every file
-CONFIGURE_FILE(OrxonoxConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h)
-# This file only gets included by very few classes to avoid a large recompilation
-CONFIGURE_FILE(SpecialConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h)
-
-SET(ORXONOX_CONFIG_FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/OrxonoxConfig.h.in
-  ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/SpecialConfig.h.in
-)
 
 ############## Include Directories ##############
Index: code/trunk/src/OrxonoxConfig.cmake
===================================================================
--- code/trunk/src/OrxonoxConfig.cmake	(revision 5695)
+++ code/trunk/src/OrxonoxConfig.cmake	(revision 5695)
@@ -0,0 +1,103 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #  Description:
+ #    Configures the header files OrxonoxConfig.h and SpecialConfig.h
+ #    and sets some other options. All the build related options should be
+ #    found and set here if possible.
+ #
+
+#################### Options ####################
+
+# Default linking is SHARED
+SET(ORXONOX_DEFAULT_LINK SHARED)
+
+# Use, i.e. don't skip the full RPATH for the build tree
+SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
+
+# Global switch to disable Precompiled Header Files
+IF(PCH_COMPILER_SUPPORT)
+  OPTION(PCH_ENABLE "Global PCH switch" TRUE)
+ENDIF()
+
+# Use WinMain() or main()?
+IF(WIN32)
+  OPTION(ORXONOX_USE_WINMAIN "Use WinMain (doesn't show console) or main" FALSE)
+ENDIF()
+
+################ Platform Config ################
+
+# Check endianness
+INCLUDE(TestBigEndian)
+TEST_BIG_ENDIAN(ORXONOX_BIG_ENDIAN)
+IF(NOT ORXONOX_BIG_ENDIAN)
+  SET(ORXONOX_LITTLE_ENDIAN TRUE)
+ENDIF()
+
+# 32/64 bit system check
+IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+  SET(ORXONOX_ARCH_64 TRUE)
+ELSE()
+  SET(ORXONOX_ARCH_32 TRUE)
+ENDIF()
+
+# Platforms
+SET(ORXONOX_PLATFORM_WINDOWS ${WIN32})
+SET(ORXONOX_PLATFORM_APPLE ${APPLE})
+SET(ORXONOX_PLATFORM_UNIX ${UNIX})
+IF(UNIX AND NOT APPLE)
+  SET(ORXONOX_PLATFORM_LINUX TRUE)
+ENDIF()
+
+# Check __forceinline
+IF(MSVC)
+  INCLUDE(CheckCXXSourceCompiles)
+  SET(_source "int main() { return 0; } __forceinline void test() { return; }")
+  CHECK_CXX_SOURCE_COMPILES("${_source}" HAVE_FORCEINLINE)
+ENDIF(MSVC)
+
+# Check iso646.h include (literal operators)
+INCLUDE(CheckIncludeFileCXX)
+CHECK_INCLUDE_FILE_CXX(iso646.h HAVE_ISO646_H)
+
+# XCode and Visual Studio support multiple configurations. In order to tell
+# about the active one we have to define the macro for each configuration
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=Debug"          Debug)
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=Release"        Release)
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=RelWithDebInfo" RelWithDebInfo)
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=MinSizeRel"     MinSizeRel)
+
+############## Configured Headers ###############
+
+SET(GENERATED_FILE_COMMENT
+   "DO NOT EDIT THIS FILE! <br>
+    It has been automatically generated by CMake from OrxonoxConfig.h.in")
+# Copy and configure OrxonoxConfig which gets included in every file
+CONFIGURE_FILE(OrxonoxConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h)
+# This file only gets included by very few classes to avoid a large recompilation
+CONFIGURE_FILE(SpecialConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h)
+
+SET(ORXONOX_CONFIG_FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/OrxonoxConfig.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/SpecialConfig.h.in
+)
Index: code/trunk/src/OrxonoxConfig.h.in
===================================================================
--- code/trunk/src/OrxonoxConfig.h.in	(revision 5693)
+++ code/trunk/src/OrxonoxConfig.h.in	(revision 5695)
@@ -198,3 +198,23 @@
 }
 
+// Import general purpose smart pointers
+namespace boost
+{
+    template<class T> class scoped_ptr;
+    template<class T> class shared_ptr;
+    template<class T> class weak_ptr;
+    template<class T> class intrusive_ptr;
+    template<class T> class shared_array;
+    template<class T> class scoped_array;
+}
+namespace orxonox
+{
+    using boost::scoped_ptr;
+    using boost::shared_ptr;
+    using boost::weak_ptr;
+    using boost::intrusive_ptr;
+    using boost::shared_array;
+    using boost::scoped_array;
+}
+
 #endif /* _OrxonoxConfig_H__ */
Index: code/trunk/src/SpecialConfig.h.in
===================================================================
--- code/trunk/src/SpecialConfig.h.in	(revision 5693)
+++ code/trunk/src/SpecialConfig.h.in	(revision 5695)
@@ -70,49 +70,59 @@
 
 // Handle default ConfigValues
-namespace orxonox
+namespace orxonox { namespace specialConfig
 {
+    // DEFAULT RELATIVE PATHS (might not be used at all)
+    const char defaultRuntimePath[] = "@DEFAULT_RUNTIME_PATH@";
+    const char defaultLibraryPath[] = "@DEFAULT_LIBRARY_PATH@";
+    const char defaultArchivePath[] = "@DEFAULT_ARCHIVE_PATH@";
+    const char defaultModulePath[]  = "@DEFAULT_MODULE_PATH@";
+    const char defaultDocPath[]     = "@DEFAULT_DOC_PATH@";
+    const char defaultDataPath[]    = "@DEFAULT_DATA_PATH@";
+    const char defaultConfigPath[]  = "@DEFAULT_CONFIG_PATH@";
+    const char defaultLogPath[]     = "@DEFAULT_LOG_PATH@";
+
+#ifndef INSTALL_COPYABLE
     // INSTALLATION PATHS
-    const char ORXONOX_RUNTIME_INSTALL_PATH[] = "@ORXONOX_RUNTIME_INSTALL_PATH@";
-    const char ORXONOX_MODULE_INSTALL_PATH[]  = "@ORXONOX_MODULE_INSTALL_PATH@";
-    const char ORXONOX_MEDIA_INSTALL_PATH[]   = "@ORXONOX_MEDIA_INSTALL_PATH@";
-    /* Config and Log path might be relative because they could be user and therefore runtime dependent */
-    const char ORXONOX_CONFIG_INSTALL_PATH[]  = "@ORXONOX_CONFIG_INSTALL_PATH@";
-    const char ORXONOX_LOG_INSTALL_PATH[]     = "@ORXONOX_LOG_INSTALL_PATH@";
+    const char dataInstallDirectory[]       = "@DATA_INSTALL_DIRECTORY@";
+    const char moduleInstallDirectory[]     = "@MODULE_INSTALL_DIRECTORY@";
+#endif
 
     // DEVELOPMENT RUN PATHS
-    const char ORXONOX_MEDIA_DEV_PATH[]       = "@CMAKE_MEDIA_OUTPUT_DIRECTORY@";
+    const char dataDevDirectory[]           = "@DATA_DIRECTORY@";
+    const char externalDataDevDirectory[]   = "@EXTERNAL_DATA_DIRECTORY@";
 #ifdef CMAKE_CONFIGURATION_TYPES
-    const char ORXONOX_MODULE_DEV_PATH[]      = "@CMAKE_MODULE_OUTPUT_DIRECTORY@/" BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
-    const char ORXONOX_CONFIG_DEV_PATH[]      = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@/" BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
-    const char ORXONOX_LOG_DEV_PATH[]         = "@CMAKE_LOG_OUTPUT_DIRECTORY@/"    BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
+    const char moduleDevDirectory[]         = "@CMAKE_MODULE_OUTPUT_DIRECTORY@/" BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
+    const char configDevDirectory[]         = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@/" BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
+    const char logDevDirectory[]            = "@CMAKE_LOG_OUTPUT_DIRECTORY@/"    BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
 #else
-    const char ORXONOX_MODULE_DEV_PATH[]      = "@CMAKE_MODULE_OUTPUT_DIRECTORY@";
-    const char ORXONOX_CONFIG_DEV_PATH[]      = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@";
-    const char ORXONOX_LOG_DEV_PATH[]         = "@CMAKE_LOG_OUTPUT_DIRECTORY@";
+    const char moduleDevDirectory[]         = "@CMAKE_MODULE_OUTPUT_DIRECTORY@";
+    const char configDevDirectory[]         = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@";
+    const char logDevDirectory[]            = "@CMAKE_LOG_OUTPUT_DIRECTORY@";
 #endif
+
 #ifdef DEPENDENCY_PACKAGE_ENABLE
-    const char ORXONOX_DEP_LIB_PATH[]         = "@DEP_LIBRARY_DIR@";
+    const char dependencyLibraryDirectory[] = "@DEP_LIBRARY_DIR@";
 #endif
 
     // Module extension
-    const char ORXONOX_MODULE_EXTENSION[]     = "@ORXONOX_MODULE_EXTENSION@";
+    const char moduleExtension[] = "@ORXONOX_MODULE_EXTENSION@";
 
     // OGRE PLUGINS
 #ifdef NDEBUG
-    const char ORXONOX_OGRE_PLUGINS[] = "@OGRE_PLUGINS_RELEASE@";
+    const char ogrePlugins[] = "@OGRE_PLUGINS_RELEASE@";
 #  ifdef DEPENDENCY_PACKAGE_ENABLE
-    const char ORXONOX_OGRE_PLUGINS_FOLDER[] = ".";
+    const char ogrePluginsDirectory[] = ".";
 #  else
-    const char ORXONOX_OGRE_PLUGINS_FOLDER[] = "@OGRE_PLUGINS_FOLDER_RELEASE@";
+    const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_RELEASE@";
 #  endif
 #else
-    const char ORXONOX_OGRE_PLUGINS[] = "@OGRE_PLUGINS_DEBUG@";
+    const char ogrePlugins[] = "@OGRE_PLUGINS_DEBUG@";
 #  ifdef DEPENDENCY_PACKAGE_ENABLE
-    const char ORXONOX_OGRE_PLUGINS_FOLDER[] = ".";
+    const char ogrePluginsDirectory[] = ".";
 #  else
-    const char ORXONOX_OGRE_PLUGINS_FOLDER[] = "@OGRE_PLUGINS_FOLDER_DEBUG@";
+    const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_DEBUG@";
 #  endif
 #endif
-}
+} }
 
 /**
Index: code/trunk/src/ceguilua/CMakeLists.txt
===================================================================
--- code/trunk/src/ceguilua/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/ceguilua/CMakeLists.txt	(revision 5695)
@@ -63,5 +63,5 @@
                                 CEGUI.pkg
   DEPENDS              ${TOLUA_PARSER_DEPENDENCIES}
-  WORKING_DIRECTORY    ${ORXONOX_RUNTIME_LIBRARY_DIRECTORY}
+  WORKING_DIRECTORY    ${RUNTIME_LIBRARY_DIRECTORY}
   COMMENT "Generating tolua bind files for package CEGUILua"
 )
Index: code/trunk/src/core/CMakeLists.txt
===================================================================
--- code/trunk/src/core/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/core/CMakeLists.txt	(revision 5695)
@@ -32,7 +32,9 @@
   GUIManager.cc
   Language.cc
-  LuaBind.cc
+  LuaState.cc
+  MemoryArchive.cc
   ObjectListBase.cc
   OrxonoxClass.cc
+  Resource.cc
   WindowEventListener.cc
 
@@ -77,5 +79,6 @@
   TOLUA_FILES
     CommandExecutor.h
-    LuaBind.h
+    Loader.h
+    LuaState.h
   DEFINE_SYMBOL
     "CORE_SHARED_BUILD"
Index: code/trunk/src/core/Clock.h
===================================================================
--- code/trunk/src/core/Clock.h	(revision 5693)
+++ code/trunk/src/core/Clock.h	(revision 5695)
@@ -21,7 +21,7 @@
  *
  *   Author:
- *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
- *      Reto Grieder
+ *      ...
  *
  */
Index: code/trunk/src/core/ConfigFileManager.cc
===================================================================
--- code/trunk/src/core/ConfigFileManager.cc	(revision 5693)
+++ code/trunk/src/core/ConfigFileManager.cc	(revision 5695)
@@ -40,8 +40,4 @@
 namespace orxonox
 {
-    const char* const DEFAULT_CONFIG_FILE = "default.ini";
-
-    ConfigFileManager* ConfigFileManager::singletonPtr_s = 0;
-
     SetConsoleCommandShortcutExtern(config).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
     SetConsoleCommandShortcutExtern(tconfig).argumentCompleter(0, autocompletion::configvalueclasses()).argumentCompleter(1, autocompletion::configvalues()).argumentCompleter(2, autocompletion::configvalue());
@@ -229,6 +225,6 @@
         if (!boost::filesystem::exists(filepath))
         {
-            // Try to get default one from the media folder
-            boost::filesystem::path defaultFilepath(Core::getMediaPath() / "defaultConfig" / this->filename_);
+            // Try to get default one from the data folder
+            boost::filesystem::path defaultFilepath(Core::getDataPath() / "defaultConfig" / this->filename_);
             if (boost::filesystem::exists(defaultFilepath))
             {
@@ -339,8 +335,6 @@
     void ConfigFile::save() const
     {
-        boost::filesystem::path filepath(Core::getConfigPath() / this->filename_);
-
         std::ofstream file;
-        file.open(filepath.string().c_str(), std::fstream::out);
+        file.open((Core::getConfigPathString() + filename_).c_str(), std::fstream::out);
         file.setf(std::ios::fixed, std::ios::floatfield);
         file.precision(6);
@@ -479,4 +473,8 @@
     ///////////////////////
 
+    ConfigFileManager* ConfigFileManager::singletonPtr_s = 0;
+
+    std::string ConfigFileManager::DEFAULT_CONFIG_FILE = "default.ini";
+
     ConfigFileManager::ConfigFileManager()
          : mininmalFreeType_(ConfigFileType::numberOfReservedTypes)
Index: code/trunk/src/core/ConfigFileManager.h
===================================================================
--- code/trunk/src/core/ConfigFileManager.h	(revision 5693)
+++ code/trunk/src/core/ConfigFileManager.h	(revision 5695)
@@ -307,4 +307,6 @@
             void updateConfigValues(ConfigFileType type);
 
+            static std::string DEFAULT_CONFIG_FILE;
+
         private:
             ConfigFileManager(const ConfigFileManager&);
Index: code/trunk/src/core/ConfigValueContainer.h
===================================================================
--- code/trunk/src/core/ConfigValueContainer.h	(revision 5693)
+++ code/trunk/src/core/ConfigValueContainer.h	(revision 5695)
@@ -31,5 +31,5 @@
     @brief Definition of the ConfigValueContainer class.
 
-    The ConfigValueContainer class contains all needed informations about a configurable variable:
+    The ConfigValueContainer class contains all needed information about a configurable variable:
      - the name of the variable
      - the name of the class the variable belongs to
@@ -79,7 +79,7 @@
 
 
-    //! The ConfigValuecontainer contains all needed informations about a configurable variable.
+    //! The ConfigValuecontainer contains all needed information about a configurable variable.
     /**
-        The ConfigValueContainer class contains all needed informations about a configurable variable:
+        The ConfigValueContainer class contains all needed information about a configurable variable:
          - the name of the variable
          - the name of the class the variable belongs to
Index: code/trunk/src/core/Core.cc
===================================================================
--- code/trunk/src/core/Core.cc	(revision 5693)
+++ code/trunk/src/core/Core.cc	(revision 5695)
@@ -42,5 +42,4 @@
 #include <boost/version.hpp>
 #include <boost/filesystem.hpp>
-#include <OgreRenderWindow.h>
 
 #ifdef ORXONOX_PLATFORM_WINDOWS
@@ -76,5 +75,5 @@
 #include "Identifier.h"
 #include "Language.h"
-#include "LuaBind.h"
+#include "LuaState.h"
 #include "Shell.h"
 #include "TclBind.h"
@@ -94,5 +93,5 @@
     Core* Core::singletonPtr_s  = 0;
 
-    SetCommandLineArgument(mediaPath, "").information("Path to the media/data files");
+    SetCommandLineArgument(externalDataPath, "").information("Path to the external data files");
     SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files");
     SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
@@ -119,7 +118,11 @@
             this->setConfigValues();
 
-            // Possible media path override by the command line
-            if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
-                tsetMediaPath(CommandLine::getValue("mediaPath"));
+            // External data directory only exists for dev runs
+            if (Core::isDevelopmentRun())
+            {
+                // Possible data path override by the command line
+                if (!CommandLine::getArgument("externalDataPath")->hasDefaultValue())
+                    tsetExternalDataPath(CommandLine::getValue("externalDataPath"));
+            }
         }
 
@@ -154,12 +157,4 @@
                 .description("If true, all random actions are different each time you start the game")
                 .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
-
-            // Only show this config value for development builds
-            if (Core::isDevelopmentRun())
-            {
-                SetConfigValue(mediaPathString_, mediaPath_.string())
-                    .description("Relative path to the game data.")
-                    .callback(this, &CoreConfiguration::mediaPathChanged);
-            }
         }
 
@@ -192,13 +187,4 @@
 
         /**
-        @brief
-            Callback function if the media path has changed.
-        */
-        void mediaPathChanged()
-        {
-            mediaPath_ = boost::filesystem::path(this->mediaPathString_);
-        }
-
-        /**
             @brief Sets the language in the config-file back to the default.
         */
@@ -210,20 +196,11 @@
         /**
         @brief
-            Temporary sets the media path
+            Temporary sets the data path
         @param path
-            The new media path
+            The new data path
         */
-        void tsetMediaPath(const std::string& path)
-        {
-            if (Core::isDevelopmentRun())
-            {
-                ModifyConfigValue(mediaPathString_, tset, path);
-            }
-            else
-            {
-                // Manual 'config' value without the file entry
-                mediaPathString_ = path;
-                this->mediaPathChanged();
-            }
+        void tsetExternalDataPath(const std::string& path)
+        {
+            dataPath_ = boost::filesystem::path(path);
         }
 
@@ -245,5 +222,4 @@
         std::string language_;                          //!< The language
         bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
-        std::string mediaPathString_;                   //!< Path to the data/media file folder as string
 
         //! Path to the parent directory of the ones above if program was installed with relativ pahts
@@ -251,5 +227,6 @@
         boost::filesystem::path executablePath_;        //!< Path to the executable
         boost::filesystem::path modulePath_;            //!< Path to the modules
-        boost::filesystem::path mediaPath_;             //!< Path to the media file folder
+        boost::filesystem::path dataPath_;              //!< Path to the data file folder
+        boost::filesystem::path externalDataPath_;      //!< Path to the external data file folder
         boost::filesystem::path configPath_;            //!< Path to the config file folder
         boost::filesystem::path logPath_;               //!< Path to the log file folder
@@ -276,5 +253,5 @@
         {
             // We search for helper files with the following extension
-            std::string moduleextension = ORXONOX_MODULE_EXTENSION;
+            std::string moduleextension = specialConfig::moduleExtension;
             size_t moduleextensionlength = moduleextension.size();
 
@@ -364,25 +341,25 @@
         this->languageInstance_.reset(new Language());
 
+        // creates the class hierarchy for all classes with factories
+        Factory::createClassHierarchy();
+
         // Do this soon after the ConfigFileManager has been created to open up the
         // possibility to configure everything below here
         this->configuration_->initialise();
 
-        // Create the lua interface
-        this->luaBind_.reset(new LuaBind());
+        // Load OGRE excluding the renderer and the render window
+        this->graphicsManager_.reset(new GraphicsManager(false));
 
         // initialise Tcl
-        this->tclBind_.reset(new TclBind(Core::getMediaPathString()));
+        this->tclBind_.reset(new TclBind(Core::getDataPathString()));
         this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
 
         // create a shell
         this->shell_.reset(new Shell());
-
-        // creates the class hierarchy for all classes with factories
-        Factory::createClassHierarchy();
     }
 
     /**
     @brief
-        All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
+        All destruction code is handled by scoped_ptrs and ScopeGuards.
     */
     Core::~Core()
@@ -392,23 +369,18 @@
     void Core::loadGraphics()
     {
-        if (bGraphicsLoaded_)
-            return;
-
-        // Load OGRE including the render window
-        scoped_ptr<GraphicsManager> graphicsManager(new GraphicsManager());
-
-        // The render window width and height are used to set up the mouse movement.
-        size_t windowHnd = 0;
-        graphicsManager->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
+        // Any exception should trigger this, even in upgradeToGraphics (see its remarks)
+        Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics);
+
+        // Upgrade OGRE to receive a render window
+        graphicsManager_->upgradeToGraphics();
 
         // Calls the InputManager which sets up the input devices.
-        scoped_ptr<InputManager> inputManager(new InputManager(windowHnd));
+        inputManager_.reset(new InputManager());
 
         // load the CEGUI interface
-        guiManager_.reset(new GUIManager(graphicsManager->getRenderWindow()));
-
-        // Dismiss scoped pointers
-        graphicsManager_.swap(graphicsManager);
-        inputManager_.swap(inputManager);
+        guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow(),
+            inputManager_->getMousePosition(), graphicsManager_->isFullScreen()));
+
+        unloader.Dismiss();
 
         bGraphicsLoaded_ = true;
@@ -417,10 +389,18 @@
     void Core::unloadGraphics()
     {
-        if (!bGraphicsLoaded_)
-            return;
-
         this->guiManager_.reset();;
         this->inputManager_.reset();;
         this->graphicsManager_.reset();
+
+        // Load Ogre::Root again, but without the render system
+        try
+            { this->graphicsManager_.reset(new GraphicsManager(false)); }
+        catch (...)
+        {
+            COUT(0) << "An exception occurred during 'new GraphicsManager' while "
+                    << "another exception was being handled. This will lead to undefined behaviour!" << std::endl
+                    << "Terminating the program." << std::endl;
+            abort();
+        }
 
         bGraphicsLoaded_ = false;
@@ -485,16 +465,25 @@
     }
 
-    /*static*/ void Core::tsetMediaPath(const std::string& path)
-    {
-        getInstance().configuration_->tsetMediaPath(path);
-    }
-
-    /*static*/ const boost::filesystem::path& Core::getMediaPath()
-    {
-        return getInstance().configuration_->mediaPath_;
-    }
-    /*static*/ std::string Core::getMediaPathString()
-    {
-        return getInstance().configuration_->mediaPath_.string() + '/';
+    /*static*/ void Core::tsetExternalDataPath(const std::string& path)
+    {
+        getInstance().configuration_->tsetExternalDataPath(path);
+    }
+
+    /*static*/ const boost::filesystem::path& Core::getDataPath()
+    {
+        return getInstance().configuration_->dataPath_;
+    }
+    /*static*/ std::string Core::getDataPathString()
+    {
+        return getInstance().configuration_->dataPath_.string() + '/';
+    }
+
+    /*static*/ const boost::filesystem::path& Core::getExternalDataPath()
+    {
+        return getInstance().configuration_->externalDataPath_;
+    }
+    /*static*/ std::string Core::getExternalDataPathString()
+    {
+        return getInstance().configuration_->externalDataPath_.string() + '/';
     }
 
@@ -638,5 +627,5 @@
             COUT(1) << "Running from the build tree." << std::endl;
             Core::bDevRun_ = true;
-            configuration_->modulePath_ = ORXONOX_MODULE_DEV_PATH;
+            configuration_->modulePath_ = specialConfig::moduleDevDirectory;
         }
         else
@@ -646,5 +635,5 @@
 
             // Also set the root path
-            boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH);
+            boost::filesystem::path relativeExecutablePath(specialConfig::defaultRuntimePath);
             configuration_->rootPath_ = configuration_->executablePath_;
             while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_)
@@ -655,5 +644,5 @@
 
             // Module path is fixed as well
-            configuration_->modulePath_ = configuration_->rootPath_ / ORXONOX_MODULE_INSTALL_PATH;
+            configuration_->modulePath_ = configuration_->rootPath_ / specialConfig::defaultModulePath;
 
 #else
@@ -661,5 +650,5 @@
             // There is no root path, so don't set it at all
             // Module path is fixed as well
-            configuration_->modulePath_ = ORXONOX_MODULE_INSTALL_PATH;
+            configuration_->modulePath_ = specialConfig::moduleInstallDirectory;
 
 #endif
@@ -677,7 +666,8 @@
         if (Core::isDevelopmentRun())
         {
-            configuration_->mediaPath_  = ORXONOX_MEDIA_DEV_PATH;
-            configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH;
-            configuration_->logPath_    = ORXONOX_LOG_DEV_PATH;
+            configuration_->dataPath_  = specialConfig::dataDevDirectory;
+            configuration_->externalDataPath_ = specialConfig::externalDataDevDirectory;
+            configuration_->configPath_ = specialConfig::configDevDirectory;
+            configuration_->logPath_    = specialConfig::logDevDirectory;
         }
         else
@@ -687,11 +677,11 @@
 
             // Using paths relative to the install prefix, complete them
-            configuration_->mediaPath_  = configuration_->rootPath_ / ORXONOX_MEDIA_INSTALL_PATH;
-            configuration_->configPath_ = configuration_->rootPath_ / ORXONOX_CONFIG_INSTALL_PATH;
-            configuration_->logPath_    = configuration_->rootPath_ / ORXONOX_LOG_INSTALL_PATH;
+            configuration_->dataPath_   = configuration_->rootPath_ / specialConfig::defaultDataPath;
+            configuration_->configPath_ = configuration_->rootPath_ / specialConfig::defaultConfigPath;
+            configuration_->logPath_    = configuration_->rootPath_ / specialConfig::defaultLogPath;
 
 #else
 
-            configuration_->mediaPath_  = ORXONOX_MEDIA_INSTALL_PATH;
+            configuration_->dataPath_  = specialConfig::dataInstallDirectory;
 
             // Get user directory
@@ -706,6 +696,6 @@
             userDataPath /= ".orxonox";
 
-            configuration_->configPath_ = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
-            configuration_->logPath_    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
+            configuration_->configPath_ = userDataPath / specialConfig::defaultConfigPath;
+            configuration_->logPath_    = userDataPath / specialConfig::defaultLogPath;
 
 #endif
@@ -741,54 +731,24 @@
     }
 
-    bool Core::preUpdate(const Clock& time) throw()
-    {
-        std::string exceptionMessage;
-        try
-        {
-            if (this->bGraphicsLoaded_)
-            {
-                // process input events
-                this->inputManager_->update(time);
-                // process gui events
-                this->guiManager_->update(time);
-            }
-            // process thread commands
-            this->tclThreadManager_->update(time);
-        }
-        catch (const std::exception& ex)
-        { exceptionMessage = ex.what(); }
-        catch (...)
-        { exceptionMessage = "Unknown exception"; }
-        if (!exceptionMessage.empty())
-        {
-            COUT(0) << "An exception occurred in the Core preUpdate: " << exceptionMessage << std::endl;
-            COUT(0) << "This should really never happen! Closing the program." << std::endl;
-            return false;
-        }
-        return true;
-    }
-
-    bool Core::postUpdate(const Clock& time) throw()
-    {
-        std::string exceptionMessage;
-        try
-        {
-            if (this->bGraphicsLoaded_)
-            {
-                // Render (doesn't throw)
-                this->graphicsManager_->update(time);
-            }
-        }
-        catch (const std::exception& ex)
-        { exceptionMessage = ex.what(); }
-        catch (...)
-        { exceptionMessage = "Unknown exception"; }
-        if (!exceptionMessage.empty())
-        {
-            COUT(0) << "An exception occurred in the Core postUpdate: " << exceptionMessage << std::endl;
-            COUT(0) << "This should really never happen! Closing the program." << std::endl;
-            return false;
-        }
-        return true;
+    void Core::preUpdate(const Clock& time)
+    {
+        if (this->bGraphicsLoaded_)
+        {
+            // process input events
+            this->inputManager_->update(time);
+            // process gui events
+            this->guiManager_->update(time);
+        }
+        // process thread commands
+        this->tclThreadManager_->update(time);
+    }
+
+    void Core::postUpdate(const Clock& time)
+    {
+        if (this->bGraphicsLoaded_)
+        {
+            // Render (doesn't throw)
+            this->graphicsManager_->update(time);
+        }
     }
 }
Index: code/trunk/src/core/Core.h
===================================================================
--- code/trunk/src/core/Core.h	(revision 5693)
+++ code/trunk/src/core/Core.h	(revision 5695)
@@ -51,5 +51,4 @@
 {
     class CoreConfiguration;
-    using boost::scoped_ptr;
 
     /**
@@ -57,5 +56,5 @@
         The Core class is a singleton used to configure the program basics.
     @details
-        The class provides information about the media, config and log path.
+        The class provides information about the data, config and log path.
         It determines those by the use of platform specific functions.
     @remark
@@ -66,4 +65,5 @@
         typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
         friend class Singleton<Core>;
+        friend class Game;
 
         public:
@@ -80,10 +80,4 @@
             void setConfigValues();
 
-            bool preUpdate(const Clock& time) throw();
-            bool postUpdate(const Clock& time) throw();
-
-            void loadGraphics();
-            void unloadGraphics();
-
             static int   getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
             static void  setSoftDebugLevel(OutputHandler::OutputDevice device, int level);
@@ -91,7 +85,9 @@
             static void  resetLanguage();
 
-            static void tsetMediaPath(const std::string& path);
-            //! Returns the path to the config files as boost::filesystem::path
-            static const boost::filesystem::path& getMediaPath();
+            static void tsetExternalDataPath(const std::string& path);
+            //! Returns the path to the data files as boost::filesystem::path
+            static const boost::filesystem::path& getDataPath();
+            //! Returns the path to the external data files as boost::filesystem::path
+            static const boost::filesystem::path& getExternalDataPath();
             //! Returns the path to the config files as boost::filesystem::path
             static const boost::filesystem::path& getConfigPath();
@@ -101,5 +97,7 @@
             static const boost::filesystem::path& getRootPath();
             //! Returns the path to the data files as std::string
-            static std::string getMediaPathString();
+            static std::string getDataPathString();
+            //! Returns the path to the external data files as std::string
+            static std::string getExternalDataPathString();
             //! Returns the path to the config files as std::string
             static std::string getConfigPathString();
@@ -113,4 +111,10 @@
         private:
             Core(const Core&); //!< Don't use (undefined symbol)
+
+            void preUpdate(const Clock& time);
+            void postUpdate(const Clock& time);
+
+            void loadGraphics();
+            void unloadGraphics();
 
             void setFixedPaths();
@@ -126,5 +130,4 @@
             scoped_ptr<Language>          languageInstance_;
             scoped_ptr<CoreConfiguration> configuration_;
-            scoped_ptr<LuaBind>           luaBind_;
             scoped_ptr<TclBind>           tclBind_;
             scoped_ptr<TclThreadManager>  tclThreadManager_;
Index: code/trunk/src/core/CorePrereqs.h
===================================================================
--- code/trunk/src/core/CorePrereqs.h	(revision 5693)
+++ code/trunk/src/core/CorePrereqs.h	(revision 5695)
@@ -135,5 +135,7 @@
     class LanguageEntry;
     class Loader;
-    class LuaBind;
+    class LuaState;
+    class MemoryArchive;
+    class MemoryArchiveFactory;
     class MetaObjectList;
     class MetaObjectListElement;
@@ -150,4 +152,5 @@
     class OgreWindowEventListener;
     class OrxonoxClass;
+    struct ResourceInfo;
     class Shell;
     class ShellListener;
@@ -225,4 +228,18 @@
 }
 
+// Ogre
+namespace Ogre
+{
+    class DataStream;
+    template <class T> class SharedPtr;
+    typedef SharedPtr<DataStream> DataStreamPtr;
+}
+namespace orxonox
+{
+    // Import the Ogre::DataStream
+    using Ogre::DataStream;
+    using Ogre::DataStreamPtr;
+}
+
 // CEGUI
 namespace CEGUI
Index: code/trunk/src/core/DynLibManager.h
===================================================================
--- code/trunk/src/core/DynLibManager.h	(revision 5693)
+++ code/trunk/src/core/DynLibManager.h	(revision 5695)
@@ -34,4 +34,7 @@
 
 #include "CorePrereqs.h"
+
+#include <map>
+#include <string>
 #include "util/Singleton.h"
 
Index: code/trunk/src/core/GUIManager.cc
===================================================================
--- code/trunk/src/core/GUIManager.cc	(revision 5693)
+++ code/trunk/src/core/GUIManager.cc	(revision 5695)
@@ -27,10 +27,4 @@
  *
  */
-
-/**
-@file
-@brief
-    Implementation of the GUIManager class.
-*/
 
 #include "GUIManager.h"
@@ -43,4 +37,5 @@
 #include <CEGUIExceptions.h>
 #include <CEGUIInputEvent.h>
+#include <CEGUIMouseCursor.h>
 #include <CEGUIResourceProvider.h>
 #include <CEGUISystem.h>
@@ -59,5 +54,6 @@
 #include "Core.h"
 #include "Clock.h"
-#include "LuaBind.h"
+#include "LuaState.h"
+#include "Resource.h"
 
 namespace orxonox
@@ -101,5 +97,5 @@
     @return true if success, otherwise false
     */
-    GUIManager::GUIManager(Ogre::RenderWindow* renderWindow)
+    GUIManager::GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen)
         : renderWindow_(renderWindow)
         , resourceProvider_(0)
@@ -109,70 +105,42 @@
         COUT(3) << "Initialising CEGUI." << std::endl;
 
-        try
-        {
-            // Note: No SceneManager specified yet
-            guiRenderer_.reset(new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
-            resourceProvider_ = guiRenderer_->createResourceProvider();
-            resourceProvider_->setDefaultResourceGroup("GUI");
-
-            // setup scripting
-            scriptModule_.reset(new LuaScriptModule());
-            luaState_ = scriptModule_->getLuaState();
-
-            // Create our own logger to specify the filepath
-            std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
-            ceguiLogger->setLogFilename(Core::getLogPathString() + "cegui.log");
-            // set the log level according to ours (translate by subtracting 1)
-            ceguiLogger->setLoggingLevel(
-                static_cast<LoggingLevel>(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
-            this->ceguiLogger_ = ceguiLogger.release();
-
-            // create the CEGUI system singleton
-            guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
-
-            // do this after 'new CEGUI::Sytem' because that creates the lua state in the first place
-            LuaBind::getInstance().openToluaInterfaces(this->luaState_);
-
-            // initialise the basic lua code
-            this->loadLuaCode();
-        }
-        catch (CEGUI::Exception& ex)
-        {
-#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
-            throw GeneralException(ex.getMessage().c_str());
-#else
-            throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
-                ex.getFileName().c_str(), ex.getName().c_str());
-#endif
-        }
-    }
-
-    /**
-    @brief
-        Destructor of the GUIManager
-
+        // Note: No SceneManager specified yet
+        guiRenderer_.reset(new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
+        resourceProvider_ = guiRenderer_->createResourceProvider();
+        resourceProvider_->setDefaultResourceGroup("GUI");
+
+        // setup scripting
+        luaState_.reset(new LuaState());
+        scriptModule_.reset(new LuaScriptModule(luaState_->getInternalLuaState()));
+
+        // Create our own logger to specify the filepath
+        std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
+        ceguiLogger->setLogFilename(Core::getLogPathString() + "cegui.log");
+        // set the log level according to ours (translate by subtracting 1)
+        ceguiLogger->setLoggingLevel(
+            static_cast<LoggingLevel>(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
+        this->ceguiLogger_ = ceguiLogger.release();
+
+        // create the CEGUI system singleton
+        guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
+
+        // Initialise the basic lua code
+        rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua", "GUI");
+        this->luaState_->doFile("InitialiseGUI.lua", "GUI", false);
+
+        // Align CEGUI mouse with OIS mouse
+        guiSystem_->injectMousePosition(mousePosition.first, mousePosition.second);
+
+        // Hide the mouse cursor unless playing in fullscreen mode
+        if (!bFullScreen)
+            CEGUI::MouseCursor::getSingleton().hide();
+    }
+
+    /**
+    @brief
         Basically shuts down CEGUI (member smart pointers) but first unloads our Tolua modules.
     */
     GUIManager::~GUIManager()
     {
-        // destroy our own tolua interfaces
-        LuaBind::getInstance().closeToluaInterfaces(this->luaState_);
-    }
-
-    /**
-    @brief
-        Calls main Lua script
-    @todo
-        This function calls the main Lua script for our GUI.
-
-        Additionally we set the datapath variable in Lua. This is needed so Lua can access the data used for the GUI.
-    */
-    void GUIManager::loadLuaCode()
-    {
-        // set datapath for GUI data
-        lua_pushfstring(this->scriptModule_->getLuaState(), Core::getMediaPathString().c_str());
-        lua_setglobal(this->scriptModule_->getLuaState(), "datapath");
-        // call main Lua script
-        this->scriptModule_->executeScriptFile("loadGUI_3.lua", "GUI");
     }
 
@@ -221,16 +189,5 @@
     void GUIManager::executeCode(const std::string& str)
     {
-        try
-        {
-            this->scriptModule_->executeString(str);
-        }
-        catch (const CEGUI::Exception& ex)
-        {
-            COUT(2) << "CEGUI Error: \"" << ex.getMessage() << "\" while executing code \"" << str << "\"" << std::endl;
-        }
-        catch (...)
-        {
-            COUT(2) << "Couldn't execute GUI related Lua code due to unknown reasons." << std::endl;
-        }
+        this->luaState_->doString(str, rootFileInfo_);
     }
 
@@ -246,5 +203,5 @@
     void GUIManager::showGUI(const std::string& name)
     {
-        this->executeCode(std::string("showGUI(\"") + name + "\")");
+        this->luaState_->doString("showGUI(\"" + name + "\")", rootFileInfo_);
     }
 
@@ -305,5 +262,5 @@
     void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     {
-        guiSystem_->injectMouseMove(static_cast<float>(rel.x), static_cast<float>(rel.y));
+        guiSystem_->injectMousePosition(static_cast<float>(abs.x), static_cast<float>(abs.y));
     }
     void GUIManager::mouseScrolled(int abs, int rel)
Index: code/trunk/src/core/GUIManager.h
===================================================================
--- code/trunk/src/core/GUIManager.h	(revision 5693)
+++ code/trunk/src/core/GUIManager.h	(revision 5695)
@@ -28,10 +28,4 @@
  */
 
-/**
-@file
-@brief
-    Declaration of the GUIManager class.
-*/
-
 #ifndef _GUIManager_H__
 #define _GUIManager_H__
@@ -43,4 +37,5 @@
 #include <CEGUIForwardRefs.h>
 #include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include "util/OgreForwardRefs.h"
@@ -67,5 +62,5 @@
         friend class Singleton<GUIManager>;
     public:
-        GUIManager(Ogre::RenderWindow* renderWindow);
+        GUIManager(Ogre::RenderWindow* renderWindow, const std::pair<int, int>& mousePosition, bool bFullScreen);
         ~GUIManager();
 
@@ -87,6 +82,4 @@
         GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
 
-        void loadLuaCode();
-
         // keyHandler functions
         void keyPressed (const KeyEvent& evt);
@@ -99,14 +92,15 @@
         void mouseScrolled (int abs, int rel);
 
-        boost::scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_;       //!< CEGUI's interface to the Ogre Engine
-        boost::scoped_ptr<CEGUI::LuaScriptModule>   scriptModule_;      //!< CEGUI's script module to use Lua
-        boost::scoped_ptr<CEGUI::System>            guiSystem_;         //!< CEGUI's main system
-        Ogre::RenderWindow*                         renderWindow_;      //!< Ogre's render window to give CEGUI access to it
-        CEGUI::ResourceProvider*                    resourceProvider_;  //!< CEGUI's resource provider
-        CEGUI::Logger*                              ceguiLogger_;       //!< CEGUI's logger to be able to log CEGUI errors in our log
-        lua_State*                                  luaState_;          //!< Lua state, access point to the Lua engine
-        std::map<std::string, PlayerInfo*>          players_;           //!< Stores the player (owner) for each gui
+        scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_;      //!< CEGUI's interface to the Ogre Engine
+        scoped_ptr<LuaState>                 luaState_;         //!< LuaState, access point to the Lua engine
+        scoped_ptr<CEGUI::LuaScriptModule>   scriptModule_;     //!< CEGUI's script module to use Lua
+        scoped_ptr<CEGUI::System>            guiSystem_;        //!< CEGUI's main system
+        shared_ptr<ResourceInfo>             rootFileInfo_;     //!< Resource information about the root script
+        Ogre::RenderWindow*                  renderWindow_;     //!< Ogre's render window to give CEGUI access to it
+        CEGUI::ResourceProvider*             resourceProvider_; //!< CEGUI's resource provider
+        CEGUI::Logger*                       ceguiLogger_;      //!< CEGUI's logger to be able to log CEGUI errors in our log
+        std::map<std::string, PlayerInfo*>   players_;          //!< Stores the player (owner) for each gui
 
-        static GUIManager*                          singletonPtr_s;     //!< Singleton reference to GUIManager
+        static GUIManager*                   singletonPtr_s;    //!< Singleton reference to GUIManager
 
     };
Index: code/trunk/src/core/Game.cc
===================================================================
--- code/trunk/src/core/Game.cc	(revision 5693)
+++ code/trunk/src/core/Game.cc	(revision 5695)
@@ -37,4 +37,5 @@
 #include <exception>
 #include <boost/weak_ptr.hpp>
+#include <CEGUIExceptions.h>
 
 #include "util/Debug.h"
@@ -54,7 +55,4 @@
 namespace orxonox
 {
-    using boost::shared_ptr;
-    using boost::weak_ptr;
-
     static void stop_game()
         { Game::getInstance().stop(); }
@@ -202,6 +200,10 @@
 
             // Core preUpdate (doesn't throw)
-            if (!this->core_->preUpdate(*this->gameClock_))
-            {
+            try
+                { this->core_->preUpdate(*this->gameClock_); }
+            catch (...)
+            {
+                COUT(0) << "An exception occurred in the Core preUpdate: " << Game::getExceptionMessage() << std::endl;
+                COUT(0) << "This should really never happen! Closing the program." << std::endl;
                 this->stop();
                 break;
@@ -212,6 +214,10 @@
 
             // Core postUpdate (doesn't throw)
-            if (!this->core_->postUpdate(*this->gameClock_))
-            {
+            try
+                { this->core_->postUpdate(*this->gameClock_); }
+            catch (...)
+            {
+            COUT(0) << "An exception occurred in the Core postUpdate: " << Game::getExceptionMessage() << std::endl;
+            COUT(0) << "This should really never happen! Closing the program." << std::endl;
                 this->stop();
                 break;
@@ -246,10 +252,10 @@
                     this->loadState(requestedStateNode->name_);
                 }
-                catch (const std::exception& ex)
+                catch (...)
                 {
-                    COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << ex.what() << std::endl;
+                    COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << Game::getExceptionMessage() << std::endl;
                     // All scheduled operations have now been rendered inert --> flush them and issue a warning
                     if (this->requestedStateNodes_.size() > 1)
-                        COUT(1) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
+                        COUT(4) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
                     this->requestedStateNodes_.clear();
                     break;
@@ -267,9 +273,8 @@
             it != this->loadedStates_.end(); ++it)
         {
-            std::string exceptionMessage;
             try
             {
                 // Add tick time for most of the states
-                uint64_t timeBeforeTick;
+                uint64_t timeBeforeTick = 0;
                 if ((*it)->getInfo().bIgnoreTickTime)
                     timeBeforeTick = this->gameClock_->getRealMicroseconds();
@@ -278,11 +283,7 @@
                     this->subtractTickTime(static_cast<int32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
             }
-            catch (const std::exception& ex)
-            { exceptionMessage = ex.what(); }
             catch (...)
-            { exceptionMessage = "Unknown exception"; }
-            if (!exceptionMessage.empty())
-            {
-                COUT(1) << "An exception occurred while updating '" << (*it)->getName() << "': " << exceptionMessage << std::endl;
+            {
+                COUT(1) << "An exception occurred while updating '" << (*it)->getName() << "': " << Game::getExceptionMessage() << std::endl;
                 COUT(1) << "This should really never happen!" << std::endl;
                 COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
@@ -590,16 +591,46 @@
             state->deactivate();
         }
+        catch (...)
+        {
+            COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << Game::getExceptionMessage() << std::endl;
+            COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
+        }
+        // Check if graphics is still required
+        if (!bAbort_)
+        {
+            bool graphicsRequired = false;
+            for (unsigned i = 0; i < loadedStates_.size(); ++i)
+                graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode;
+            if (!graphicsRequired)
+                this->unloadGraphics();
+        }
+        this->bChangingState_ = false;
+    }
+
+    /*static*/ std::string Game::getExceptionMessage()
+    {
+        std::string exceptionMessage;
+        try
+        {
+            // rethrow
+            throw;
+        }
         catch (const std::exception& ex)
         {
-            COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << ex.what() << std::endl;
-            COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
-        }
-        // Check if graphics is still required
-        bool graphicsRequired = false;
-        for (unsigned i = 0; i < loadedStates_.size(); ++i)
-            graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode;
-        if (!graphicsRequired)
-            this->unloadGraphics();
-        this->bChangingState_ = false;
+            return ex.what();
+        }
+        catch (const CEGUI::Exception& ex)
+        {
+#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
+            return GeneralException(ex.getMessage().c_str()).getDescription();
+#else
+            return GeneralException(ex.getMessage().c_str(), ex.getLine(),
+                ex.getFileName().c_str(), ex.getName().c_str()).getDescription();
+#endif
+        }
+        catch (...)
+        {
+            return "Unknown exception";
+        }
     }
 
Index: code/trunk/src/core/Game.h
===================================================================
--- code/trunk/src/core/Game.h	(revision 5693)
+++ code/trunk/src/core/Game.h	(revision 5695)
@@ -62,6 +62,4 @@
 {
     class GameConfiguration;
-    using boost::scoped_ptr;
-    using boost::shared_ptr;
 
     //! Helper object required before GameStates are being constructed
@@ -85,5 +83,5 @@
         typedef std::vector<shared_ptr<GameState> > GameStateVector;
         typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
-        typedef boost::shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
+        typedef shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
 
     public:
@@ -157,4 +155,11 @@
         // ScopeGuard helper function
         void resetChangingState() { this->bChangingState_ = false; }
+        /**
+        @brief
+            Retrieves information from an exception caught with "..."
+        @remarks
+            Never ever call this function without an exception in the stack!
+        */
+        static std::string getExceptionMessage();
 
         scoped_ptr<Clock>                  gameClock_;
Index: code/trunk/src/core/GraphicsManager.cc
===================================================================
--- code/trunk/src/core/GraphicsManager.cc	(revision 5693)
+++ code/trunk/src/core/GraphicsManager.cc	(revision 5695)
@@ -28,25 +28,19 @@
  */
 
-/**
-@file
-@brief
-    Implementation of an partial interface to Ogre.
-*/
-
 #include "GraphicsManager.h"
 
 #include <fstream>
-#include <memory>
+#include <sstream>
 #include <boost/filesystem.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <OgreCompositorManager.h>
-#include <OgreConfigFile.h>
+#include <boost/shared_array.hpp>
+
+#include <OgreArchiveFactory.h>
+#include <OgreArchiveManager.h>
 #include <OgreFrameListener.h>
 #include <OgreRoot.h>
 #include <OgreLogManager.h>
-#include <OgreException.h>
 #include <OgreRenderWindow.h>
 #include <OgreRenderSystem.h>
+#include <OgreResourceGroupManager.h>
 #include <OgreTextureManager.h>
 #include <OgreViewport.h>
@@ -64,10 +58,11 @@
 #include "Game.h"
 #include "GameMode.h"
+#include "Loader.h"
+#include "MemoryArchive.h"
 #include "WindowEventListener.h"
+#include "XMLFile.h"
 
 namespace orxonox
 {
-    using boost::shared_ptr;
-
     class OgreWindowEventListener : public Ogre::WindowEventListener
     {
@@ -89,10 +84,11 @@
         Non-initialising constructor.
     */
-    GraphicsManager::GraphicsManager()
-        : ogreRoot_(0)
-        , ogreLogger_(0)
+    GraphicsManager::GraphicsManager(bool bLoadRenderer)
+        : ogreWindowEventListener_(new OgreWindowEventListener())
+#if OGRE_VERSION < 0x010600
+        , memoryArchiveFactory_(new MemoryArchiveFactory())
+#endif
         , renderWindow_(0)
         , viewport_(0)
-        , ogreWindowEventListener_(new OgreWindowEventListener())
     {
         RegisterObject(GraphicsManager);
@@ -100,32 +96,29 @@
         this->setConfigValues();
 
-        // Ogre setup procedure
-        setupOgre();
-
-        try
-        {
-            // load all the required plugins for Ogre
-            loadOgrePlugins();
-            // read resource declaration file
-            this->declareResources();
-            // Reads ogre config and creates the render window
-            this->loadRenderer();
-
-            // TODO: Spread this
-            this->initialiseResources();
-
-            // add console commands
-            FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
-            functor1->setObject(this);
-            ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
-            CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
-        }
-        catch (...)
-        {
-            // clean up
-            delete this->ogreRoot_;
-            delete this->ogreLogger_;
-            delete this->ogreWindowEventListener_;
-            throw;
+        // Ogre setup procedure (creating Ogre::Root)
+        this->loadOgreRoot();
+        // load all the required plugins for Ogre
+        this->loadOgrePlugins();
+
+        // At first, add the root paths of the data directories as resource locations
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(Core::getDataPathString(), "FileSystem", "dataRoot", false);
+        // Load resources
+        resources_.reset(new XMLFile("resources.oxr", "dataRoot"));
+        resources_->setLuaSupport(false);
+        Loader::open(resources_.get());
+
+        // Only for development runs
+        if (Core::isDevelopmentRun())
+        {
+            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(Core::getExternalDataPathString(), "FileSystem", "externalDataRoot", false);
+            extResources_.reset(new XMLFile("resources.oxr", "externalDataRoot"));
+            extResources_->setLuaSupport(false);
+            Loader::open(extResources_.get());
+        }
+
+        if (bLoadRenderer)
+        {
+            // Reads the ogre config and creates the render window
+            this->upgradeToGraphics();
         }
     }
@@ -133,33 +126,19 @@
     /**
     @brief
-        Destroys all the Ogre related objects
+        Destruction is done by the member scoped_ptrs.
     */
     GraphicsManager::~GraphicsManager()
     {
-/*
-        delete this->ccPrintScreen_;
-*/
-
-        // unload all compositors (this is only necessary because we don't yet destroy all resources!)
-        Ogre::CompositorManager::getSingleton().removeAll();
-
-        // Delete OGRE main control organ
-        delete this->ogreRoot_;
-
-        // delete the logManager (since we have created it in the first place).
-        delete this->ogreLogger_;
-
-        delete this->ogreWindowEventListener_;
+        Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_.get());
+        // TODO: Destroy the console command
     }
 
     void GraphicsManager::setConfigValues()
     {
-        SetConfigValue(resourceFile_,    "resources.cfg")
-            .description("Location of the resources file in the data path.");
         SetConfigValue(ogreConfigFile_,  "ogre.cfg")
             .description("Location of the Ogre config file");
-        SetConfigValue(ogrePluginsFolder_, ORXONOX_OGRE_PLUGINS_FOLDER)
+        SetConfigValue(ogrePluginsDirectory_, specialConfig::ogrePluginsDirectory)
             .description("Folder where the Ogre plugins are located.");
-        SetConfigValue(ogrePlugins_, ORXONOX_OGRE_PLUGINS)
+        SetConfigValue(ogrePlugins_, specialConfig::ogrePlugins)
             .description("Comma separated list of all plugins to load.");
         SetConfigValue(ogreLogFile_,     "ogre.log")
@@ -173,4 +152,170 @@
     }
 
+    /**
+    @brief
+        Loads the renderer and creates the render window if not yet done so.
+    @remarks
+        This operation is irreversible without recreating the GraphicsManager!
+        So if it throws you HAVE to recreate the GraphicsManager!!!
+        It therefore offers almost no exception safety.
+    */
+    void GraphicsManager::upgradeToGraphics()
+    {
+        if (renderWindow_ != NULL)
+            return;
+
+        this->loadRenderer();
+
+#if OGRE_VERSION < 0x010600
+        // WORKAROUND: There is an incompatibility for particle scripts when trying
+        // to support both Ogre 1.4 and 1.6. The hacky solution is to create
+        // scripts for the 1.6 version and then remove the inserted "particle_system"
+        // keyword. But we need to supply these new scripts as well, which is why
+        // there is an extra Ogre::Archive dealing with in the memory.
+        using namespace Ogre;
+        ArchiveManager::getSingleton().addArchiveFactory(memoryArchiveFactory_.get());
+        const StringVector& groups = ResourceGroupManager::getSingleton().getResourceGroups();
+        // Travers all groups
+        for (StringVector::const_iterator itGroup = groups.begin(); itGroup != groups.end(); ++itGroup)
+        {
+            FileInfoListPtr files = ResourceGroupManager::getSingleton().findResourceFileInfo(*itGroup, "*.particle");
+            for (FileInfoList::const_iterator itFile = files->begin(); itFile != files->end(); ++itFile)
+            {
+                // open file
+                Ogre::DataStreamPtr input = ResourceGroupManager::getSingleton().openResource(itFile->filename, *itGroup, false);
+                std::stringstream output;
+                // Parse file and replace "particle_system" with nothing
+                while (!input->eof())
+                {
+                    std::string line = input->getLine();
+                    size_t pos = line.find("particle_system");
+                    if (pos != std::string::npos)
+                    {
+                        // 15 is the length of "particle_system"
+                        line.replace(pos, 15, "");
+                    }
+                    output << line << std::endl;
+                }
+                // Add file to the memory archive
+                shared_array<char> data(new char[output.str().size()]);
+                // Debug optimisations
+                const std::string outputStr = output.str();
+                char* rawData = data.get();
+                for (unsigned i = 0; i < outputStr.size(); ++i)
+                    rawData[i] = outputStr[i];
+                MemoryArchive::addFile("particle_scripts_ogre_1.4_" + *itGroup, itFile->filename, data, output.str().size());
+            }
+            if (!files->empty())
+            {
+                // Declare the files, but using a new group
+                ResourceGroupManager::getSingleton().addResourceLocation("particle_scripts_ogre_1.4_" + *itGroup,
+                    "Memory", "particle_scripts_ogre_1.4_" + *itGroup);
+            }
+        }
+#endif
+
+        // Initialise all resources (do this AFTER the renderer has been loaded!)
+        // Note: You can only do this once! Ogre will check whether a resource group has
+        // already been initialised. If you need to load resources later, you will have to
+        // choose another resource group.
+        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+    }
+
+    /**
+    @brief
+        Creates the Ogre Root object and sets up the ogre log.
+    */
+    void GraphicsManager::loadOgreRoot()
+    {
+        COUT(3) << "Setting up Ogre..." << std::endl;
+
+        if (ogreConfigFile_ == "")
+        {
+            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
+            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
+        }
+        if (ogreLogFile_ == "")
+        {
+            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
+            ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
+        }
+
+        boost::filesystem::path ogreConfigFilepath(Core::getConfigPath() / this->ogreConfigFile_);
+        boost::filesystem::path ogreLogFilepath(Core::getLogPath() / this->ogreLogFile_);
+
+        // create a new logManager
+        // Ogre::Root will detect that we've already created a Log
+        ogreLogger_.reset(new Ogre::LogManager());
+        COUT(4) << "Ogre LogManager created" << std::endl;
+
+        // create our own log that we can listen to
+        Ogre::Log *myLog;
+        myLog = ogreLogger_->createLog(ogreLogFilepath.string(), true, false, false);
+        COUT(4) << "Ogre Log created" << std::endl;
+
+        myLog->setLogDetail(Ogre::LL_BOREME);
+        myLog->addListener(this);
+
+        COUT(4) << "Creating Ogre Root..." << std::endl;
+
+        // check for config file existence because Ogre displays (caught) exceptions if not
+        if (!boost::filesystem::exists(ogreConfigFilepath))
+        {
+            // create a zero sized file
+            std::ofstream creator;
+            creator.open(ogreConfigFilepath.string().c_str());
+            creator.close();
+        }
+
+        // Leave plugins file empty. We're going to do that part manually later
+        ogreRoot_.reset(new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string()));
+
+        COUT(3) << "Ogre set up done." << std::endl;
+    }
+
+    void GraphicsManager::loadOgrePlugins()
+    {
+        // just to make sure the next statement doesn't segfault
+        if (ogrePluginsDirectory_ == "")
+            ogrePluginsDirectory_ = ".";
+
+        boost::filesystem::path folder(ogrePluginsDirectory_);
+        // Do some SubString magic to get the comma separated list of plugins
+        SubString plugins(ogrePlugins_, ",", " ", false, '\\', false, '"', false, '(', ')', false, '\0');
+        // Use backslash paths on Windows! file_string() already does that though.
+        for (unsigned int i = 0; i < plugins.size(); ++i)
+            ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
+    }
+
+    void GraphicsManager::loadRenderer()
+    {
+        CCOUT(4) << "Configuring Renderer" << std::endl;
+
+        if (!ogreRoot_->restoreConfig())
+            if (!ogreRoot_->showConfigDialog())
+                ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
+
+        CCOUT(4) << "Creating render window" << std::endl;
+
+        this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
+        // Propagate the size of the new winodw
+        this->ogreWindowEventListener_->windowResized(renderWindow_);
+
+        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_.get());
+
+        // create a full screen default viewport
+        // Note: This may throw when adding a viewport with an existing z-order!
+        //       But in our case we only have one viewport for now anyway, therefore
+        //       no ScopeGuards or anything to handle exceptions.
+        this->viewport_ = this->renderWindow_->addViewport(0, 0);
+
+        Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);
+
+        // add console commands
+        FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
+        ccPrintScreen_ = createConsoleCommand(functor1->setObject(this), "printScreen");
+        CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
+    }
+
     void GraphicsManager::update(const Clock& time)
     {
@@ -207,165 +352,4 @@
     {
         this->viewport_->setCamera(camera);
-    }
-
-    /**
-    @brief
-        Creates the Ogre Root object and sets up the ogre log.
-    */
-    void GraphicsManager::setupOgre()
-    {
-        COUT(3) << "Setting up Ogre..." << std::endl;
-
-        if (ogreConfigFile_ == "")
-        {
-            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
-            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
-        }
-        if (ogreLogFile_ == "")
-        {
-            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
-            ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
-        }
-
-        boost::filesystem::path ogreConfigFilepath(Core::getConfigPath() / this->ogreConfigFile_);
-        boost::filesystem::path ogreLogFilepath(Core::getLogPath() / this->ogreLogFile_);
-
-        // create a new logManager
-        // Ogre::Root will detect that we've already created a Log
-        std::auto_ptr<Ogre::LogManager> logger(new Ogre::LogManager());
-        COUT(4) << "Ogre LogManager created" << std::endl;
-
-        // create our own log that we can listen to
-        Ogre::Log *myLog;
-        myLog = logger->createLog(ogreLogFilepath.string(), true, false, false);
-        COUT(4) << "Ogre Log created" << std::endl;
-
-        myLog->setLogDetail(Ogre::LL_BOREME);
-        myLog->addListener(this);
-
-        COUT(4) << "Creating Ogre Root..." << std::endl;
-
-        // check for config file existence because Ogre displays (caught) exceptions if not
-        if (!boost::filesystem::exists(ogreConfigFilepath))
-        {
-            // create a zero sized file
-            std::ofstream creator;
-            creator.open(ogreConfigFilepath.string().c_str());
-            creator.close();
-        }
-
-        // Leave plugins file empty. We're going to do that part manually later
-        ogreRoot_ = new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string());
-        // In case that new Root failed the logger gets destroyed because of the std::auto_ptr
-        ogreLogger_ = logger.release();
-
-        COUT(3) << "Ogre set up done." << std::endl;
-    }
-
-    void GraphicsManager::loadOgrePlugins()
-    {
-        // just to make sure the next statement doesn't segfault
-        if (ogrePluginsFolder_ == "")
-            ogrePluginsFolder_ = ".";
-
-        boost::filesystem::path folder(ogrePluginsFolder_);
-        // Do some SubString magic to get the comma separated list of plugins
-        SubString plugins(ogrePlugins_, ",", " ", false, '\\', false, '"', false, '(', ')', false, '\0');
-        // Use backslash paths on Windows! file_string() already does that though.
-        for (unsigned int i = 0; i < plugins.size(); ++i)
-            ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
-    }
-
-    void GraphicsManager::declareResources()
-    {
-        CCOUT(4) << "Declaring Resources" << std::endl;
-        //TODO: Specify layout of data file and maybe use xml-loader
-        //TODO: Work with ressource groups (should be generated by a special loader)
-
-        if (resourceFile_ == "")
-        {
-            COUT(2) << "Warning: Ogre resource file set to \"\". Defaulting to resources.cfg" << std::endl;
-            ModifyConfigValue(resourceFile_, tset, "resources.cfg");
-        }
-
-        // Load resource paths from data file using configfile ressource type
-        Ogre::ConfigFile cf;
-        try
-        {
-            cf.load((Core::getMediaPath() / resourceFile_).string());
-        }
-        catch (...)
-        {
-            //COUT(1) << ex.getFullDescription() << std::endl;
-            COUT(0) << "Have you forgotten to set the data path in orxnox.ini?" << std::endl;
-            throw;
-        }
-
-        // Go through all sections & settings in the file
-        Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
-
-        std::string secName, typeName, archName;
-        while (seci.hasMoreElements())
-        {
-            try
-            {
-                secName = seci.peekNextKey();
-                Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
-                Ogre::ConfigFile::SettingsMultiMap::iterator i;
-                for (i = settings->begin(); i != settings->end(); ++i)
-                {
-                    typeName = i->first; // for instance "FileSystem" or "Zip"
-                    archName = i->second; // name (and location) of archive
-
-                    Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
-                        (Core::getMediaPath() / archName).string(), typeName, secName);
-                }
-            }
-            catch (Ogre::Exception& ex)
-            {
-                COUT(1) << ex.getFullDescription() << std::endl;
-            }
-        }
-    }
-
-    void GraphicsManager::loadRenderer()
-    {
-        CCOUT(4) << "Configuring Renderer" << std::endl;
-
-        if (!ogreRoot_->restoreConfig())
-            if (!ogreRoot_->showConfigDialog())
-                ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
-
-        CCOUT(4) << "Creating render window" << std::endl;
-
-        this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
-        this->ogreWindowEventListener_->windowResized(renderWindow_);
-
-        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
-
-        Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);
-
-        // create a full screen default viewport
-        this->viewport_ = this->renderWindow_->addViewport(0, 0);
-    }
-
-    void GraphicsManager::initialiseResources()
-    {
-        CCOUT(4) << "Initialising resources" << std::endl;
-        //TODO: Do NOT load all the groups, why are we doing that? And do we really do that? initialise != load...
-        //try
-        //{
-            Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
-            /*Ogre::StringVector str = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
-            for (unsigned int i = 0; i < str.size(); i++)
-            {
-            Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(str[i]);
-            }*/
-        //}
-        //catch (...)
-        //{
-        //    CCOUT(2) << "Error: There was a serious error when initialising the resources." << std::endl;
-        //    throw;
-        //}
     }
 
@@ -406,4 +390,28 @@
     }
 
+    size_t GraphicsManager::getRenderWindowHandle()
+    {
+        size_t windowHnd = 0;
+        renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
+        return windowHnd;
+    }
+
+    bool GraphicsManager::isFullScreen() 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;
+        }
+        else
+        {
+            COUT(0) << "Could not find 'Full Screen' render system option. Fix This!!!" << std::endl;
+            return false;
+        }
+    }
+
     void GraphicsManager::printScreen()
     {
Index: code/trunk/src/core/GraphicsManager.h
===================================================================
--- code/trunk/src/core/GraphicsManager.h	(revision 5693)
+++ code/trunk/src/core/GraphicsManager.h	(revision 5695)
@@ -42,4 +42,7 @@
 #include <string>
 #include <OgreLog.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
 #include "util/Singleton.h"
 #include "OrxonoxClass.h"
@@ -55,5 +58,5 @@
         friend class Singleton<GraphicsManager>;
     public:
-        GraphicsManager();
+        GraphicsManager(bool bLoadRenderer = true);
         ~GraphicsManager();
 
@@ -62,8 +65,11 @@
         void update(const Clock& time);
 
-        inline Ogre::Viewport* getViewport()
-            { return this->viewport_; }
-        inline Ogre::RenderWindow* getRenderWindow()
-            { return this->renderWindow_; }
+        Ogre::Viewport* getViewport()         { return this->viewport_; }
+        Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
+        size_t getRenderWindowHandle();
+        bool isFullScreen() const;
+
+        void upgradeToGraphics();
+        bool rendererLoaded() const { return renderWindow_ != NULL; }
 
         void setCamera(Ogre::Camera* camera);
@@ -73,9 +79,7 @@
 
         // OGRE initialisation
-        void setupOgre();
+        void loadOgreRoot();
         void loadOgrePlugins();
-        void declareResources();
         void loadRenderer();
-        void initialiseResources();
 
         // event from Ogre::LogListener
@@ -86,15 +90,20 @@
         void printScreen();
 
-    private:
-        Ogre::Root*         ogreRoot_;                 //!< Ogre's root
-        Ogre::LogManager*   ogreLogger_;
+        scoped_ptr<OgreWindowEventListener> ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
+#if OGRE_VERSION < 0x010600
+        scoped_ptr<MemoryArchiveFactory>    memoryArchiveFactory_;    //!< Stores the modified particle scripts
+#endif
+        scoped_ptr<Ogre::LogManager>        ogreLogger_;
+        scoped_ptr<Ogre::Root>              ogreRoot_;                //!< Ogre's root
         Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
         Ogre::Viewport*     viewport_;                 //!< default full size viewport
-        OgreWindowEventListener* ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
+
+        // XML files for the resources
+        shared_ptr<XMLFile> resources_;                //!< XML with resource locations
+        shared_ptr<XMLFile> extResources_;             //!< XML with resource locations in the external path (only for dev runs)
 
         // config values
-        std::string         resourceFile_;             //!< resources file name
         std::string         ogreConfigFile_;           //!< ogre config file name
-        std::string         ogrePluginsFolder_;        //!< Folder where the Ogre plugins are located
+        std::string         ogrePluginsDirectory_;     //!< Directory where the Ogre plugins are located
         std::string         ogrePlugins_;              //!< Comma separated list of all plugins to load
         std::string         ogreLogFile_;              //!< log file name for Ogre log messages
Index: code/trunk/src/core/Identifier.cc
===================================================================
--- code/trunk/src/core/Identifier.cc	(revision 5693)
+++ code/trunk/src/core/Identifier.cc	(revision 5695)
@@ -138,5 +138,5 @@
         if (!this->bCreatedOneObject_ && Identifier::isCreatingHierarchy())
         {
-            // If no: We have to store the informations and initialize the Identifier
+            // If no: We have to store the information and initialize the Identifier
             COUT(4) << "*** ClassIdentifier: Register Class in " << this->getName() << "-Singleton -> Initialize Singleton." << std::endl;
             if (bRootClass)
Index: code/trunk/src/core/Identifier.h
===================================================================
--- code/trunk/src/core/Identifier.h	(revision 5693)
+++ code/trunk/src/core/Identifier.h	(revision 5695)
@@ -31,5 +31,5 @@
     @brief Definition of the Identifier, ClassIdentifier and SubclassIdentifier classes, implementation of the ClassIdentifier and SubclassIdentifier classes.
 
-    The Identifier contains all needed informations about the class it belongs to:
+    The Identifier contains all needed information about the class it belongs to:
      - the name
      - a list with all objects
@@ -73,7 +73,7 @@
     // ###       Identifier        ###
     // ###############################
-    //! The Identifier is used to identify the class of an object and to store informations about the class.
-    /**
-        The Identifier contains all needed informations about the class it belongs to:
+    //! The Identifier is used to identify the class of an object and to store information about the class.
+    /**
+        The Identifier contains all needed information about the class it belongs to:
          - the name
          - a list with all objects
@@ -335,5 +335,5 @@
     /**
         ClassIdentifier is a Singleton, which means that only one object of a given type T exists.
-        This makes it possible to store informations about a class, sharing them with all
+        This makes it possible to store information about a class, sharing them with all
         objects of that class without defining static variables in every class.
 
Index: code/trunk/src/core/Loader.cc
===================================================================
--- code/trunk/src/core/Loader.cc	(revision 5693)
+++ code/trunk/src/core/Loader.cc	(revision 5695)
@@ -29,13 +29,17 @@
 #include "Loader.h"
 
+#include <sstream>
 #include <tinyxml/ticpp.h>
+#include <boost/scoped_ptr.hpp>
 
 #include "util/Debug.h"
 #include "util/Exception.h"
+#include "util/StringUtils.h"
 #include "BaseObject.h"
 #include "Iterator.h"
 #include "ObjectList.h"
-#include "LuaBind.h"
+#include "LuaState.h"
 #include "Namespace.h"
+#include "Resource.h"
 #include "XMLFile.h"
 
@@ -118,9 +122,23 @@
         Loader::currentMask_s = file->getMask() * mask;
 
-        // let Lua work this out:
-        LuaBind& lua = LuaBind::getInstance();
-        lua.clearLuaOutput();
-        lua.loadFile(file->getFilename(), true);
-        lua.run();
+        std::string xmlInput;
+        if (file->getLuaSupport())
+        {
+            // Use the LuaState to replace the XML tags (calls our function)
+            scoped_ptr<LuaState> luaState(new LuaState());
+            luaState->setIncludeParser(&Loader::replaceLuaTags);
+            luaState->includeFile(file->getFilename(), file->getResourceGroup(), false);
+            xmlInput = luaState->getOutput().str();
+        }
+        else
+        {
+            shared_ptr<ResourceInfo> info = Resource::getInfo(file->getFilename(), file->getResourceGroup());
+            if (info == NULL)
+            {
+                COUT(1) << "Error: Could not find XML file '" << file->getFilename() << "'." << std::endl;
+                return false;
+            }
+            xmlInput = Resource::open(file->getFilename(), file->getResourceGroup())->getAsString();
+        }
 
         try
@@ -129,10 +147,6 @@
             COUT(3) << "Mask: " << Loader::currentMask_s << std::endl;
 
-            //ticpp::Document xmlfile(file->getFilename());
-            //xmlfile.LoadFile();
-            //ticpp::Element myelement(*Script::getFileString());
-            ticpp::Document xmlfile;
-            //xmlfile.ToDocument();
-            xmlfile.Parse(lua.getLuaOutput(), true);
+            ticpp::Document xmlfile(file->getFilename());
+            xmlfile.Parse(xmlInput, true);
 
             ticpp::Element rootElement;
@@ -208,3 +222,154 @@
         return Loader::load(file, mask);
     }
+
+    std::string Loader::replaceLuaTags(const std::string& text)
+    {
+        // chreate map with all Lua tags
+        std::map<size_t, bool> luaTags;
+        {
+            size_t pos = 0;
+            while ((pos = text.find("<?lua", pos)) != std::string::npos)
+                luaTags[pos++] = true;
+        }
+        {
+            size_t pos = 0;
+            while ((pos = text.find("?>", pos)) != std::string::npos)
+                luaTags[pos++] = false;
+        }
+
+        // erase all tags from the map that are between two quotes
+        {
+            std::map<size_t, bool>::iterator it = luaTags.begin();
+            std::map<size_t, bool>::iterator it2 = it;
+            bool bBetweenQuotes = false;
+            size_t pos = 0;
+            while ((pos = getNextQuote(text, pos)) != std::string::npos)
+            {
+                while ((it != luaTags.end()) && (it->first < pos))
+                {
+                    if (bBetweenQuotes)
+                    {
+                        it2++;
+                        if(it->second && !(it2->second) && it2->first < pos)
+                            it = ++it2;
+                        else
+                            luaTags.erase(it++);
+                    }
+                    else
+                        ++it;
+                }
+                bBetweenQuotes = !bBetweenQuotes;
+                pos++;
+            }
+        }
+
+        // check whether on every opening <?lua tag a closing ?> tag follows
+        {
+            bool expectedValue = true;
+            for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
+            {
+                if (it->second == expectedValue)
+                    expectedValue = !expectedValue;
+                else
+                {
+                    expectedValue = false;
+                    break;
+                }
+            }
+            if (!expectedValue)
+            {
+                COUT(2) << "Warning: Error in level file" << std::endl;
+                // todo: errorhandling
+                return "";
+            }
+        }
+
+        // Use a stringstream object to speed up the parsing
+        std::ostringstream output;
+
+        // cut the original string into pieces and put them together with print() instead of lua tags
+        {
+            std::map<size_t, bool>::iterator it = luaTags.begin();
+            bool bInPrintFunction = true;
+            size_t start = 0;
+            size_t end = 0;
+
+            do
+            {
+                if (it != luaTags.end())
+                    end = (*(it++)).first;
+                else
+                    end = std::string::npos;
+
+                unsigned int equalSignCounter = 0;
+
+                if (bInPrintFunction)
+                {
+                    // count ['='[ and ]'='] and replace tags with print([[ and ]])
+                    std::string temp = text.substr(start, end - start);
+                    {
+                    size_t pos = 0;
+                    while ((pos = temp.find('[', pos)) != std::string::npos)
+                    {
+                        unsigned int tempCounter = 1;
+                        size_t tempPos = pos++;
+                        while(temp[++tempPos] == '=')
+                        {
+                            tempCounter++;
+                        }
+                        if(temp[tempPos] != '[')
+                        {
+                            tempCounter = 0;
+                        }
+                        else if(tempCounter == 0)
+                        {
+                            tempCounter = 1;
+                        }
+                        if (tempCounter > equalSignCounter)
+                            equalSignCounter = tempCounter;
+                        }
+                    }
+                    {
+                        size_t pos = 0;
+                        while ((pos = temp.find(']', pos)) != std::string::npos)
+                        {
+                            unsigned int tempCounter = 1;
+                            size_t tempPos = pos++;
+                            while(temp[++tempPos] == '=')
+                            {
+                                tempCounter++;
+                            }
+                            if(temp[tempPos] != ']')
+                            {
+                                tempCounter = 0;
+                            }
+                            else if(tempCounter == 0)
+                            {
+                                tempCounter = 1;
+                            }
+                            if (tempCounter > equalSignCounter)
+                                equalSignCounter = tempCounter;
+                        }
+                    }
+                    std::string equalSigns = "";
+                    for(unsigned int i = 0; i < equalSignCounter; i++)
+                    {
+                        equalSigns += "=";
+                    }
+                    output << "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
+                    start = end + 5;
+                }
+                else
+                {
+                    output << text.substr(start, end - start);
+                    start = end + 2;
+                }
+
+                bInPrintFunction = !bInPrintFunction;
+            }
+            while (end != std::string::npos);
+        }
+
+        return output.str();
+    }
 }
Index: code/trunk/src/core/Loader.h
===================================================================
--- code/trunk/src/core/Loader.h	(revision 5693)
+++ code/trunk/src/core/Loader.h	(revision 5695)
@@ -55,4 +55,6 @@
             static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
 
+            static std::string replaceLuaTags(const std::string& text);
+
             static ClassTreeMask currentMask_s;
 
Index: code/trunk/src/core/LuaBind.cc
===================================================================
--- code/trunk/src/core/LuaBind.cc	(revision 5693)
+++ 	(revision )
@@ -1,343 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Benjamin Knecht
- *   Co-authors:
- *      ...
- *
- */
-
-#include "LuaBind.h"
-
-#include <fstream>
-#include <map>
-extern "C" {
-#include <lualib.h>
-}
-#include <tolua/tolua++.h>
-#include <boost/filesystem.hpp>
-
-#include "util/Debug.h"
-#include "util/StringUtils.h"
-#include "Core.h"
-
-namespace orxonox
-{
-  LuaBind* LuaBind::singletonPtr_s = NULL;
-
-  LuaBind::LuaBind()
-  {
-    this->includePath_ = Core::getMediaPathString();
-
-    luaState_ = lua_open();
-    luaSource_ = "";
-#if LUA_VERSION_NUM == 501
-    luaL_openlibs(luaState_);
-#else
-    luaopen_base(luaState_);
-    luaopen_string(luaState_);
-    luaopen_table(luaState_);
-    luaopen_math(luaState_);
-    luaopen_io(luaState_);
-    luaopen_debug(luaState_);
-#endif
-
-    // Open all available tolua interfaces
-    this->openToluaInterfaces(luaState_);
-
-    output_ = "";
-    isRunning_ = false;
-  }
-
-  LuaBind::~LuaBind()
-  {
-    this->closeToluaInterfaces(luaState_);
-  };
-
-  void LuaBind::luaPrint(const std::string& str)
-  {
-    output_ += str;
-//    COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
-    COUT(5) << str;
-  }
-
-  /**
-      @brief Loads the specified file line by line
-      @param filename The filename of the file
-      @param luaTags if true, the loaded file gets stripped off luaTags
-  */
-  void LuaBind::loadFile(const std::string& filename, bool luaTags)
-  {
-    boost::filesystem::path filepath(filename);
-
-    output_ = "";
-    std::ifstream file;
-    file.open(filepath.string().c_str(), std::fstream::in);
-
-    if (!file.is_open())
-    {
-      // some error msg
-    }
-
-    std::string levelString = "";
-
-    while (file.good() && !file.eof())
-    {
-      std::string line;
-      std::getline(file, line);
-      levelString += line;
-      levelString += "\n";
-    }
-
-    file.close();
-    //std::string output;
-
-    if (luaTags)
-      luaSource_ = replaceLuaTags(levelString);
-    else
-      luaSource_ = levelString;
-    COUT(5) << "ParsedSourceCode: " << luaSource_ << std::endl;
-  }
-
-  void LuaBind::loadString(const std::string& code)
-  {
-    luaSource_ = code;
-    output_ = "";
-  }
-
-#if LUA_VERSION_NUM != 501
-  const char * LuaBind::lua_Chunkreader(lua_State *L, void *data, size_t *size)
-  {
-    LoadS* ls = static_cast<LoadS*>(data);
-    if (ls->size == 0) return NULL;
-    *size = ls->size;
-    ls->size = 0;
-    return ls->s;
-  }
-#endif
-  void LuaBind::run()
-  {
-    if (!isRunning_)
-    {
-      isRunning_ = true;
-      int error = 0;
-      std::string init =
-         "local scr = orxonox.LuaBind:getInstance()\n \
-          local debug = print\n \
-          print = function(s)\n \
-              scr:luaPrint(s)\n \
-          end\n \
-          include = function(f)\n \
-              file = assert(io.open(\"" + this->includePath_ + "\"..\"/\"..f))\n \
-              content = file:read(\"*a\")\n \
-              file:close()\n \
-              source = scr:replaceLuaTags(content)\n \
-              assert(loadstring(source))()\n \
-          end\n";
-      init += luaSource_;
-  #if LUA_VERSION_NUM == 501
-      error = luaL_loadstring(luaState_, init.c_str());
-  #else
-      LoadS ls;
-      ls.s = init.c_str();
-      ls.size = init.size();
-      error = lua_load(luaState_, &orxonox::LuaBind::lua_Chunkreader, &ls, init.c_str());
-  #endif
-      if (error == 0)
-      {
-        error = lua_pcall(luaState_, 0, 0, 0);
-      }
-      if (error != 0)
-      {
-        COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
-      }
-      isRunning_ = false;
-    }
-    else
-    {
-      COUT(2) << "Warning: Lua's run is called while running!" << std::endl;
-    }
-  }
-
-  std::string LuaBind::replaceLuaTags(const std::string& text)
-  {
-    // chreate map with all Lua tags
-    std::map<size_t, bool> luaTags;
-    {
-      size_t pos = 0;
-      while ((pos = text.find("<?lua", pos)) != std::string::npos)
-        luaTags[pos++] = true;
-    }
-    {
-      size_t pos = 0;
-      while ((pos = text.find("?>", pos)) != std::string::npos)
-        luaTags[pos++] = false;
-    }
-
-    // erase all tags from the map that are between two quotes
-    {
-      std::map<size_t, bool>::iterator it = luaTags.begin();
-      std::map<size_t, bool>::iterator it2 = it;
-      bool bBetweenQuotes = false;
-      size_t pos = 0;
-      while ((pos = getNextQuote(text, pos)) != std::string::npos)
-      {
-        while ((it != luaTags.end()) && (it->first < pos))
-        {
-          if (bBetweenQuotes) {
-            it2++;
-            if(it->second && !(it2->second) && it2->first < pos)
-              it = ++it2;
-            else
-              luaTags.erase(it++);
-          }
-          else
-            ++it;
-        }
-        bBetweenQuotes = !bBetweenQuotes;
-        pos++;
-      }
-    }
-
-    // check whether on every opening <?lua tag a closing ?> tag follows
-    {
-      bool expectedValue = true;
-      for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
-      {
-        if (it->second == expectedValue)
-          expectedValue = !expectedValue;
-        else
-        {
-          expectedValue = false;
-          break;
-        }
-      }
-      if (!expectedValue) {
-        COUT(2) << "Warning: Error in level file" << std::endl;
-        // todo: errorhandling
-        return "";
-      }
-    }
-
-    // cut the original string into pieces and put them together with print() instead of lua tags
-    std::string output;
-    {
-      std::map<size_t, bool>::iterator it = luaTags.begin();
-      bool bInPrintFunction = true;
-      size_t start = 0;
-      size_t end = 0;
-
-      do
-      {
-        if (it != luaTags.end())
-          end = (*(it++)).first;
-        else
-          end = std::string::npos;
-
-        unsigned int equalSignCounter = 0;
-
-        if (bInPrintFunction)
-        {
-          // count ['='[ and ]'='] and replace tags with print([[ and ]])
-          std::string temp = text.substr(start, end - start);
-          {
-            size_t pos = 0;
-            while ((pos = temp.find('[', pos)) != std::string::npos)
-            {
-              unsigned int tempCounter = 1;
-              size_t tempPos = pos++;
-              while(temp[++tempPos] == '=') {
-                tempCounter++;
-              }
-              if(temp[tempPos] != '[') {
-                tempCounter = 0;
-              }
-              else if(tempCounter == 0) {
-                tempCounter = 1;
-              }
-              if (tempCounter > equalSignCounter)
-                equalSignCounter = tempCounter;
-            }
-          }
-          {
-            size_t pos = 0;
-            while ((pos = temp.find(']', pos)) != std::string::npos)
-            {
-              unsigned int tempCounter = 1;
-              size_t tempPos = pos++;
-              while(temp[++tempPos] == '=') {
-                tempCounter++;
-              }
-              if(temp[tempPos] != ']') {
-                tempCounter = 0;
-              }
-              else if(tempCounter == 0) {
-                tempCounter = 1;
-              }
-              if (tempCounter > equalSignCounter)
-                equalSignCounter = tempCounter;
-            }
-          }
-          std::string equalSigns = "";
-          for(unsigned int i = 0; i < equalSignCounter; i++) {
-            equalSigns += "=";
-          }
-          output += "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
-          start = end + 5;
-        }
-        else
-        {
-          output += text.substr(start, end - start);
-          start = end + 2;
-        }
-
-        bInPrintFunction = !bInPrintFunction;
-      }
-      while (end != std::string::npos);
-    }
-
-    return output;
-  }
-
-  void LuaBind::addToluaInterface(int (*function)(lua_State*), const std::string& name)
-  {
-    toluaInterfaces_.push_back(std::make_pair(name, function));
-    // Apply changes to our own lua state as well 
-    (*function)(luaState_);
-  }
-
-  void LuaBind::openToluaInterfaces(lua_State* state)
-  {
-    for (unsigned int i = 0; i < toluaInterfaces_.size(); ++i)
-      (*toluaInterfaces_[i].second)(state);
-  }
-
-  void LuaBind::closeToluaInterfaces(lua_State* state)
-  {
-    for (unsigned int i = 0; i < toluaInterfaces_.size(); ++i)
-    {
-      lua_pushnil(state);
-      lua_setglobal(state, toluaInterfaces_[i].first.c_str());
-    }
-  }
-
-}
Index: code/trunk/src/core/LuaBind.h
===================================================================
--- code/trunk/src/core/LuaBind.h	(revision 5693)
+++ 	(revision )
@@ -1,105 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Benjamin Knecht
- *   Co-authors:
- *      ...
- *
- */
-
-/**
- @file
- @brief Representation of an interface to lua
- @author Benjamin Knecht <beni_at_orxonox.net>
- */
-
-#ifndef _LuaBind_H__
-#define _LuaBind_H__
-
-#include "CorePrereqs.h"
-
-#include <cassert>
-#include <string>
-#include <vector>
-extern "C" {
-#include <lua.h>
-}
-
-#include "util/Singleton.h"
-
-// tolua_begin
-namespace orxonox
-{
-  class _CoreExport LuaBind : public Singleton<LuaBind>
-  {
-// tolua_end
-    friend class Singleton<LuaBind>;
-
-    struct LoadS {
-      const char *s;
-      size_t size;
-    };
-
-    public:
-      LuaBind();
-      ~LuaBind();
-
-      static LuaBind& getInstance() { return Singleton<LuaBind>::getInstance(); } // tolua_export
-
-    void loadFile(const std::string& filename, bool luaTags);
-    void loadString(const std::string& code);
-    //void init(lua_State *state_);
-    //void xmlToLua();
-    void run();
-    void luaPrint(const std::string& str); // tolua_export
-
-#if LUA_VERSION_NUM != 501
-    static const char * lua_Chunkreader(lua_State *L, void *data, size_t *size);
-#endif
-
-    inline lua_State* getLuaState() { return luaState_; };
-    inline const std::string& getLuaOutput() { return output_; };
-    //inline std::string* getFileString() { return &fileString_; };
-    inline void clearLuaOutput() { output_ = ""; }
-
-    std::string replaceLuaTags(const std::string& text); // tolua_export
-
-    inline void setIncludePath(const std::string& includepath)
-        { this->includePath_ = includepath; }
-
-    void addToluaInterface(int (*function)(lua_State*), const std::string& name);
-    void openToluaInterfaces(lua_State* state);
-    void closeToluaInterfaces(lua_State* state);
-
-    private:
-      static LuaBind* singletonPtr_s;
-
-      std::string luaSource_;
-      std::string output_;
-      lua_State* luaState_;
-      bool isRunning_;
-      std::string includePath_;
-      std::vector<std::pair<std::string, int (*)(lua_State *L)> > toluaInterfaces_;
-
-  }; // tolua_export
-} // tolua_export
-#endif /* _LuaBind_H__ */
Index: code/trunk/src/core/LuaState.cc
===================================================================
--- code/trunk/src/core/LuaState.cc	(revision 5695)
+++ code/trunk/src/core/LuaState.cc	(revision 5695)
@@ -0,0 +1,266 @@
+/*
+ *   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:
+ *      Benjamin Knecht
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LuaState.h"
+
+#include <tolua/tolua++.h>
+extern "C" {
+#include <lua.h>
+#include <lualib.h>
+}
+
+#include "util/Debug.h"
+#include "Core.h"
+#include "Resource.h"
+#include "ToluaBindCore.h"
+
+namespace orxonox
+{
+    LuaState::ToluaInterfaceMap LuaState::toluaInterfaces_s;
+    std::vector<LuaState*> LuaState::instances_s;
+
+    // Do this after declaring toluaInterfaces_s and instances_s to avoid larger problems
+    DeclareToluaInterface(Core);
+
+    LuaState::LuaState()
+        : bIsRunning_(false)
+        , includeParseFunction_(NULL)
+    {
+        // Create new lua state and configure it
+        luaState_ = lua_open();
+#if LUA_VERSION_NUM == 501
+        luaL_openlibs(luaState_);
+#else
+        luaopen_base(luaState_);
+        luaopen_string(luaState_);
+        luaopen_table(luaState_);
+        luaopen_math(luaState_);
+        luaopen_io(luaState_);
+        luaopen_debug(luaState_);
+#endif
+
+        // Open all available tolua interfaces
+        this->openToluaInterfaces(luaState_);
+
+        // Create dummy file info
+        sourceFileInfo_.reset(new ResourceInfo());
+        sourceFileInfo_->group = "General";
+        sourceFileInfo_->size = 0;
+
+        // Push this pointer
+        tolua_pushusertype(luaState_, static_cast<void*>(this), "orxonox::LuaState");
+        lua_setglobal(luaState_, "luaState");
+
+        // Parse init script
+        this->doFile("LuaStateInit.lua");
+    }
+
+    LuaState::~LuaState()
+    {
+        lua_close(luaState_);
+    }
+
+    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> sourceInfo;
+        if (resourceGroup != "NoResourceGroupProvided")
+            sourceInfo = Resource::getInfo(filename, resourceGroup);
+
+        // Continue search if not explicitely forbidden
+        if (bSearchOtherPaths && sourceInfo == NULL)
+        {
+            // Call might be relative to the file currently being processed
+            sourceInfo = Resource::getInfo(sourceFileInfo_->path + filename, sourceFileInfo_->group);
+            if (sourceInfo == NULL)
+            {
+                // Maybe find something in the same group but in the root path
+                sourceInfo = Resource::getInfo(filename, sourceFileInfo_->group);
+            }
+        }
+        return sourceInfo;
+    }
+
+    void LuaState::includeFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
+        if (sourceInfo != NULL)
+            this->includeString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
+        else
+            COUT(2) << "LuaState: Cannot include file '" << filename << "' in resource group '"
+                    << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
+    }
+
+    void LuaState::includeString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo)
+    {
+        // Parse string with provided include parser (otherwise don't preparse at all)
+        std::string luaInput;
+        if (includeParseFunction_ != NULL)
+            luaInput = (*includeParseFunction_)(code);
+        else
+            luaInput = code;
+
+        this->doString(luaInput, sourceFileInfo);
+    }
+
+    void LuaState::doFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
+        if (sourceInfo != NULL)
+            this->doString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
+        else
+            COUT(2) << "LuaState: Cannot do file '" << filename << "' in resource group '"
+                << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
+    }
+
+    void LuaState::doString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo)
+    {
+        // Save the oold source file info
+        shared_ptr<ResourceInfo> oldSourceFileInfo = sourceFileInfo_;
+        // Only override if sourceFileInfo provides useful information
+        if (sourceFileInfo != NULL)
+            sourceFileInfo_ = sourceFileInfo;
+
+        int error = 0;
+#if LUA_VERSION_NUM != 501
+        LoadS ls;
+        ls.s = code.c_str();
+        ls.size = code.size();
+        error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, code.c_str());
+#else
+        error = luaL_loadstring(luaState_, code.c_str());
+#endif
+
+        // execute the chunk
+        if (error == 0)
+            error = lua_pcall(luaState_, 0, 1, 0);
+        if (error != 0)
+        {
+            std::string origin;
+            if (sourceFileInfo != NULL)
+                origin = " originating from " + sourceFileInfo_->filename;
+            COUT(2) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
+            // return value is nil
+            lua_pushnil(luaState_);
+        }
+        // push return value because it will get lost since the return value of this function is void
+        lua_setglobal(luaState_, "LuaStateReturnValue");
+
+        // Load the old info again
+        sourceFileInfo_ = oldSourceFileInfo;
+    }
+
+    void LuaState::luaPrint(const std::string& str)
+    {
+        output_ << str;
+    }
+
+    void LuaState::luaLog(unsigned int level, const std::string& message)
+    {
+        OutputHandler::getOutStream().setOutputLevel(level) << message << std::endl;
+    }
+
+    bool LuaState::fileExists(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
+    {
+        shared_ptr<ResourceInfo> info =  this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
+        if (info == NULL)
+            return false;
+        else
+            return true;
+    }
+
+#if LUA_VERSION_NUM != 501
+    const char * LuaState::lua_Chunkreader(lua_State *L, void *data, size_t *size)
+    {
+        LoadS* ls = static_cast<LoadS*>(data);
+        if (ls->size == 0)
+            return NULL;
+        *size = ls->size;
+        ls->size = 0;
+        return ls->s;
+    }
+#endif
+
+    /*static*/ bool LuaState::addToluaInterface(int (*function)(lua_State*), const std::string& name)
+    {
+        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
+        {
+            if (it->first == name || it->second == function)
+            {
+                COUT(2) << "Warning: Trying to add a Tolua interface with the same name or function." << std::endl;
+                return true;
+            }
+        }
+        toluaInterfaces_s[name] = function;
+
+        // Open interface in all LuaStates
+        for (std::vector<LuaState*>::const_iterator it = instances_s.begin(); it != instances_s.end(); ++it)
+            (*function)((*it)->luaState_);
+
+        // Return dummy bool
+        return true;
+    }
+
+    /*static*/ bool LuaState::removeToluaInterface(const std::string& name)
+    {
+        ToluaInterfaceMap::iterator it = toluaInterfaces_s.find(name);
+        if (it == toluaInterfaces_s.end())
+        {
+            COUT(2) << "Warning: Cannot remove Tolua interface '" << name << "': Not found" << std::endl;
+            return true;
+        }
+
+        // Close interface in all LuaStates
+        for (std::vector<LuaState*>::const_iterator itState = instances_s.begin(); itState != instances_s.end(); ++itState)
+        {
+            lua_pushnil((*itState)->luaState_);
+            lua_setglobal((*itState)->luaState_, it->first.c_str());
+        }
+
+        // Remove entry
+        toluaInterfaces_s.erase(it);
+
+        // Return dummy bool
+        return true;
+    }
+
+    /*static*/ void LuaState::openToluaInterfaces(lua_State* state)
+    {
+        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
+            (*it->second)(state);
+    }
+
+    /*static*/ void LuaState::closeToluaInterfaces(lua_State* state)
+    {
+        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
+        {
+            lua_pushnil(state);
+            lua_setglobal(state, it->first.c_str());
+        }
+    }
+}
Index: code/trunk/src/core/LuaState.h
===================================================================
--- code/trunk/src/core/LuaState.h	(revision 5695)
+++ code/trunk/src/core/LuaState.h	(revision 5695)
@@ -0,0 +1,104 @@
+/*
+ *   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:
+ *      Benjamin Knecht
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LuaState_H__
+#define _LuaState_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include "util/ScopeGuard.h"
+#include "ToluaInterface.h"
+
+// tolua_begin
+namespace orxonox
+{
+    /**
+    @brief
+        Representation of an interface to lua
+    */
+    class _CoreExport LuaState
+    {
+// tolua_end
+    public:
+        LuaState();
+        ~LuaState();
+
+        void doFile(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
+        void doString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo = shared_ptr<ResourceInfo>());
+
+        void includeFile(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
+        void includeString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo = shared_ptr<ResourceInfo>());
+
+        void luaPrint(const std::string& str); // tolua_export
+        void luaLog(unsigned int level, const std::string& message); // tolua_export
+        bool fileExists(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
+
+        const std::stringstream& getOutput() const { return output_; }
+        void clearOutput() { output_.clear(); } // tolua_export
+
+        void setIncludeParser(std::string (*function)(const std::string&)) { includeParseFunction_ = function; }
+        lua_State* getInternalLuaState() { return luaState_; }
+
+        static bool addToluaInterface(int (*function)(lua_State*), const std::string& name);
+        static bool removeToluaInterface(const std::string& name);
+        static void openToluaInterfaces(lua_State* state);
+        static void closeToluaInterfaces(lua_State* state);
+
+    private:
+        shared_ptr<ResourceInfo> getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths);
+
+#if LUA_VERSION_NUM != 501
+        struct LoadS
+        {
+            const char* s;
+            size_t size;
+        };
+
+        static const char * lua_Chunkreader(lua_State *L, void *data, size_t *size);
+#endif
+
+        std::stringstream output_;
+        lua_State* luaState_;
+        bool bIsRunning_;
+        shared_ptr<ResourceInfo> sourceFileInfo_;
+        std::string (*includeParseFunction_)(const std::string&);
+
+        typedef std::map<std::string, int (*)(lua_State *L)> ToluaInterfaceMap;
+        static ToluaInterfaceMap toluaInterfaces_s;
+        static std::vector<LuaState*> instances_s;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _LuaState_H__ */
Index: code/trunk/src/core/MemoryArchive.cc
===================================================================
--- code/trunk/src/core/MemoryArchive.cc	(revision 5695)
+++ code/trunk/src/core/MemoryArchive.cc	(revision 5695)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MemoryArchive.h"
+
+#if OGRE_VERSION < 0x010600
+
+#include <OgreException.h>
+#include <boost/filesystem.hpp>
+
+namespace orxonox
+{
+    using namespace Ogre;
+
+    MemoryArchive::ArchiveMap MemoryArchive::archives_s;
+
+    void MemoryArchive::load()
+    {
+        if (archives_s.find(this->getName()) == archives_s.end())
+            OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, this->getName() + " - MemoryArchive not found.", "MemoryArchive");
+    }
+
+    DataStreamPtr MemoryArchive::open(const String& filename) const
+    {
+        const FileMap& files = archives_s[this->getName()];
+        FileMap::const_iterator itFile = files.find(filename);
+        if (itFile == files.end())
+            return DataStreamPtr();
+        else
+            return MemoryDataStreamPtr(new MemoryDataStream(itFile->second.first.get(), itFile->second.second));
+    }
+
+    void MemoryArchive::findFiles(const String& pattern, bool bRecursive, 
+        bool bDirs, StringVector* simpleList, FileInfoList* detailList)
+    {
+        const FileMap& files = archives_s[this->getName()];
+
+        for (FileMap::const_iterator it = files.begin(); it != files.end(); ++it)
+        {
+            boost::filesystem::path file = it->first;
+            // Check pattern
+            if (!StringUtil::match(file.string(), pattern, true))
+                continue;
+            if (bDirs)
+                file = file.parent_path();
+            if (file.empty())
+                continue;
+            if (file.has_parent_path() && !bRecursive)
+                continue;
+            if (simpleList)
+                simpleList->push_back(file.string());
+            if (detailList)
+            {
+                FileInfo fi;
+                fi.archive = this;
+                fi.filename = file.string();
+                fi.basename = file.filename();
+                fi.path = file.parent_path().string();
+                fi.compressedSize = it->second.second;
+                fi.uncompressedSize = it->second.second;
+                detailList->push_back(fi);
+            }
+        }
+    }
+    StringVectorPtr MemoryArchive::list(bool recursive, bool dirs)
+    {
+        StringVectorPtr ret(new StringVector());
+        findFiles("*", recursive, dirs, ret.getPointer(), 0);
+        return ret;
+    }
+
+    FileInfoListPtr MemoryArchive::listFileInfo(bool recursive, bool dirs)
+    {
+        FileInfoListPtr ret(new FileInfoList());
+        findFiles("*", recursive, dirs, 0, ret.getPointer());
+        return ret;
+    }
+
+    StringVectorPtr MemoryArchive::find(const String& pattern,
+                                            bool recursive, bool dirs)
+    {
+        StringVectorPtr ret(new StringVector());
+        findFiles(pattern, recursive, dirs, ret.getPointer(), 0);
+        return ret;
+    }
+
+    FileInfoListPtr MemoryArchive::findFileInfo(const String& pattern, 
+        bool recursive, bool dirs)
+    {
+        FileInfoListPtr ret(new FileInfoList());
+        findFiles(pattern, recursive, dirs, 0, ret.getPointer());
+        return ret;
+    }
+
+    bool MemoryArchive::exists(const String& filename)
+	{
+        const FileMap& files = archives_s[this->getName()];
+        return files.find(filename) != files.end();
+	}
+
+    const Ogre::String& MemoryArchiveFactory::getType(void) const
+    {
+        static std::string result("Memory");
+        return result;
+    }
+}
+
+#endif /* OGRE_VERSION < 0x010600 */
Index: code/trunk/src/core/MemoryArchive.h
===================================================================
--- code/trunk/src/core/MemoryArchive.h	(revision 5695)
+++ code/trunk/src/core/MemoryArchive.h	(revision 5695)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MemoryArchive_H__
+#define _MemoryArchive_H__
+
+#include "CorePrereqs.h"
+#include <OgrePrerequisites.h>
+
+#if OGRE_VERSION < 0x010600
+
+#include <map>
+#include <OgreArchive.h>
+#include <OgreArchiveFactory.h>
+#include <boost/shared_array.hpp>
+
+namespace orxonox
+{
+    /**
+    @brief
+        Provides a simple mechanism of 'memory mapped IO', but compatible for Ogre 1.4
+
+        Files are stored as shared_array<char> in a static map with the archive names
+        (imaging the different archives as resource locations). This map then contains
+        yet another map with the actual files.
+        If you want to know why we make such a fuss, contact GraphicsManager::upgradeToGraphics()
+        for more information.
+    */
+    class MemoryArchive : public Ogre::Archive
+    {
+    public:
+        MemoryArchive(const Ogre::String& name, const Ogre::String& archiveType) : Ogre::Archive(name, archiveType) { }
+        ~MemoryArchive() { }
+
+        bool isCaseSensitive(void) const { return true; }
+
+        void load();
+        void unload() { }
+
+        Ogre::DataStreamPtr open(const Ogre::String& filename) const;
+
+        Ogre::StringVectorPtr list(bool recursive = true, bool dirs = false);
+        Ogre::FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false);
+
+        Ogre::StringVectorPtr find(const Ogre::String& pattern, bool recursive = true,
+            bool dirs = false);
+        Ogre::FileInfoListPtr findFileInfo(const Ogre::String& pattern, bool recursive = true,
+            bool dirs = false);
+
+        bool exists(const Ogre::String& filename);
+
+        static void addFile(const std::string& archiveName, const std::string& filename, shared_array<char> content, size_t size)
+            { archives_s[archiveName][filename] = std::make_pair(content, size); }
+
+    private:
+        void findFiles(const Ogre::String& pattern, bool bRecursive, 
+            bool bDirs, Ogre::StringVector* simpleList, Ogre::FileInfoList* detailList);
+
+        typedef std::map<std::string, std::pair<shared_array<char>, size_t> > FileMap;
+        typedef std::map<std::string, FileMap> ArchiveMap;
+        static ArchiveMap archives_s;
+    };
+
+    //! Specialisation of ArchiveFactory for MemoryArchive.
+    class _CoreExport MemoryArchiveFactory : public Ogre::ArchiveFactory
+    {
+    public:
+        const Ogre::String& getType(void) const;
+        Ogre::Archive* createInstance(const Ogre::String& name) { return new MemoryArchive(name, "Memory"); }
+        void destroyInstance(Ogre::Archive* arch)               { delete arch; }
+    };
+}
+
+#endif /* OGRE_VERSION < 0x010600 */
+
+#endif /* _MemoryArchive_H__ */
Index: code/trunk/src/core/Resource.cc
===================================================================
--- code/trunk/src/core/Resource.cc	(revision 5695)
+++ code/trunk/src/core/Resource.cc	(revision 5695)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Resource.h"
+#include <OgreResourceGroupManager.h>
+
+namespace orxonox
+{
+    std::string Resource::DEFAULT_GROUP(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+
+    DataStreamPtr Resource::open(const std::string& name, const std::string& group, bool bSearchGroupsIfNotFound)
+    {
+        return Ogre::ResourceGroupManager::getSingleton().openResource(name, group, bSearchGroupsIfNotFound);
+    }
+
+    DataStreamListPtr Resource::openMulti(const std::string& pattern, const std::string& group)
+    {
+        return Ogre::ResourceGroupManager::getSingleton().openResources(pattern, group);
+    }
+
+    bool Resource::exists(const std::string& name, const std::string& group)
+    {
+        return Ogre::ResourceGroupManager::getSingleton().resourceExists(group, name);
+    }
+
+    shared_ptr<ResourceInfo> Resource::getInfo(const std::string& name, const std::string& group)
+    {
+        Ogre::FileInfoListPtr infos = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(group, name);
+        for (std::vector<Ogre::FileInfo>::const_iterator it = infos->begin(); it != infos->end(); ++it)
+        {
+            if (it->filename == name)
+            {
+                shared_ptr<ResourceInfo> ptr(new ResourceInfo());
+                ptr->filename = name;
+                ptr->path = it->path;
+                ptr->basename = it->basename;
+                ptr->group = group;
+                ptr->size = it->uncompressedSize;
+                return ptr;
+            }
+        }
+        return shared_ptr<ResourceInfo>();
+    }
+}
Index: code/trunk/src/core/Resource.h
===================================================================
--- code/trunk/src/core/Resource.h	(revision 5695)
+++ code/trunk/src/core/Resource.h	(revision 5695)
@@ -0,0 +1,134 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Resource_H__
+#define _Core_Resource_H__
+
+#include "CorePrereqs.h"
+
+#include <boost/shared_ptr.hpp>
+#include <OgreDataStream.h>
+
+namespace orxonox
+{
+    // Import the Ogre::DataStreamList
+    using Ogre::DataStreamList;
+    using Ogre::DataStreamListPtr;
+
+    //! Stores basic information about a Resource from Ogre
+    struct ResourceInfo
+    {
+        //! The file's fully qualified name
+        std::string filename;
+        //! Path name; separated by '/' and ending with '/'
+        std::string path;
+        //! Base filename
+        std::string basename;
+        //! Resource group the file is in
+        std::string group;
+        //! Uncompressed size
+        size_t size;
+    };
+
+    /**
+    @brief
+        Provides simple functions to easily access the Ogre::ResourceGroupManager
+    */
+    class _CoreExport Resource
+    {
+        // Docs by Ogre::ResourceGroupManager.h
+    public:
+		/**
+        @brief
+            Open a single resource by name and return a DataStream
+            pointing at the source of the data.
+        @param name
+            The name of the resource to locate.
+            Even if resource locations are added recursively, you
+            must provide a fully qualified name to this method.
+        @param groupName
+            The name of the resource group; this determines which 
+            locations are searched. 
+        @param searchGroupsIfNotFound
+            If true, if the resource is not found in 
+            the group specified, other groups will be searched.
+        @return
+            Shared pointer to data stream containing the data. Will be
+            destroyed automatically when no longer referenced.
+		*/
+        static DataStreamPtr open(const std::string& name,
+            const std::string& group = Resource::DEFAULT_GROUP,
+            bool bSearchGroupsIfNotFound = false);
+
+		/**
+        @brief
+            Open all resources matching a given pattern (which can contain
+            the character '*' as a wildcard), and return a collection of 
+            DataStream objects on them.
+        @param pattern
+            The pattern to look for. If resource locations have been
+            added recursively, subdirectories will be searched too so this
+            does not need to be fully qualified.
+        @param groupName
+            The resource group; this determines which locations
+            are searched.
+        @return
+            Shared pointer to a data stream list , will be
+            destroyed automatically when no longer referenced
+		*/
+        static DataStreamListPtr openMulti(const std::string& pattern, const std::string& group = Resource::DEFAULT_GROUP);
+
+        /**
+            Find out if the named file exists in a group. 
+        @param filename
+            Fully qualified name of the file to test for
+        @param group
+            The name of the resource group
+        */
+        static bool exists(const std::string& name, const std::string& group = Resource::DEFAULT_GROUP);
+
+        /**
+            Get struct with information about group, path and size.
+        @param filename
+            Fully qualified name of the file to test for
+        @param group
+            The name of the resource group
+        */
+        static shared_ptr<ResourceInfo> getInfo(const std::string& name, const std::string& group = Resource::DEFAULT_GROUP);
+
+        //! Name of the default resource group (usually "General")
+        static std::string DEFAULT_GROUP;
+
+    private:
+        Resource();
+        ~Resource();
+        Resource(const Resource& instance);
+    };
+}
+
+#endif /* _Core_Resource_H__ */
Index: code/trunk/src/core/TclBind.cc
===================================================================
--- code/trunk/src/core/TclBind.cc	(revision 5693)
+++ code/trunk/src/core/TclBind.cc	(revision 5695)
@@ -127,5 +127,5 @@
 #ifdef DEPENDENCY_PACKAGE_ENABLE
         if (Core::isDevelopmentRun())
-            return (std::string(ORXONOX_DEP_LIB_PATH) + "/tcl");
+            return (std::string(specialConfig::dependencyLibraryDirectory) + "/tcl");
         else
             return (Core::getRootPathString() + "lib/tcl");
Index: code/trunk/src/core/TclThreadManager.cc
===================================================================
--- code/trunk/src/core/TclThreadManager.cc	(revision 5693)
+++ code/trunk/src/core/TclThreadManager.cc	(revision 5695)
@@ -57,5 +57,5 @@
 
     /**
-        @brief A struct containing all informations about a Tcl-interpreter
+        @brief A struct containing all information about a Tcl-interpreter
     */
     struct TclInterpreterBundle
Index: code/trunk/src/core/ToluaInterface.h
===================================================================
--- code/trunk/src/core/ToluaInterface.h	(revision 5695)
+++ code/trunk/src/core/ToluaInterface.h	(revision 5695)
@@ -0,0 +1,45 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+    This is required because tolua would parse this macro in LuaState.h and fail
+*/
+
+#ifndef _ToluaInterface_H__
+#define _ToluaInterface_H__
+
+#include "CorePrereqs.h"
+#include <boost/preprocessor/cat.hpp>
+
+// Macro for declaring a tolua interface of a library/module
+#define DeclareToluaInterface(libraryName) \
+    static bool BOOST_PP_CAT(bDummy##libraryName, __LINE__) = orxonox::LuaState::addToluaInterface(&tolua_##libraryName##_open, #libraryName); \
+    static Loki::ScopeGuardImpl1<bool (*)(const std::string&), std::string> BOOST_PP_CAT(dummy##libraryName, __LINE__)(&orxonox::LuaState::removeToluaInterface, #libraryName)
+
+#endif /* _ToluaInterface_H__ */
Index: code/trunk/src/core/XMLFile.h
===================================================================
--- code/trunk/src/core/XMLFile.h	(revision 5693)
+++ code/trunk/src/core/XMLFile.h	(revision 5695)
@@ -40,13 +40,28 @@
     {
         public:
-            XMLFile(const std::string& filename) : filename_(filename) {}
-            XMLFile(const std::string& filename, const ClassTreeMask& mask) : filename_(filename), mask_(mask) {};
+            XMLFile(const std::string& filename, const std::string& resourceGroup = "General")
+                : filename_(filename)
+                , group_(resourceGroup)
+                , bLuaSupport_(true)
+            { }
+            XMLFile(const ClassTreeMask& mask, const std::string& filename, const std::string& resourceGroup = "General")
+                : filename_(filename)
+                , group_(resourceGroup)
+                , mask_(mask)
+                , bLuaSupport_(true)
+            { }
+
+            void setLuaSupport(bool val) { bLuaSupport_ = val; }
 
             const std::string& getFilename() const { return this->filename_; }
+            const std::string& getResourceGroup() const { return this->group_; }
             const ClassTreeMask& getMask() const { return this->mask_; }
+            bool getLuaSupport() const { return this->bLuaSupport_; }
 
         private:
             std::string filename_;
+            std::string group_;
             ClassTreeMask mask_;
+            bool bLuaSupport_; // Default is true
     };
 }
Index: code/trunk/src/core/input/Button.cc
===================================================================
--- code/trunk/src/core/input/Button.cc	(revision 5693)
+++ code/trunk/src/core/input/Button.cc	(revision 5695)
@@ -59,5 +59,4 @@
         nCommands_[1]=0;
         nCommands_[2]=0;
-        this->configContainer_ = 0;
     }
 
Index: code/trunk/src/core/input/InputManager.cc
===================================================================
--- code/trunk/src/core/input/InputManager.cc	(revision 5693)
+++ code/trunk/src/core/input/InputManager.cc	(revision 5695)
@@ -41,4 +41,5 @@
 #include <boost/foreach.hpp>
 
+#include "util/Convert.h"
 #include "util/Exception.h"
 #include "util/ScopeGuard.h"
@@ -49,4 +50,5 @@
 #include "core/CommandLine.h"
 #include "core/Functor.h"
+#include "core/GraphicsManager.h"
 
 #include "InputBuffer.h"
@@ -82,9 +84,9 @@
     // ##########                                        ##########
     // ############################################################
-    InputManager::InputManager(size_t windowHnd)
+    InputManager::InputManager()
         : internalState_(Bad)
         , oisInputManager_(0)
         , devices_(2)
-        , windowHnd_(0)
+        , bExclusiveMouse_(false)
         , emptyState_(0)
         , keyDetector_(0)
@@ -97,5 +99,5 @@
         this->setConfigValues();
 
-        this->loadDevices(windowHnd);
+        this->loadDevices();
 
         // Lowest priority empty InputState
@@ -147,6 +149,4 @@
         Creates the OIS::InputMananger, the keyboard, the mouse and
         the joys ticks. If either of the first two fail, this method throws an exception.
-    @param windowHnd
-        The window handle of the render window
     @param windowWidth
         The width of the render window
@@ -154,7 +154,7 @@
         The height of the render window
     */
-    void InputManager::loadDevices(size_t windowHnd)
-    {
-        CCOUT(3) << "Loading input devices..." << std::endl;
+    void InputManager::loadDevices()
+    {
+        CCOUT(4) << "Loading input devices..." << std::endl;
 
         // When loading the devices they should not already be loaded
@@ -164,28 +164,40 @@
         assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
 
-        // store handle internally so we can reload OIS
-        windowHnd_ = windowHnd;
-
+        // Fill parameter list
         OIS::ParamList paramList;
-        std::ostringstream windowHndStr;
-
-        // Fill parameter list
-        windowHndStr << static_cast<unsigned int>(windowHnd);
-        paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
+        size_t windowHnd = GraphicsManager::getInstance().getRenderWindowHandle();
+        paramList.insert(std::make_pair("WINDOW", multi_cast<std::string>(windowHnd)));
 #if defined(ORXONOX_PLATFORM_WINDOWS)
-        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
-        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
-        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
-        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
+        paramList.insert(std::make_pair("w32_keyboard", "DISCL_NONEXCLUSIVE"));
+        paramList.insert(std::make_pair("w32_keyboard", "DISCL_FOREGROUND"));
+        paramList.insert(std::make_pair("w32_mouse", "DISCL_FOREGROUND"));
+        if (bExclusiveMouse_ || GraphicsManager::getInstance().isFullScreen())
+        {
+            // Disable Windows key plus special keys (like play, stop, next, etc.)
+            paramList.insert(std::make_pair("w32_keyboard", "DISCL_NOWINKEY"));
+            paramList.insert(std::make_pair("w32_mouse", "DISCL_EXCLUSIVE"));
+        }
+        else
+            paramList.insert(std::make_pair("w32_mouse", "DISCL_NONEXCLUSIVE"));
 #elif defined(ORXONOX_PLATFORM_LINUX)
-        paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
-        paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
-        paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true"));
-        bool kbNoGrab;
-        CommandLine::getValue("keyboard_no_grab", &kbNoGrab);
-        if (kbNoGrab)
-            paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
+        // Enabling this is probably a bad idea, but whenever orxonox crashes, the setting stays on
+        // Trouble might be that the Pressed event occurs a bit too often...
+        paramList.insert(std::make_pair("XAutoRepeatOn", "true"));
+
+        if (bExclusiveMouse_ || GraphicsManager::getInstance().isFullScreen())
+        {
+            if (CommandLine::getValue("keyboard_no_grab").getBool())
+                paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
+            else
+                paramList.insert(std::make_pair("x11_keyboard_grab", "true"));
+            paramList.insert(std::make_pair("x11_mouse_grab",  "true"));
+            paramList.insert(std::make_pair("x11_mouse_hide", "true"));
+        }
         else
-            paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
+        {
+            paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
+            paramList.insert(std::make_pair("x11_mouse_grab",  "false"));
+            paramList.insert(std::make_pair("x11_mouse_hide", "false"));
+        }
 #endif
 
@@ -212,5 +224,4 @@
         }
 
-        // TODO: Remove the two parameters
         this->loadMouse();
         this->loadJoySticks();
@@ -219,5 +230,5 @@
         this->updateActiveStates();
 
-        CCOUT(3) << "Input devices loaded." << std::endl;
+        CCOUT(4) << "Input devices loaded." << std::endl;
     }
 
@@ -275,5 +286,5 @@
     InputManager::~InputManager()
     {
-        CCOUT(4) << "Destroying..." << std::endl;
+        CCOUT(3) << "Destroying..." << std::endl;
 
         // Destroy calibrator helper handler and state
@@ -293,5 +304,5 @@
             this->destroyDevices();
 
-        CCOUT(4) << "Destruction complete." << std::endl;
+        CCOUT(3) << "Destruction complete." << std::endl;
     }
 
@@ -304,5 +315,5 @@
     void InputManager::destroyDevices()
     {
-        CCOUT(3) << "Destroying devices..." << std::endl;
+        CCOUT(4) << "Destroying devices..." << std::endl;
 
         BOOST_FOREACH(InputDevice*& device, devices_)
@@ -336,5 +347,5 @@
 
         internalState_ |= Bad;
-        CCOUT(3) << "Destroyed devices." << std::endl;
+        CCOUT(4) << "Destroyed devices." << std::endl;
     }
 
@@ -365,9 +376,9 @@
 
         this->destroyDevices();
-        this->loadDevices(windowHnd_);
+        this->loadDevices();
 
         internalState_ &= ~Bad;
         internalState_ &= ~ReloadRequest;
-        CCOUT(3) << "Reloading complete." << std::endl;
+        CCOUT(4) << "Reloading complete." << std::endl;
     }
 
@@ -481,4 +492,5 @@
     void InputManager::updateActiveStates()
     {
+        assert((internalState_ & InputManager::Ticking) == 0);
         // temporary resize
         for (unsigned int i = 0; i < devices_.size(); ++i)
@@ -512,4 +524,14 @@
         for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
             activeStatesTicked_.push_back(*it);
+
+        // Check whether we have to change the mouse mode
+        std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
+        if (mouseStates.empty() && bExclusiveMouse_ ||
+            !mouseStates.empty() && mouseStates.front()->getIsExclusiveMouse() != bExclusiveMouse_)
+        {
+            bExclusiveMouse_ = !bExclusiveMouse_;
+            if (!GraphicsManager::getInstance().isFullScreen())
+                this->reloadInternal();
+        }
     }
 
@@ -556,6 +578,18 @@
     }
 
-    // ############################################################
-    // #####                    Iput States                   #####
+    std::pair<int, int> InputManager::getMousePosition() const
+    {
+        Mouse* mouse = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse]);
+        if (mouse != NULL)
+        {
+            const OIS::MouseState state = mouse->getOISDevice()->getMouseState();
+            return std::make_pair(state.X.abs, state.Y.abs);
+        }
+        else
+            return std::make_pair(0, 0);
+    }
+
+    // ############################################################
+    // #####                    Input States                  #####
     // ##########                                        ##########
     // ############################################################
Index: code/trunk/src/core/input/InputManager.h
===================================================================
--- code/trunk/src/core/input/InputManager.h	(revision 5693)
+++ code/trunk/src/core/input/InputManager.h	(revision 5695)
@@ -84,5 +84,5 @@
             the constructor fails with an std::exception.
         */
-        InputManager(size_t windowHnd);
+        InputManager();
         //! Destroys all devices AND all input states!
         ~InputManager();
@@ -167,6 +167,6 @@
             { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
         //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
-        OIS::InputManager* getOISInputManager()
-            { return this->oisInputManager_; }
+        OIS::InputManager* getOISInputManager() { return this->oisInputManager_; }
+        std::pair<int, int> getMousePosition() const;
 
     private: // functions
@@ -175,5 +175,5 @@
 
         // Intenal methods
-        void loadDevices(size_t windowHnd);
+        void loadDevices();
         void loadMouse();
         void loadJoySticks();
@@ -193,6 +193,5 @@
         OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
         std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
-        // TODO: Get this from the GraphicsManager during reload
-        size_t                              windowHnd_;            //!< Render window handle (used to reload the InputManager)
+        bool                                bExclusiveMouse_;      //!< Currently applied mouse mode
 
         // some internally handled states and handlers
Index: code/trunk/src/core/input/InputState.cc
===================================================================
--- code/trunk/src/core/input/InputState.cc	(revision 5693)
+++ code/trunk/src/core/input/InputState.cc	(revision 5695)
@@ -37,4 +37,5 @@
         , bAlwaysGetsInput_(bAlwaysGetsInput)
         , bTransparent_(bTransparent)
+        , bExclusiveMouse_(true)
         , bExpired_(true)
         , handlers_(2)
Index: code/trunk/src/core/input/InputState.h
===================================================================
--- code/trunk/src/core/input/InputState.h	(revision 5693)
+++ code/trunk/src/core/input/InputState.h	(revision 5695)
@@ -75,6 +75,5 @@
           not influence ony other InputState at all.
 
-        Priorities
-        **********
+    @par Priorities
         Every InputState has a priority when on the stack, but mostly this
         priority is dynamic (InputStatePriority::Dynamic) which means that a state
@@ -83,4 +82,11 @@
         a high priority (InputStatePriority::HighPriority). These 'special' ones
         are used for features like the KeyDetector or the console. Use with care!
+
+    @par Exclusive/Non-Exclusive mouse Mode
+        You can select a specific mouse mode that tells whether the application
+        should have exclusive accessto it or not.
+        When in non-exclusive mode, you can move the mouse out of the window
+        like with any other normal window (only for windowed mode!).
+        The setting is dictated by the topmost InputState that gets mouse events.
     */
     class _CoreExport InputState : public JoyStickQuantityListener
@@ -114,4 +120,7 @@
         void setHandler        (InputHandler* handler);
 
+        void setIsExclusiveMouse(bool value) { bExclusiveMouse_ = value; this->bExpired_ = true; }
+        bool getIsExclusiveMouse() const { return bExclusiveMouse_; }
+
         //! Returns the name of the state (which is unique!)
         const std::string& getName() const { return name_; }
@@ -165,4 +174,5 @@
         const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
         const bool                  bTransparent_;          //!< See class declaration for explanation
+        bool                        bExclusiveMouse_;       //!< See class declaration for explanation
         int                         priority_;              //!< Current priority (might change)
         bool                        bExpired_;              //!< See hasExpired()
Index: code/trunk/src/core/input/KeyBinder.cc
===================================================================
--- code/trunk/src/core/input/KeyBinder.cc	(revision 5693)
+++ code/trunk/src/core/input/KeyBinder.cc	(revision 5695)
@@ -55,7 +55,4 @@
         mousePosition_[0] = 0;
         mousePosition_[1] = 0;
-
-        joyStickButtons_.reserve(1000);
-        joyStickAxes_.reserve(1000);
 
         RegisterRootObject(KeyBinder);
@@ -167,7 +164,7 @@
             {
                 for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
-                    joyStickButtons_[iDev][i].readConfigValue(this->configFile_);
+                    (*joyStickButtons_[iDev])[i].readConfigValue(this->configFile_);
                 for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
-                    joyStickAxes_[iDev][i].readConfigValue(this->configFile_);
+                    (*joyStickAxes_[iDev])[i].readConfigValue(this->configFile_);
             }
         }
@@ -179,4 +176,9 @@
     void KeyBinder::initialiseJoyStickBindings()
     {
+        while (joyStickAxes_.size() < joySticks_.size())
+            joyStickAxes_.push_back(shared_ptr<JoyStickAxisVector>(new JoyStickAxisVector()));
+        while (joyStickButtons_.size() < joySticks_.size())
+            joyStickButtons_.push_back(shared_ptr<JoyStickButtonVector>(new JoyStickButtonVector()));
+        // For the case the new size is smaller
         this->joyStickAxes_.resize(joySticks_.size());
         this->joyStickButtons_.resize(joySticks_.size());
@@ -189,18 +191,18 @@
             for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
             {
-                joyStickButtons_[iDev][i].name_ = JoyStickButtonCode::ByString[i];
-                joyStickButtons_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
-                joyStickButtons_[iDev][i].groupName_ = "JoyStickButtons_" + deviceName;
+                (*joyStickButtons_[iDev])[i].name_ = JoyStickButtonCode::ByString[i];
+                (*joyStickButtons_[iDev])[i].paramCommandBuffer_ = &paramCommandBuffer_;
+                (*joyStickButtons_[iDev])[i].groupName_ = "JoyStickButtons_" + deviceName;
             }
             // joy stick axes
             for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
             {
-                joyStickAxes_[iDev][i].name_ = JoyStickAxisCode::ByString[i / 2];
+                (*joyStickAxes_[iDev])[i].name_ = JoyStickAxisCode::ByString[i / 2];
                 if (i & 1)
-                    joyStickAxes_[iDev][i].name_ += "Pos";
+                    (*joyStickAxes_[iDev])[i].name_ += "Pos";
                 else
-                    joyStickAxes_[iDev][i].name_ += "Neg";
-                joyStickAxes_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
-                joyStickAxes_[iDev][i].groupName_ = "JoyStickAxes_" + deviceName;
+                    (*joyStickAxes_[iDev])[i].name_ += "Neg";
+                (*joyStickAxes_[iDev])[i].paramCommandBuffer_ = &paramCommandBuffer_;
+                (*joyStickAxes_[iDev])[i].groupName_ = "JoyStickAxes_" + deviceName;
             }
         }
@@ -226,9 +228,9 @@
         {
             for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
-                allButtons_[joyStickButtons_[iDev][i].groupName_ + "." + joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
+                allButtons_[(*joyStickButtons_[iDev])[i].groupName_ + "." + (*joyStickButtons_[iDev])[i].name_] = &((*joyStickButtons_[iDev])[i]);
             for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
             {
-                allButtons_[joyStickAxes_[iDev][i].groupName_ + "." + joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
-                allHalfAxes_.push_back(&(joyStickAxes_[iDev][i]));
+                allButtons_[(*joyStickAxes_[iDev])[i].groupName_ + "." + (*joyStickAxes_[iDev])[i].name_] = &((*joyStickAxes_[iDev])[i]);
+                allHalfAxes_.push_back(&((*joyStickAxes_[iDev])[i]));
             }
         }
@@ -303,6 +305,6 @@
             for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
             {
-                joyStickAxes_[iDev][i].absVal_ = 0.0f;
-                joyStickAxes_[iDev][i].relVal_ = 0.0f;
+                (*joyStickAxes_[iDev])[i].absVal_ = 0.0f;
+                (*joyStickAxes_[iDev])[i].relVal_ = 0.0f;
             }
         }
@@ -366,5 +368,5 @@
         for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
         {
-            tickHalfAxis(joyStickAxes_[joyStick][i]);
+            tickHalfAxis((*joyStickAxes_[joyStick])[i]);
         }
     }
@@ -481,5 +483,5 @@
     {
         int i = axisID * 2;
-        JoyStickAxisVector& axis = joyStickAxes_[device];
+        JoyStickAxisVector& axis = *joyStickAxes_[device];
         if (value < 0)
         {
Index: code/trunk/src/core/input/KeyBinder.h
===================================================================
--- code/trunk/src/core/input/KeyBinder.h	(revision 5693)
+++ code/trunk/src/core/input/KeyBinder.h	(revision 5695)
@@ -41,4 +41,5 @@
 #include <string>
 #include <vector>
+#include <boost/shared_ptr.hpp>
 
 #include "InputHandler.h"
@@ -115,5 +116,5 @@
         };
         //! Actual key bindings for joy stick buttons
-        std::vector<JoyStickButtonVector> joyStickButtons_;
+        std::vector<shared_ptr<JoyStickButtonVector> > joyStickButtons_;
         //! Helper class to use something like std:vector<HalfAxis[48]>
         struct JoyStickAxisVector
@@ -123,5 +124,5 @@
         };
         //! Actual key bindings for joy stick axes (and sliders)
-        std::vector<JoyStickAxisVector> joyStickAxes_;
+        std::vector<shared_ptr<JoyStickAxisVector> > joyStickAxes_;
 
         //! Pointer map with all Buttons, including half axes
@@ -191,11 +192,11 @@
 
     inline void KeyBinder::buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button)
-    { joyStickButtons_[device][button].execute(KeybindMode::OnPress); }
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnPress); }
 
     inline void KeyBinder::buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button)
-    { joyStickButtons_[device][button].execute(KeybindMode::OnRelease); }
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnRelease); }
 
     inline void KeyBinder::buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button)
-    { joyStickButtons_[device][button].execute(KeybindMode::OnHold); }
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnHold); }
 
     inline void KeyBinder::allDevicesUpdated(float dt)
Index: code/trunk/src/core/input/KeyDetector.cc
===================================================================
--- code/trunk/src/core/input/KeyDetector.cc	(revision 5693)
+++ code/trunk/src/core/input/KeyDetector.cc	(revision 5695)
@@ -70,5 +70,6 @@
     {
         KeyBinder::JoyStickQuantityChanged(joyStickList);
-        setCallbackCommand(callbackCommand_);
+        if (!callbackCommand_.empty())
+            setCallbackCommand(callbackCommand_);
     }
 }
Index: code/trunk/src/network/CMakeLists.txt
===================================================================
--- code/trunk/src/network/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/network/CMakeLists.txt	(revision 5695)
@@ -35,9 +35,29 @@
   TrafficControl.cc
 )
+
+SET_SOURCE_FILES(NETWORK_HDR_FILES
+  ChatListener.h
+  Client.h
+  ClientConnection.h
+  ClientConnectionListener.h
+  ClientInformation.h
+  Connection.h
+  FunctionCallManager.h
+  GamestateClient.h
+  GamestateHandler.h
+  GamestateManager.h
+  Host.h
+  NetworkFunction.h
+  NetworkPrecompiledHeaders.h
+  NetworkPrereqs.h
+  Server.h
+  ServerConnection.h
+  TrafficControl.h
+)
+
 ADD_SUBDIRECTORY(packet)
 ADD_SUBDIRECTORY(synchronisable)
 
 ORXONOX_ADD_LIBRARY(network
-  FIND_HEADER_FILES
   DEFINE_SYMBOL
     "NETWORK_SHARED_BUILD"
@@ -51,4 +71,4 @@
     core
   SOURCE_FILES
-    ${NETWORK_SRC_FILES}
+    ${NETWORK_SRC_FILES} ${NETWORK_HDR_FILES}
 )
Index: code/trunk/src/network/ClientInformation.h
===================================================================
--- code/trunk/src/network/ClientInformation.h	(revision 5693)
+++ code/trunk/src/network/ClientInformation.h	(revision 5695)
@@ -49,5 +49,5 @@
 
   /**
-  * This class implements a list for client informations
+  * This class implements a list for client information
   * @author Oliver Scheuss
   */
Index: code/trunk/src/network/packet/CMakeLists.txt
===================================================================
--- code/trunk/src/network/packet/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/network/packet/CMakeLists.txt	(revision 5695)
@@ -1,4 +1,3 @@
 ADD_SOURCE_FILES(NETWORK_SRC_FILES
-  Packet.cc
   Acknowledgement.cc
   Chat.cc
@@ -8,4 +7,18 @@
   FunctionCalls.cc
   Gamestate.cc
+  Packet.cc
   Welcome.cc
 )
+
+ADD_SOURCE_FILES(NETWORK_HDR_FILES
+  Acknowledgement.h
+  Chat.cc
+  Chat.h
+  ClassID.h
+  DeleteObjects.h
+  FunctionCalls.h
+  FunctionIDs.h
+  Gamestate.h
+  Packet.h
+  Welcome.h
+)
Index: code/trunk/src/network/synchronisable/CMakeLists.txt
===================================================================
--- code/trunk/src/network/synchronisable/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/network/synchronisable/CMakeLists.txt	(revision 5695)
@@ -5,2 +5,9 @@
   SynchronisableVariable.cc
 )
+
+ADD_SOURCE_FILES(NETWORK_HDR_FILES
+  NetworkCallback.h
+  NetworkCallbackManager.h
+  Synchronisable.h
+  SynchronisableVariable.h
+)
Index: code/trunk/src/ois/OISEffect.cpp
===================================================================
--- code/trunk/src/ois/OISEffect.cpp	(revision 5693)
+++ code/trunk/src/ois/OISEffect.cpp	(revision 5695)
@@ -29,4 +29,39 @@
 //Perhaps a case of a crazy extreme optimizer :/ (moved to header)
 //const unsigned int Effect::OIS_INFINITE = 0xFFFFFFFF;
+
+//------------------------------------------------------------------------------//
+static const char* pszEForceString[] = 
+  { "UnknownForce",
+    "ConstantForce", 
+    "RampForce", 
+    "PeriodicForce", 
+    "ConditionalForce", 
+    "CustomForce" };
+
+const char* Effect::getForceTypeName(Effect::EForce eValue)
+{
+  return (eValue >= 0 && eValue < _ForcesNumber) ? pszEForceString[eValue] : "<Bad force type>";
+}
+
+static const char* pszETypeString[] = 
+  { "Unknown",
+    "Constant",
+    "Ramp",
+    "Square", "Triangle", "Sine", "SawToothUp", "SawToothDown",
+    "Friction", "Damper", "Inertia", "Spring",
+    "Custom" };
+
+const char* Effect::getEffectTypeName(Effect::EType eValue)
+{
+  return (eValue >= 0 && eValue < _TypesNumber) ? pszETypeString[eValue] : "<Bad effect type>";
+}
+
+static const char* pszEDirectionString[] = 
+  { "NorthWest", "North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West"};
+
+const char* Effect::getDirectionName(Effect::EDirection eValue)
+{
+  return (eValue >= 0 && eValue < _DirectionsNumber) ? pszEDirectionString[eValue] : "<Bad direction>";
+}
 
 //------------------------------------------------------------------------------//
Index: code/trunk/src/ois/OISEffect.h
===================================================================
--- code/trunk/src/ois/OISEffect.h	(revision 5693)
+++ code/trunk/src/ois/OISEffect.h	(revision 5695)
@@ -60,6 +60,9 @@
 			PeriodicForce,
 			ConditionalForce,
-			CustomForce
+			CustomForce,
+			_ForcesNumber // Always keep in last position.
 		};
+
+		static const char* getForceTypeName(EForce eValue);
 
 		//! Type of effect
@@ -79,6 +82,9 @@
 			Inertia,     //ConditionalForce
 			Spring,      //ConditionalForce
-			Custom       //CustomForce
+			Custom,      //CustomForce
+			_TypesNumber // Always keep in last position.
 		};
+
+		static const char* getEffectTypeName(EType eValue);
 
 		//! Direction of the Force
@@ -92,6 +98,9 @@
 			South,
 			SouthWest,
-			West
+			West,
+			_DirectionsNumber // Always keep in last position.
 		};
+
+		static const char* getDirectionName(EDirection eValue);
 
 		/**
@@ -168,5 +177,5 @@
 		An optional envelope to be applied to the start/end of an effect. If any of
 		these values are nonzero, then the envelope will be used in setting up the
-		effect. Not currently utilised.. But, will be soon.
+		effect.
 	*/
 	class _OISExport Envelope : public ForceEffect
@@ -178,12 +187,21 @@
   #pragma warning (disable : 4800)
 #endif
-		bool isUsed() { return attackLength | attackLevel | fadeLength | fadeLevel; }
+		bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; }
 #if defined(OIS_MSVC_COMPILER)
   #pragma warning (pop)
 #endif
 
-		unsigned short attackLength;
+		// Duration of the attack (microseconds)
+		unsigned int attackLength;
+
+		// Absolute level at the beginning of the attack (0 to 10K)
+		// (automatically signed when necessary by FF core according to effect level sign)
 		unsigned short attackLevel;
-		unsigned short fadeLength;
+
+		// Duration of fade (microseconds)
+		unsigned int fadeLength;
+
+		// Absolute level at the end of fade (0 to 10K)
+		// (automatically signed when necessary by FF core according to effect level sign)
 		unsigned short fadeLevel;
 	};
@@ -211,5 +229,5 @@
 		RampEffect() : startLevel(0), endLevel(0) {}
 
-        class Envelope envelope; //Optional envolope
+        class Envelope envelope; //Optional envelope
 		signed short startLevel;  //-10K to +10k
 		signed short endLevel;    //-10K to +10k
Index: code/trunk/src/ois/OISForceFeedback.cpp
===================================================================
--- code/trunk/src/ois/OISForceFeedback.cpp	(revision 5693)
+++ code/trunk/src/ois/OISForceFeedback.cpp	(revision 5695)
@@ -27,16 +27,48 @@
 
 //-------------------------------------------------------------//
-void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type )
+ForceFeedback::ForceFeedback() : mSetGainSupport(false), mSetAutoCenterSupport(false)
 {
-	if( force == Effect::UnknownForce || type == Effect::Unknown )
-		OIS_EXCEPT( E_General, "Unknown Force||Type was added too effect list..." );
-
-	mSupportedEffects[force] = type;
 }
 
 //-------------------------------------------------------------//
-const ForceFeedback::SupportedEffectList& 
-						ForceFeedback::getSupportedEffects() const
+void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type )
+{
+	if( force <= Effect::UnknownForce || force >= Effect::_ForcesNumber
+		|| type <= Effect::Unknown || type >= Effect::_TypesNumber )
+		OIS_EXCEPT( E_General, "Can't add unknown effect Force/Type to the supported list" );
+
+	mSupportedEffects.insert(std::pair<Effect::EForce, Effect::EType>(force, type));
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_setGainSupport( bool on )
+{
+	mSetGainSupport = on;
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_setAutoCenterSupport( bool on )
+{
+	mSetAutoCenterSupport = on;
+}
+
+//-------------------------------------------------------------//
+const ForceFeedback::SupportedEffectList& ForceFeedback::getSupportedEffects() const
 {
 	return mSupportedEffects;
 }
+
+//-------------------------------------------------------------//
+bool ForceFeedback::supportsEffect(Effect::EForce force, Effect::EType type) const
+{
+    const std::pair<SupportedEffectList::const_iterator, SupportedEffectList::const_iterator> 
+	    iterRange = mSupportedEffects.equal_range(force);
+	SupportedEffectList::const_iterator iter;
+	for (iter = iterRange.first; iter != iterRange.second; iter++)
+	{
+	  if ((*iter).second == type)
+		return true;
+	}
+
+	return false;
+}
Index: code/trunk/src/ois/OISForceFeedback.h
===================================================================
--- code/trunk/src/ois/OISForceFeedback.h	(revision 5693)
+++ code/trunk/src/ois/OISForceFeedback.h	(revision 5695)
@@ -36,5 +36,5 @@
 	{
 	public:
-		ForceFeedback() {}
+		ForceFeedback();
 		virtual ~ForceFeedback() {}
 
@@ -44,4 +44,5 @@
 			Individual effects have gain levels; however, this affects all
 			effects at once.
+			Note: If the device does not support master gain setting, nothing is done
 		@param level
 			A value between 0.0 and 1.0 represent the percentage of gain. 1.0
@@ -56,4 +57,5 @@
 			the joystick back to center. DirectInput only has an on/off setting,
 			whereas linux has levels.. Though, we go with DI's on/off mode only
+			Note: If the device does not support auto-centering, nothing is done
 		@param auto_on
 			true to turn auto centering on, false to turn off.
@@ -87,5 +89,11 @@
         virtual short getFFAxesNumber() = 0;
 
-		typedef std::map<Effect::EForce, Effect::EType> SupportedEffectList;
+		/**
+		@remarks
+			Get the current load (%, in [0, 100] of the FF device memory 
+		*/
+		virtual unsigned short getFFMemoryLoad() = 0;
+
+		typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList;
 		/**
 		@remarks
@@ -94,8 +102,18 @@
 		const SupportedEffectList& getSupportedEffects() const;
 
+		/**
+		@remarks
+			Tell if a given force / effect type pair is supported
+		*/
+		bool supportsEffect(Effect::EForce force, Effect::EType type) const;
+
 		void _addEffectTypes( Effect::EForce force, Effect::EType type );
+		void _setGainSupport( bool on );
+		void _setAutoCenterSupport( bool on );
 
 	protected:
 		SupportedEffectList mSupportedEffects;
+		bool mSetGainSupport;
+		bool mSetAutoCenterSupport;
 	};
 }
Index: code/trunk/src/ois/OISJoyStick.h
===================================================================
--- code/trunk/src/ois/OISJoyStick.h	(revision 5693)
+++ code/trunk/src/ois/OISJoyStick.h	(revision 5695)
@@ -32,5 +32,5 @@
 
 	//! POV / HAT Joystick component
-	class _OISExport Pov : Component
+	class _OISExport Pov : public Component
 	{
 	public:
@@ -51,5 +51,5 @@
 
 	//! A sliding axis - only used in Win32 Right Now
-	class _OISExport Slider : Component
+	class _OISExport Slider : public Component
 	{
 	public:
Index: code/trunk/src/ois/OISPrereqs.h
===================================================================
--- code/trunk/src/ois/OISPrereqs.h	(revision 5693)
+++ code/trunk/src/ois/OISPrereqs.h	(revision 5695)
@@ -167,6 +167,6 @@
 	{
 	public:
-		Button() {}
-		Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {};
+		Button() : Component(OIS_Button), pushed(false) {}
+		Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
 		//! true if pushed, false otherwise
 		bool pushed;
Index: code/trunk/src/ois/changes_orxonox.diff
===================================================================
--- code/trunk/src/ois/changes_orxonox.diff	(revision 5693)
+++ code/trunk/src/ois/changes_orxonox.diff	(revision 5695)
@@ -0,0 +1,24 @@
+--- linux/EventHelpers.cpp	(revision 5668)
++++ linux/EventHelpers.cpp	(working copy)
+@@ -35,6 +35,20 @@
+ # include <iostream>
+ #endif
+ 
++// Fixes for missing macros in input.h
++#ifndef FF_EFFECT_MIN
++#define FF_EFFECT_MIN FF_RUMBLE
++#endif
++#ifndef FF_EFFECT_MAX
++#define FF_EFFECT_MAX FF_RAMP
++#endif
++#ifndef FF_WAVEFORM_MIN
++#define FF_WAVEFORM_MIN FF_SQUARE
++#endif
++#ifndef FF_WAVEFORM_MAX
++#define FF_WAVEFORM_MAX FF_CUSTOM
++#endif
++
+ using namespace std;
+ using namespace OIS;
+ 
+
Index: code/trunk/src/ois/linux/EventHelpers.cpp
===================================================================
--- code/trunk/src/ois/linux/EventHelpers.cpp	(revision 5693)
+++ code/trunk/src/ois/linux/EventHelpers.cpp	(revision 5695)
@@ -34,7 +34,21 @@
 #ifdef OIS_LINUX_JOY_DEBUG
 # include <iostream>
-  using namespace std;
-#endif
-
+#endif
+
+// Fixes for missing macros in input.h
+#ifndef FF_EFFECT_MIN
+#define FF_EFFECT_MIN FF_RUMBLE
+#endif
+#ifndef FF_EFFECT_MAX
+#define FF_EFFECT_MAX FF_RAMP
+#endif
+#ifndef FF_WAVEFORM_MIN
+#define FF_WAVEFORM_MIN FF_SQUARE
+#endif
+#ifndef FF_WAVEFORM_MAX
+#define FF_WAVEFORM_MAX FF_CUSTOM
+#endif
+
+using namespace std;
 using namespace OIS;
 
@@ -42,33 +56,49 @@
 {
 public:
-	std::vector<int> buttons, relAxes, absAxes, hats;
+	vector<int> buttons, relAxes, absAxes, hats;
 };
 
-bool inline isBitSet(unsigned long bits[], unsigned int bit)
-{
-	return (bits[bit/(sizeof(long)*8)] >> ((bit)%(sizeof(long)*8))) & 1;
-}
+bool inline isBitSet(unsigned char bits[], unsigned int bit)
+{
+  return (bits[(bit)/(sizeof(unsigned char)*8)] >> ((bit)%(sizeof(unsigned char)*8))) & 1;
+}
+
 //-----------------------------------------------------------------------------//
 DeviceComponentInfo getComponentInfo( int deviceID )
 {
-	unsigned long info[2][((KEY_MAX-1)/(sizeof(long)*8)) +1];
-	memset( info, 0, sizeof(info) );
+	unsigned char ev_bits[1 + EV_MAX/8/sizeof(unsigned char)];
+	memset( ev_bits, 0, sizeof(ev_bits) );
+
+	//Read "all" (hence 0) components of the device
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getComponentInfo(" << deviceID 
+		 << ") : Reading device events features" << endl;
+#endif
+	if (ioctl(deviceID, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1)
+		OIS_EXCEPT( E_General, "Could not read device events features");
 
 	DeviceComponentInfo components;
-
-	//Read "all" (hence 0) components of the device - read into first entry
-	ioctl(deviceID, EVIOCGBIT(0, EV_MAX), info[0]);
 
 	for (int i = 0; i < EV_MAX; i++)
 	{
-		if( isBitSet(info[0], i) )
+		if( isBitSet(ev_bits, i) )
 		{
-			memset( info[1], 0, sizeof(info) / 2 );
-			ioctl(deviceID, EVIOCGBIT(i, KEY_MAX), info[1]);
-			for (int j = 0; j < KEY_MAX; j++)
+		    // Absolute axis.
+		    if(i == EV_ABS)
 			{
-				if( isBitSet(info[1], j) )
+			    unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)];
+			    memset( abs_bits, 0, sizeof(abs_bits) );
+
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device absolute axis features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(abs_bits)), abs_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device absolute axis features");
+
+				for (int j = 0; j < ABS_MAX; j++)
 				{
-					if(i == EV_ABS)
+				    if( isBitSet(abs_bits, j) )
 					{
 						//input_absinfo abInfo;
@@ -89,11 +119,45 @@
 						}
 					}
-					else if(i == EV_REL)
+				}
+			}
+			else if(i == EV_REL)
+			{
+			    unsigned char rel_bits[1 + REL_MAX/8/sizeof(unsigned char)];
+				memset( rel_bits, 0, sizeof(rel_bits) );
+				
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device relative axis features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(rel_bits)), rel_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device relative axis features");
+				
+				for (int j = 0; j < REL_MAX; j++)
+				{
+				    if( isBitSet(rel_bits, j) )
 					{
-						components.relAxes.push_back(j);
+					    components.relAxes.push_back(j);
 					}
-					else if(i == EV_KEY)
+				}
+			}
+			else if(i == EV_KEY)
+			{
+			    unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)];
+				memset( key_bits, 0, sizeof(key_bits) );
+				
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device buttons features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(key_bits)), key_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device buttons features");
+				
+				for (int j = 0; j < KEY_MAX; j++)
+				{
+				    if( isBitSet(key_bits, j) )
 					{
-						components.buttons.push_back(j);
+					    components.buttons.push_back(j);
 					}
 				}
@@ -108,5 +172,6 @@
 bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js )
 {
-	if( deviceID == -1 ) OIS_EXCEPT( E_General, "Error with File Descriptor" );
+	if( deviceID == -1 ) 
+		OIS_EXCEPT( E_General, "Error with File Descriptor" );
 
 	DeviceComponentInfo info = getComponentInfo( deviceID );
@@ -117,10 +182,12 @@
 
 	#ifdef OIS_LINUX_JOY_DEBUG
-	  cout << "\n\nDisplaying ButtonMapping Status:";
+	cout << endl << "Displaying ButtonMapping Status:" << endl;
 	#endif
-	for(std::vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i )
+	for(vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i )
 	{
 		//Check to ensure we find at least one joy only button
-		if( (*i >= BTN_JOYSTICK && *i <= BTN_THUMBR) || (*i >= BTN_WHEEL && *i <= BTN_GEAR_UP ) )
+		if( (*i >= BTN_JOYSTICK && *i < BTN_GAMEPAD)  
+			|| (*i >= BTN_GAMEPAD && *i < BTN_DIGI)
+			|| (*i >= BTN_WHEEL && *i < KEY_OK) )
 			joyButtonFound = true;
 
@@ -128,7 +195,11 @@
 
 		#ifdef OIS_LINUX_JOY_DEBUG
-		  cout << "\nButton Mapping ID (hex): " << hex << *i << " OIS Button Num: " << dec << (buttons-1);
+		  cout << "Button Mapping ID (hex): " << hex << *i 
+			   << " OIS Button Num: " << dec << buttons-1 << endl;
 		#endif
 	}
+	#ifdef OIS_LINUX_JOY_DEBUG
+	cout << endl;
+	#endif
 
 	//Joy Buttons found, so it must be a joystick or pad
@@ -140,20 +211,32 @@
 		js.axes = info.relAxes.size() + info.absAxes.size();
 		js.hats = info.hats.size();
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << endl << "Device name:" << js.vendor << endl;
+		  cout << "Device unique Id:" << getUniqueId(deviceID) << endl;
+		  cout << "Device physical location:" << getPhysicalLocation(deviceID) << endl;
+		#endif
 
 		//Map the Axes
 		#ifdef OIS_LINUX_JOY_DEBUG
-		  cout << "\n\nDisplaying AxisMapping Status:";
+		  cout << endl << "Displaying AxisMapping Status:" << endl;
 		#endif
 		int axes = 0;
-		for(std::vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )
+		for(vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )
 		{
 			js.axis_map[*i] = axes;
 
+#ifdef OIS_LINUX_JOY_DEBUG
+			cout << "EventUtils::isJoyStick(" << deviceID 
+					  << ") : Reading device absolute axis #" << *i << " features" << endl;
+#endif
+
 			input_absinfo absinfo;
-			ioctl(deviceID, EVIOCGABS(*i), &absinfo);
+			if (ioctl(deviceID, EVIOCGABS(*i), &absinfo) == -1)
+				OIS_EXCEPT( E_General, "Could not read device absolute axis features");
 			js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum);
 
 			#ifdef OIS_LINUX_JOY_DEBUG
-			  cout << "\nAxis Mapping ID (hex): " << hex << *i << " OIS Axis Num: " << dec << axes;
+			  cout << "Axis Mapping ID (hex): " << hex << *i 
+				   << " OIS Axis Num: " << dec << axes << endl;
 			#endif
 
@@ -166,9 +249,45 @@
 
 //-----------------------------------------------------------------------------//
-std::string EventUtils::getName( int deviceID )
-{
+string EventUtils::getName( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getName(" << deviceID 
+		 << ") : Reading device name" << endl;
+#endif
+
 	char name[OIS_DEVICE_NAME];
-	ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name);
-	return std::string(name);
+	if (ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name) == -1)
+		OIS_EXCEPT( E_General, "Could not read device name");
+	return string(name);
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getUniqueId( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getUniqueId(" << deviceID 
+		 << ") : Reading device unique Id" << endl;
+#endif
+
+#define OIS_DEVICE_UNIQUE_ID 128
+	char uId[OIS_DEVICE_UNIQUE_ID];
+	if (ioctl(deviceID, EVIOCGUNIQ(OIS_DEVICE_UNIQUE_ID), uId) == -1)
+		OIS_EXCEPT( E_General, "Could not read device unique Id");
+	return string(uId);
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getPhysicalLocation( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getPhysicalLocation(" << deviceID 
+		 << ") : Reading device physical location" << endl;
+#endif
+
+#define OIS_DEVICE_PHYSICAL_LOCATION 128
+	char physLoc[OIS_DEVICE_PHYSICAL_LOCATION];
+	if (ioctl(deviceID, EVIOCGPHYS(OIS_DEVICE_PHYSICAL_LOCATION), physLoc) == -1)
+		OIS_EXCEPT( E_General, "Could not read device physical location");
+	return string(physLoc);
 }
 
@@ -177,5 +296,5 @@
 {
 	//Linux Event to OIS Event Mappings
-	std::map<int, Effect::EType> typeMap;
+	map<int, Effect::EType> typeMap;
 	typeMap[FF_CONSTANT] = Effect::Constant;
 	typeMap[FF_RAMP]     = Effect::Ramp;
@@ -191,41 +310,71 @@
 	typeMap[FF_CUSTOM]   = Effect::Custom;
 
-	std::map<int, Effect::EForce> forceMap;
+	map<int, Effect::EForce> forceMap;
 	forceMap[FF_CONSTANT] = Effect::ConstantForce;
-	forceMap[FF_RAMP] = Effect::RampForce;
-	forceMap[FF_PERIODIC] = Effect::PeriodicForce;
-	forceMap[FF_CUSTOM] = Effect::CustomForce;
+	forceMap[FF_RAMP]     = Effect::RampForce;
+	forceMap[FF_SPRING]   = Effect::ConditionalForce;
+	forceMap[FF_FRICTION] = Effect::ConditionalForce;
+	forceMap[FF_SQUARE]   = Effect::PeriodicForce;
+	forceMap[FF_TRIANGLE] = Effect::PeriodicForce;
+	forceMap[FF_SINE]     = Effect::PeriodicForce;
+	forceMap[FF_SAW_UP]   = Effect::PeriodicForce;
+	forceMap[FF_SAW_DOWN] = Effect::PeriodicForce;
+	forceMap[FF_DAMPER]   = Effect::ConditionalForce;
+	forceMap[FF_INERTIA]  = Effect::ConditionalForce;
+	forceMap[FF_CUSTOM]   = Effect::CustomForce;
 
 	//Remove any previously existing memory and create fresh
 	removeForceFeedback( ff );
-	*ff = new LinuxForceFeedback();
-
-	unsigned long info[4] = {0,0,0,0};
-	unsigned long subinfo[4]= {0,0,0,0};
-
-	//Read overall force feedback components of the device
-	ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(long)*4), info);
+	*ff = new LinuxForceFeedback(deviceID);
+
+	//Read overall force feedback features
+	unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)];
+	memset(ff_bits, 0, sizeof(ff_bits));
+
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::enumerateForceFeedback(" << deviceID 
+		 << ") : Reading device force feedback features" << endl;
+#endif
+
+	if (ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(ff_bits)), ff_bits) == -1)
+		OIS_EXCEPT( E_General, "Could not read device force feedback features");
+
+
+    #ifdef OIS_LINUX_JOY_DEBUG
+	cout << "FF bits: " << hex;
+	for (int i = 0; i < sizeof(ff_bits); i++)
+		cout << (int)ff_bits[i];
+	cout << endl << dec;
+    #endif
 
 	//FF Axes
-	//if( isBitSet(info, ABS_X) ) //X Axis
-	//if( isBitSet(info, ABS_Y) ) //Y Axis
-	//if( isBitSet(info, ABS_WHEEL) ) //Wheel
+	//if( isBitSet(ff_bits, ABS_X) ) //X Axis
+	//if( isBitSet(ff_bits, ABS_Y) ) //Y Axis
+	//if( isBitSet(ff_bits, ABS_WHEEL) ) //Wheel
 
 	//FF Effects
-	for( int effect = ABS_WHEEL+1; effect < FF_MAX; effect++ )
+	for( int effect = FF_EFFECT_MIN; effect <= FF_WAVEFORM_MAX; effect++ )
 	{
-		if(isBitSet(info, effect))
+		// The RUMBLE force type is ignored, as periodic force one is more powerfull.
+		// The PERIODIC force type is processed later, for each associated periodic effect type.
+		if (effect == FF_RUMBLE || effect == FF_PERIODIC)
+			continue;
+
+		if(isBitSet(ff_bits, effect))
 		{
-			//std::cout << "\tEffect Type: " << effect << std::endl;
-			memset(subinfo, 0, sizeof(subinfo));
-			//Read any info about this supported effect
-			ioctl(deviceID, EVIOCGBIT(effect, sizeof(long)*4), subinfo);
-			for( int force = 0; force < FF_MAX; force++ )
-			{
-				if(isBitSet(subinfo, force))
-					(*ff)->_addEffectTypes( forceMap[force], typeMap[effect] );
-			}
+			#ifdef OIS_LINUX_JOY_DEBUG
+		    cout << "  Effect Type: " << Effect::getEffectTypeName(typeMap[effect]) << endl;
+			#endif
+
+			(*ff)->_addEffectTypes( forceMap[effect], typeMap[effect] );
 		}
 	}
+
+	//FF device properties
+	if (isBitSet(ff_bits, FF_GAIN))
+		(*ff)->_setGainSupport(true);
+		
+	if (isBitSet(ff_bits, FF_AUTOCENTER))
+		(*ff)->_setAutoCenterSupport(true);
 
 	//Check to see if any effects were added, else destroy the pointer
Index: code/trunk/src/ois/linux/EventHelpers.h
===================================================================
--- code/trunk/src/ois/linux/EventHelpers.h	(revision 5693)
+++ code/trunk/src/ois/linux/EventHelpers.h	(revision 5695)
@@ -43,4 +43,6 @@
 
 		static std::string getName( int deviceID );
+		static std::string getUniqueId( int deviceID );
+		static std::string getPhysicalLocation( int deviceID );
 	};
 }
Index: code/trunk/src/ois/linux/LinuxForceFeedback.cpp
===================================================================
--- code/trunk/src/ois/linux/LinuxForceFeedback.cpp	(revision 5693)
+++ code/trunk/src/ois/linux/LinuxForceFeedback.cpp	(revision 5695)
@@ -24,38 +24,536 @@
 #include "OISException.h"
 
+#include <cstdlib>
+#include <errno.h>
+#include <memory.h>
+
 using namespace OIS;
 
-//--------------------------------------------------------------//
-LinuxForceFeedback::LinuxForceFeedback()
-{
-}
+// 0 = No trace; 1 = Important traces; 2 = Debug traces
+#define OIS_LINUX_JOYFF_DEBUG 1
+
+#ifdef OIS_LINUX_JOYFF_DEBUG
+# include <iostream>
+  using namespace std;
+#endif
+
+//--------------------------------------------------------------//
+LinuxForceFeedback::LinuxForceFeedback(int deviceID) :
+	ForceFeedback(), mJoyStick(deviceID)
+{
+}
+
 //--------------------------------------------------------------//
 LinuxForceFeedback::~LinuxForceFeedback()
 {
-}
-
-//--------------------------------------------------------------//
-void LinuxForceFeedback::setMasterGain(float)
-{
-}
-
-//--------------------------------------------------------------//
-void LinuxForceFeedback::setAutoCenterMode(bool)
-{
-}
-
-//--------------------------------------------------------------//
-void LinuxForceFeedback::upload( const Effect* /*effect*/ )
-{
-}
-
-//--------------------------------------------------------------//
-void LinuxForceFeedback::modify( const Effect* /*effect*/ )
-{
-}
-
-//--------------------------------------------------------------//
-void LinuxForceFeedback::remove( const Effect* /*effect*/ )
-{
-}
-
+	// Unload all effects.
+	for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i )
+	{
+		struct ff_effect *linEffect = i->second;
+		if( linEffect )
+			_unload(linEffect->id);
+	}
+
+	mEffectList.clear();
+}
+
+//--------------------------------------------------------------//
+unsigned short LinuxForceFeedback::getFFMemoryLoad()
+{
+	int nEffects = -1;
+	if (ioctl(mJoyStick, EVIOCGEFFECTS, &nEffects) == -1)
+		OIS_EXCEPT(E_General, "Unknown error reading max number of uploaded effects.");
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "LinuxForceFeedback("<< mJoyStick  
+		 << ") : Read device max number of uploaded effects : " << nEffects << endl;
+#endif
+
+	return (unsigned short int)(nEffects > 0 ? 100.0*mEffectList.size()/nEffects : 100);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::setMasterGain(float value)
+{
+	if (!mSetGainSupport)
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+		cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain " 
+			 << "is not supported by the device" << endl;
+#endif
+		return;
+	}
+
+	struct input_event event;
+
+	memset(&event, 0, sizeof(event));
+	event.type = EV_FF;
+	event.code = FF_GAIN;
+	if (value < 0.0)
+		value = 0.0;
+	else if (value > 1.0)
+		value = 1.0;
+	event.value = (__s32)(value * 0xFFFFUL);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+	cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain to " 
+		 << value << " => " << event.value << endl;
+#endif
+
+	if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) {
+		OIS_EXCEPT(E_General, "Unknown error changing master gain.");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::setAutoCenterMode(bool enabled)
+{
+	if (!mSetAutoCenterSupport)
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+		cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting auto-center mode " 
+			 << "is not supported by the device" << endl;
+#endif
+		return;
+	}
+
+	struct input_event event;
+
+	memset(&event, 0, sizeof(event));
+	event.type = EV_FF;
+	event.code = FF_AUTOCENTER;
+	event.value = (__s32)(enabled*0xFFFFFFFFUL);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+	cout << "LinuxForceFeedback("<< mJoyStick << ") : Toggling auto-center to " 
+		 << enabled << " => 0x" << hex << event.value << dec << endl;
+#endif
+
+	if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) {
+		OIS_EXCEPT(E_General, "Unknown error toggling auto-center.");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::upload( const Effect* effect )
+{
+	switch( effect->force )
+	{
+		case OIS::Effect::ConstantForce: 
+			_updateConstantEffect(effect);	
+			break;
+		case OIS::Effect::ConditionalForce: 
+			_updateConditionalEffect(effect);
+			break;
+		case OIS::Effect::PeriodicForce: 
+			_updatePeriodicEffect(effect);
+			break;
+		case OIS::Effect::RampForce: 
+			_updateRampEffect(effect);	
+			break;
+		case OIS::Effect::CustomForce: 
+			//_updateCustomEffect(effect);
+			//break;
+		default: 
+			OIS_EXCEPT(E_NotImplemented, "Requested force not implemented yet, sorry!"); 
+			break;
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::modify( const Effect* effect )
+{
+	upload(effect);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::remove( const Effect* effect )
+{
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	if( i != mEffectList.end() )
+	{
+		struct ff_effect *linEffect = i->second;
+		if( linEffect )
+		{
+			_stop(effect->_handle);
+
+			_unload(effect->_handle);
+
+			free(linEffect);
+
+			mEffectList.erase(i);
+		}
+		else
+			mEffectList.erase(i);
+	}
+}
+
+//--------------------------------------------------------------//
+// To Signed16/Unsigned15 safe conversions
+#define MaxUnsigned15Value 0x7FFF
+#define toUnsigned15(value) \
+	(__u16)((value) < 0 ? 0 : ((value) > MaxUnsigned15Value ? MaxUnsigned15Value : (value)))
+
+#define MaxSigned16Value  0x7FFF
+#define MinSigned16Value -0x7FFF
+#define toSigned16(value) \
+  (__s16)((value) < MinSigned16Value ? MinSigned16Value : ((value) > MaxSigned16Value ? MaxSigned16Value : (value)))
+
+// OIS to Linux duration
+#define LinuxInfiniteDuration 0xFFFF
+#define OISDurationUnitMS 1000 // OIS duration unit (microseconds), expressed in milliseconds (theLinux duration unit)
+
+// linux/input.h : All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+//                 should not be used and have unspecified results.
+#define LinuxDuration(oisDuration) ((oisDuration) == Effect::OIS_INFINITE ? LinuxInfiniteDuration \
+									: toUnsigned15((oisDuration)/OISDurationUnitMS))
+
+
+// OIS to Linux levels
+#define OISMaxLevel 10000
+#define LinuxMaxLevel 0x7FFF
+
+// linux/input.h : Valid range for the attack and fade levels is 0x0000 - 0x7fff
+#define LinuxPositiveLevel(oisLevel) toUnsigned15(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel)
+
+#define LinuxSignedLevel(oisLevel) toSigned16(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel)
+
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_setCommonProperties(struct ff_effect *event, 
+											  struct ff_envelope *ffenvelope, 
+											  const Effect* effect, const Envelope *envelope )
+{
+	memset(event, 0, sizeof(struct ff_effect));
+
+	if (envelope && ffenvelope && envelope->isUsed()) {
+		ffenvelope->attack_length = LinuxDuration(envelope->attackLength);
+		ffenvelope->attack_level = LinuxPositiveLevel(envelope->attackLevel);
+		ffenvelope->fade_length = LinuxDuration(envelope->fadeLength);
+		ffenvelope->fade_level = LinuxPositiveLevel(envelope->fadeLevel);
+	}
+	
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl;
+	if (envelope && ffenvelope)
+	{
+		cout << "  Enveloppe :" << endl
+			 << "    AttackLen : " << envelope->attackLength
+			 << " => " << ffenvelope->attack_length << endl 
+			 << "    AttackLvl : " << envelope->attackLevel
+			 << " => " << ffenvelope->attack_level << endl 
+			 << "    FadeLen   : " << envelope->fadeLength
+			 << " => " << ffenvelope->fade_length << endl
+			 << "    FadeLvl   : " << envelope->fadeLevel
+			 << " => " << ffenvelope->fade_level << endl;
+	}
+#endif
+	
+	event->direction = (__u16)(1 + (effect->direction*45.0+135.0)*0xFFFFUL/360.0);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
+		 << " => 0x" << hex << event->direction << dec << endl;
+#endif
+
+	// TODO trigger_button 0 vs. -1
+	event->trigger.button = effect->trigger_button; // < 0 ? 0 : effect->trigger_button;
+	event->trigger.interval = LinuxDuration(effect->trigger_interval);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Trigger :" << endl
+		 << "    Button   : " << effect->trigger_button 
+		 << " => " << event->trigger.button << endl
+		 << "    Interval : " << effect->trigger_interval 
+		 << " => " << event->trigger.interval << endl;
+#endif
+
+	event->replay.length = LinuxDuration(effect->replay_length);
+	event->replay.delay = LinuxDuration(effect->replay_delay);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Replay :" << endl
+		 << "    Length : " << effect->replay_length 
+		 << " => " << event->replay.length << endl
+		 << "    Delay  : " << effect->replay_delay 
+		 << " => " << event->replay.delay << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateConstantEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	ConstantEffect *effect = static_cast<ConstantEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope);
+
+	event.type = FF_CONSTANT;
+	event.id = -1;
+
+	event.u.constant.level = LinuxSignedLevel(effect->level);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Level : " << effect->level
+		 << " => " << event.u.constant.level << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateRampEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	RampEffect *effect = static_cast<RampEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope);
+
+	event.type = FF_RAMP;
+	event.id = -1;
+
+	event.u.ramp.start_level = LinuxSignedLevel(effect->startLevel);
+	event.u.ramp.end_level = LinuxSignedLevel(effect->endLevel);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  StartLevel : " << effect->startLevel
+		 << " => " << event.u.ramp.start_level << endl
+		 << "  EndLevel   : " << effect->endLevel
+		 << " => " << event.u.ramp.end_level << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updatePeriodicEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	PeriodicEffect *effect = static_cast<PeriodicEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.periodic.envelope, eff, &effect->envelope);
+
+	event.type = FF_PERIODIC;
+	event.id = -1;
+
+	switch( eff->type )
+	{
+		case OIS::Effect::Square:
+			event.u.periodic.waveform = FF_SQUARE;
+			break;
+		case OIS::Effect::Triangle:
+			event.u.periodic.waveform = FF_TRIANGLE;
+			break;
+		case OIS::Effect::Sine:
+			event.u.periodic.waveform = FF_SINE;
+			break;
+		case OIS::Effect::SawToothUp:
+			event.u.periodic.waveform = FF_SAW_UP;
+			break;
+		case OIS::Effect::SawToothDown:
+			event.u.periodic.waveform = FF_SAW_DOWN;
+			break;
+		// Note: No support for Custom periodic force effect for the moment
+		//case OIS::Effect::Custom:
+			//event.u.periodic.waveform = FF_CUSTOM;
+			//break;
+		default:
+			OIS_EXCEPT(E_General, "No such available effect for Periodic force!"); 
+			break;
+	}
+
+	event.u.periodic.period    = LinuxDuration(effect->period);
+	event.u.periodic.magnitude = LinuxPositiveLevel(effect->magnitude);
+	event.u.periodic.offset    = LinuxPositiveLevel(effect->offset);
+	event.u.periodic.phase     = (__u16)(effect->phase*event.u.periodic.period/36000.0); // ?????
+
+	// Note: No support for Custom periodic force effect for the moment
+	event.u.periodic.custom_len = 0;
+	event.u.periodic.custom_data = 0;
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Magnitude : " << effect->magnitude
+		 << " => " << event.u.periodic.magnitude << endl
+		 << "  Period    : " << effect->period
+		 << " => " << event.u.periodic.period  << endl
+		 << "  Offset    : " << effect->offset
+		 << " => " << event.u.periodic.offset << endl
+		 << "  Phase     : " << effect->phase
+		 << " => " << event.u.periodic.phase << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateConditionalEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	ConditionalEffect *effect = static_cast<ConditionalEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, NULL, eff, NULL);
+
+	switch( eff->type )
+	{
+		case OIS::Effect::Friction:
+			event.type = FF_FRICTION; 
+			break;
+		case OIS::Effect::Damper:
+			event.type = FF_DAMPER; 
+			break;
+		case OIS::Effect::Inertia:
+			event.type = FF_INERTIA; 
+			break;
+		case OIS::Effect::Spring:
+			event.type = FF_SPRING;
+			break;
+		default:
+			OIS_EXCEPT(E_General, "No such available effect for Conditional force!"); 
+			break;
+	}
+
+	event.id = -1;
+
+	event.u.condition[0].right_saturation = LinuxSignedLevel(effect->rightSaturation);
+	event.u.condition[0].left_saturation  = LinuxSignedLevel(effect->leftSaturation);
+	event.u.condition[0].right_coeff      = LinuxSignedLevel(effect->rightCoeff);
+	event.u.condition[0].left_coeff       = LinuxSignedLevel(effect->leftCoeff);
+	event.u.condition[0].deadband         = LinuxPositiveLevel(effect->deadband);// Unit ?? 
+	event.u.condition[0].center           = LinuxSignedLevel(effect->center); // Unit ?? TODO ?
+
+	// TODO support for second condition
+	event.u.condition[1] = event.u.condition[0];
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Condition[0] : " << endl
+		 << "    RightSaturation  : " << effect->rightSaturation
+		 << " => " << event.u.condition[0].right_saturation << endl
+		 << "    LeftSaturation   : " << effect->leftSaturation
+		 << " => " << event.u.condition[0]. left_saturation << endl
+		 << "    RightCoefficient : " << effect->rightCoeff
+		 << " => " << event.u.condition[0].right_coeff << endl
+		 << "    LeftCoefficient : " << effect->leftCoeff
+		 << " => " << event.u.condition[0].left_coeff << endl
+		 << "    DeadBand        : " << effect->deadband
+		 << " => " << event.u.condition[0].deadband  << endl
+		 << "    Center          : " << effect->center
+		 << " => " << event.u.condition[0].center << endl;
+	cout << "  Condition[1] : Not implemented" << endl;
+#endif
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_upload( struct ff_effect* ffeffect, const Effect* effect)
+{
+	struct ff_effect *linEffect = 0;
+
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	//It has been created already
+	if( i != mEffectList.end() )
+		linEffect = i->second;
+
+	if( linEffect == 0 )
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+		cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Adding new effect : " 
+			 << Effect::getEffectTypeName(effect->type) << endl;
+#endif
+
+		//This effect has not yet been created, so create it in the device
+		if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) {
+			// TODO device full check
+			// OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!");
+			OIS_EXCEPT(E_General, "Unknown error creating effect (may be the device is full)->..");
+		}
+
+		// Save returned effect handle
+		effect->_handle = ffeffect->id;
+
+		// Save a copy of the uploaded effect for later simple modifications
+		linEffect = (struct ff_effect *)calloc(1, sizeof(struct ff_effect));
+		memcpy(linEffect, ffeffect, sizeof(struct ff_effect));
+
+		mEffectList[effect->_handle] = linEffect;
+
+		// Start playing the effect.
+		_start(effect->_handle);
+	}
+	else
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+		cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Replacing effect : " 
+			 << Effect::getEffectTypeName(effect->type) << endl;
+#endif
+
+		// Keep same id/handle, as this is just an update in the device.
+		ffeffect->id = effect->_handle;
+
+		// Update effect in the device.
+		if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) {
+			OIS_EXCEPT(E_General, "Unknown error updating an effect->..");
+		}
+
+		// Update local linEffect for next time.
+		memcpy(linEffect, ffeffect, sizeof(struct ff_effect));
+	}
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Effect handle : " << effect->_handle << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_stop( int handle) {
+	struct input_event stop;
+
+	stop.type = EV_FF;
+	stop.code = handle;
+	stop.value = 0;
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Stopping effect with handle " << handle << endl;
+#endif
+
+	if (write(mJoyStick, &stop, sizeof(stop)) != sizeof(stop)) {
+		OIS_EXCEPT(E_General, "Unknown error stopping effect->..");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_start( int handle) {
+	struct input_event play;
+
+	play.type = EV_FF;
+	play.code = handle;
+	play.value = 1; // Play once.
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Starting effect with handle " << handle << endl;
+#endif
+
+	if (write(mJoyStick, &play, sizeof(play)) != sizeof(play)) {
+		OIS_EXCEPT(E_General, "Unknown error playing effect->..");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_unload( int handle)
+{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Removing effect with handle " << handle << endl;
+#endif
+
+	if (ioctl(mJoyStick, EVIOCRMFF, handle) == -1) {
+		OIS_EXCEPT(E_General, "Unknown error removing effect->..");
+	}
+}
Index: code/trunk/src/ois/linux/LinuxForceFeedback.h
===================================================================
--- code/trunk/src/ois/linux/LinuxForceFeedback.h	(revision 5693)
+++ code/trunk/src/ois/linux/LinuxForceFeedback.h	(revision 5695)
@@ -26,4 +26,5 @@
 #include "linux/LinuxPrereqs.h"
 #include "OISForceFeedback.h"
+#include <linux/input.h>
 
 namespace OIS
@@ -32,5 +33,5 @@
 	{
 	public:
-		LinuxForceFeedback();
+		LinuxForceFeedback(int deviceID);
 		~LinuxForceFeedback();
 
@@ -50,6 +51,34 @@
 		void remove( const Effect* effect );
 
-		/** FF is not yet implemented fully on Linux.. just retun 0 for now. todo, xxx */
-		short int getFFAxesNumber() { return 0; }
+		/** FF is not yet implemented fully on Linux.. just return -1 for now. todo, xxx */
+		short int getFFAxesNumber() { return -1; }
+
+		/** @copydoc ForceFeedback::getFFMemoryLoad */
+		unsigned short getFFMemoryLoad();
+
+	protected:
+
+		//Sets the common properties to all effects
+		void _setCommonProperties(struct ff_effect *event, struct ff_envelope *ffenvelope, 
+								  const Effect* effect, const Envelope *envelope );
+
+		//Specific Effect Settings
+		void _updateConstantEffect( const Effect* effect );
+		void _updateRampEffect( const Effect* effect );
+		void _updatePeriodicEffect( const Effect* effect );
+		void _updateConditionalEffect( const Effect* effect );
+		//void _updateCustomEffect( const Effect* effect );
+
+		void _upload( struct ff_effect* ffeffect, const Effect* effect);
+		void _stop( int handle);
+		void _start( int handle);
+		void _unload( int handle);
+
+		// Map of currently uploaded effects (handle => effect)
+		typedef std::map<int, struct ff_effect *> EffectList;
+		EffectList mEffectList;
+
+		// Joystick device (file) descriptor.
+		int mJoyStick;
 	};
 }
Index: code/trunk/src/ois/linux/LinuxJoyStickEvents.cpp
===================================================================
--- code/trunk/src/ois/linux/LinuxJoyStickEvents.cpp	(revision 5693)
+++ code/trunk/src/ois/linux/LinuxJoyStickEvents.cpp	(revision 5695)
@@ -37,13 +37,10 @@
 
 #include <sstream>
+# include <iostream>
+using namespace std;
 
 using namespace OIS;
 
 //#define OIS_LINUX_JOY_DEBUG
-
-#ifdef OIS_LINUX_JOY_DEBUG
-# include <iostream>
-  using namespace std;
-#endif
 
 //-------------------------------------------------------------------//
@@ -114,5 +111,5 @@
 
 			#ifdef OIS_LINUX_JOY_DEBUG
-			  std::cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << std::endl;
+			  cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << endl;
 			#endif
 
@@ -132,5 +129,6 @@
 			break;
 		}
-		case EV_ABS:  //Absoulte Axis
+
+		case EV_ABS:  //Absolute Axis
 		{
 			//A Stick (BrakeDefine is the highest possible Axis)
@@ -138,6 +136,6 @@
 			{
 				int axis = mAxisMap[js[i].code];
-				assert( axis < 32 && "Too many axes, not supported. Report this to OIS forums!" );
-				
+				assert( axis < 32 && "Too many axes (Max supported is 32). Report this to OIS forums!" );
+
 				axisMoved[axis] = true;
 
@@ -190,6 +188,11 @@
 			break;
 		}
-		//Relative Axes (Do any joysticks actually have a relative axis?)
-		case EV_REL:
+
+		
+		case EV_REL: //Relative Axes (Do any joystick actually have a relative axis?)
+#ifdef OIS_LINUX_JOY_DEBUG
+		    cout << "\nWarning: Relatives axes not supported yet" << endl;
+#endif
+			break;
 		default: break;
 		}
@@ -243,12 +246,12 @@
 	for(int i = 0; i < 64; ++i )
 	{
-		std::stringstream s;
+		stringstream s;
 		s << "/dev/input/event" << i;
-		int fd = open( s.str().c_str(), O_RDONLY |O_NONBLOCK );
+		int fd = open( s.str().c_str(), O_RDWR |O_NONBLOCK );
 		if(fd == -1)
 			continue;
-		
+
         #ifdef OIS_LINUX_JOY_DEBUG
-          std::cout << "\nOpening " << s.str() << "...";
+		  cout << "Opening " << s.str() << "..." << endl;
         #endif
 		try
@@ -259,5 +262,5 @@
 				joys.push_back(js);
                 #ifdef OIS_LINUX_JOY_DEBUG
-                  std::cout << "\n__Joystick added to list";
+                  cout << "=> Joystick added to list." << endl;
                 #endif
 			}
@@ -265,5 +268,5 @@
 			{
                 #ifdef OIS_LINUX_JOY_DEBUG
-                  std::cout << "\n__Not a joystick!!";
+                  cout << "=> Not a joystick." << endl;
                 #endif
 				close(fd);
@@ -273,5 +276,5 @@
 		{
             #ifdef OIS_LINUX_JOY_DEBUG
-              std::cout << "\nException caught!!";
+              cout << "Exception caught!!" << endl;
             #endif
 			close(fd);
Index: code/trunk/src/ois/win32/Win32ForceFeedback.cpp
===================================================================
--- code/trunk/src/ois/win32/Win32ForceFeedback.cpp	(revision 5693)
+++ code/trunk/src/ois/win32/Win32ForceFeedback.cpp	(revision 5695)
@@ -25,6 +25,11 @@
 #include <Math.h>
 
-#if defined (_DEBUG)
+// 0 = No trace; 1 = Important traces; 2 = Debug traces
+#define OIS_WIN32_JOYFF_DEBUG 1
+
+#if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG))
+  #include <iostream>
   #include <sstream>
+  using namespace std;
 #endif
 
@@ -32,7 +37,12 @@
 
 //--------------------------------------------------------------//
-Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* joy) :
-	mHandles(0), mJoyStick(joy)
-{
+Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps) :
+  mHandles(0), mJoyStick(pDIJoy), mFFAxes(0), mpDIJoyCaps(pDIJoyCaps)
+{
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+  cout << "FFSamplePeriod      : " << mpDIJoyCaps->dwFFSamplePeriod << " mu-s, "
+	   << "FFMinTimeResolution : " << mpDIJoyCaps->dwFFMinTimeResolution << " mu-s,"
+	   << "" << endl;
+#endif
 }
 
@@ -45,8 +55,39 @@
 		LPDIRECTINPUTEFFECT dxEffect = i->second;
 		if( dxEffect )
+		{
 			dxEffect->Unload();
+			dxEffect->Release();
+		}
 	}
 
 	mEffectList.clear();
+}
+
+//--------------------------------------------------------------//
+short Win32ForceFeedback::getFFAxesNumber()
+{
+	return mFFAxes;
+}
+
+//--------------------------------------------------------------//
+unsigned short Win32ForceFeedback::getFFMemoryLoad()
+{
+    DIPROPDWORD dipdw;  // DIPROPDWORD contains a DIPROPHEADER structure. 
+	dipdw.diph.dwSize       = sizeof(DIPROPDWORD); 
+	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
+	dipdw.diph.dwObj        = 0; // device property 
+	dipdw.diph.dwHow        = DIPH_DEVICE;
+	dipdw.dwData            = 0; // In case of any error.
+
+	const HRESULT hr = mJoyStick->GetProperty(DIPROP_FFLOAD, &dipdw.diph);
+	if(FAILED(hr))
+	{
+	    if (hr == DIERR_NOTEXCLUSIVEACQUIRED)
+		    OIS_EXCEPT(E_General, "Can't query FF memory load as device was not acquired in exclusive mode");
+		else
+		    OIS_EXCEPT(E_General, "Unknown error querying FF memory load ->..");
+	}
+
+	return (unsigned short)dipdw.dwData;
 }
 
@@ -86,5 +127,8 @@
 			//have been unlaoded
 			if( SUCCEEDED(dxEffect->Unload()) )
+			{
+			    dxEffect->Release();
 				mEffectList.erase(i);
+			}
 		}
 		else
@@ -111,5 +155,15 @@
 	DIPropGain.dwData            = gain_level;
 
-	mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph);
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting master gain to " 
+		 << level << " => " << DIPropGain.dwData << endl;
+#endif
+
+	const HRESULT hr = mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph);
+
+#if defined (_DEBUG)
+	if(FAILED(hr))
+	    cout << "Failed to change master gain" << endl;
+#endif
 }
 
@@ -117,5 +171,4 @@
 void Win32ForceFeedback::setAutoCenterMode( bool auto_on )
 {
-	//DI Property DIPROPAUTOCENTER_OFF = 0, 1 is on
 	DIPROPDWORD DIPropAutoCenter;
 	DIPropAutoCenter.diph.dwSize       = sizeof(DIPropAutoCenter);
@@ -123,8 +176,17 @@
 	DIPropAutoCenter.diph.dwObj        = 0;
 	DIPropAutoCenter.diph.dwHow        = DIPH_DEVICE;
-	DIPropAutoCenter.dwData            = auto_on;
-
-	//hr =
-	mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
+	DIPropAutoCenter.dwData            = (auto_on ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF);
+
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting auto-center mode to " 
+		 << auto_on << " => " << DIPropAutoCenter.dwData << endl;
+#endif
+
+	const HRESULT hr = mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
+
+#if defined (_DEBUG)
+	if(FAILED(hr))
+	    cout << "Failed to change auto-center mode" << endl;
+#endif
 }
 
@@ -132,6 +194,9 @@
 void Win32ForceFeedback::_updateConstantEffect( const Effect* effect )
 {
+	ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect());
+
 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
 	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
 	DICONSTANTFORCE cf;
 	DIEFFECT        diEffect;
@@ -139,7 +204,12 @@
 	//Currently only support 1 axis
 	//if( effect->getNumAxes() == 1 )
-	cf.lMagnitude = static_cast<ConstantEffect*>(effect->getForceEffect())->level;
-
-	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONSTANTFORCE), &cf, effect);
+	cf.lMagnitude = eff->level;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Level : " << eff->level
+		 << " => " << cf.lMagnitude << endl;
+#endif
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONSTANTFORCE), &cf, effect, &eff->envelope);
 	_upload(GUID_ConstantForce, &diEffect, effect);
 }
@@ -148,14 +218,17 @@
 void Win32ForceFeedback::_updateRampEffect( const Effect* effect )
 {
+	RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect());
+
 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
 	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
 	DIRAMPFORCE     rf;
 	DIEFFECT        diEffect;
 
 	//Currently only support 1 axis
-	rf.lStart = static_cast<RampEffect*>(effect->getForceEffect())->startLevel;
-	rf.lEnd = static_cast<RampEffect*>(effect->getForceEffect())->endLevel;
-
-	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIRAMPFORCE), &rf, effect);
+	rf.lStart = eff->startLevel;
+	rf.lEnd = eff->endLevel;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIRAMPFORCE), &rf, effect, &eff->envelope );
 	_upload(GUID_RampForce, &diEffect, effect);
 }
@@ -164,16 +237,19 @@
 void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect )
 {
+	PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect());
+
 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
 	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
 	DIPERIODIC      pf;
 	DIEFFECT        diEffect;
 
 	//Currently only support 1 axis
-	pf.dwMagnitude = static_cast<PeriodicEffect*>(effect->getForceEffect())->magnitude;
-	pf.lOffset = static_cast<PeriodicEffect*>(effect->getForceEffect())->offset;
-	pf.dwPhase = static_cast<PeriodicEffect*>(effect->getForceEffect())->phase;
-	pf.dwPeriod = static_cast<PeriodicEffect*>(effect->getForceEffect())->period;
-
-	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIPERIODIC), &pf, effect);
+	pf.dwMagnitude = eff->magnitude;
+	pf.lOffset = eff->offset;
+	pf.dwPhase = eff->phase;
+	pf.dwPeriod = eff->period;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIPERIODIC), &pf, effect, &eff->envelope );
 
 	switch( effect->type )
@@ -191,17 +267,20 @@
 void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect )
 {
+	ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect());
+
 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
 	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
 	DICONDITION     cf;
 	DIEFFECT        diEffect;
 
-	cf.lOffset = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband;
-	cf.lPositiveCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightCoeff;
-	cf.lNegativeCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftCoeff;
-	cf.dwPositiveSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightSaturation;
-	cf.dwNegativeSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftSaturation;
-	cf.lDeadBand = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband;
-
-	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONDITION), &cf, effect);
+	cf.lOffset = eff->deadband;
+	cf.lPositiveCoefficient = eff->rightCoeff;
+	cf.lNegativeCoefficient = eff->leftCoeff;
+	cf.dwPositiveSaturation = eff->rightSaturation;
+	cf.dwNegativeSaturation = eff->leftSaturation;
+	cf.lDeadBand = eff->deadband;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONDITION), &cf, effect, 0 );
 
 	switch( effect->type )
@@ -218,6 +297,9 @@
 void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ )
 {
+    //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect());
+    //
 	//DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
 	//LONG            rglDirection[2] = { 0, 0 };
+	//DIENVELOPE      diEnvelope;
 	//DICUSTOMFORCE cf;
 	//DIEFFECT        diEffect;
@@ -226,5 +308,5 @@
 	//cf.cSamples = 0;
 	//cf.rglForceData = 0;
-	//_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICUSTOMFORCE), &cf, effect);
+	//_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope);
 	//_upload(GUID_CustomForce, &diEffect, effect);
 }
@@ -233,6 +315,6 @@
 void Win32ForceFeedback::_setCommonProperties(
 		DIEFFECT* diEffect, DWORD* rgdwAxes,
-		LONG* rglDirection, DWORD struct_size,
-		LPVOID struct_type, const Effect* effect )
+		LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size,
+		LPVOID struct_type, const Effect* effect, const Envelope* envelope )
 {
 	ZeroMemory(diEffect, sizeof(DIEFFECT));
@@ -240,16 +322,71 @@
 	diEffect->dwSize                  = sizeof(DIEFFECT);
 	diEffect->dwFlags                 = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
+	diEffect->dwGain                  = DI_FFNOMINALMAX;
+
+	diEffect->dwTriggerButton         = DIEB_NOTRIGGER; // effect->trigger_button; // TODO: Conversion
+	diEffect->dwTriggerRepeatInterval = effect->trigger_interval;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Trigger :" << endl
+		 << "    Button   : " << effect->trigger_button 
+		 << " => " << diEffect->dwTriggerButton << endl
+		 << "    Interval : " << effect->trigger_interval 
+		 << " => " << diEffect->dwTriggerRepeatInterval << endl;
+#endif
+
+	diEffect->cAxes                   = 1; // effect->getNumAxes();
+	diEffect->rgdwAxes                = rgdwAxes;
+
+	diEffect->rglDirection            = rglDirection; // TODO: conversion from effect->direction
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
+		 << " => {";
+	for (int iDir=0; iDir < (int)diEffect->cAxes; iDir++)
+	  cout << " " << diEffect->rglDirection[iDir];
+	cout << "}" << endl;
+#endif
+
+	if (diEnvelope && envelope && envelope->isUsed())
+	{
+	    diEnvelope->dwSize = sizeof(DIENVELOPE);
+	    diEnvelope->dwAttackLevel = envelope->attackLevel;
+	    diEnvelope->dwAttackTime  = envelope->attackLength;
+	    diEnvelope->dwFadeLevel   = envelope->fadeLevel;
+	    diEnvelope->dwFadeTime    = envelope->fadeLength;
+	    diEffect->lpEnvelope = diEnvelope;
+	}
+	else
+	    diEffect->lpEnvelope = 0;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	if (diEnvelope && envelope && envelope->isUsed())
+	{
+		cout << "  Enveloppe :" << endl
+			 << "    AttackLen : " << envelope->attackLength
+			 << " => " << diEnvelope->dwAttackTime << endl 
+			 << "    AttackLvl : " << envelope->attackLevel
+			 << " => " << diEnvelope->dwAttackLevel << endl 
+			 << "    FadeLen   : " << envelope->fadeLength
+			 << " => " << diEnvelope->dwFadeTime << endl
+			 << "    FadeLvl   : " << envelope->fadeLevel
+			 << " => " << diEnvelope->dwFadeLevel << endl;
+	}
+#endif
+
+	diEffect->dwSamplePeriod          = 0;
 	diEffect->dwDuration              = effect->replay_length;
-	diEffect->dwSamplePeriod          = 0;
-	diEffect->dwGain                  = DI_FFNOMINALMAX;
-	diEffect->dwTriggerButton         = DIEB_NOTRIGGER;
-	diEffect->dwTriggerRepeatInterval = 0;
-	diEffect->cAxes                   = effect->getNumAxes();
-	diEffect->rgdwAxes                = rgdwAxes;
-	diEffect->rglDirection            = rglDirection;
-	diEffect->lpEnvelope              = 0;
+	diEffect->dwStartDelay            = effect->replay_delay;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Replay :" << endl
+		 << "    Length : " << effect->replay_length 
+		 << " => " << diEffect->dwDuration << endl
+		 << "    Delay  : " << effect->replay_delay 
+		 << " => " << diEffect->dwStartDelay << endl;
+#endif
+
 	diEffect->cbTypeSpecificParams    = struct_size;
 	diEffect->lpvTypeSpecificParams   = struct_type;
-	diEffect->dwStartDelay            = effect->replay_delay;
 }
 
@@ -295,31 +432,97 @@
 void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei )
 {
-	//Determine what the effect is and how it corresponds to our OIS's Enums
-	//We could save the GUIDs too, however, we will just use the predefined
-	//ones later
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+    // Dump some usefull information about the effect type.
+    cout << "Adding support for '" << pdei->tszName << "' effect type" << endl;
+	cout << "  Supported static params: ";
+	if (pdei->dwStaticParams & DIEP_AXES) cout << " Axes";
+	if (pdei->dwStaticParams & DIEP_DIRECTION) cout << " Direction";
+	if (pdei->dwStaticParams & DIEP_DURATION) cout << " Duration";
+	if (pdei->dwStaticParams & DIEP_ENVELOPE) cout << " Envelope";
+	if (pdei->dwStaticParams & DIEP_GAIN) cout << " Gain";
+	if (pdei->dwStaticParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
+	if (pdei->dwStaticParams & DIEP_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwStaticParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
+	if (pdei->dwStaticParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
+	if (pdei->dwStaticParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
+	cout << endl;
+	cout << "  Supported dynamic params: ";
+	if (pdei->dwDynamicParams & DIEP_AXES) cout << " Axes";
+	if (pdei->dwDynamicParams & DIEP_DIRECTION) cout << " Direction";
+	if (pdei->dwDynamicParams & DIEP_DURATION) cout << " Duration";
+	if (pdei->dwDynamicParams & DIEP_ENVELOPE) cout << " Envelope";
+	if (pdei->dwDynamicParams & DIEP_GAIN) cout << " Gain";
+	if (pdei->dwDynamicParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
+	if (pdei->dwDynamicParams & DIEP_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwDynamicParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
+	if (pdei->dwDynamicParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
+	if (pdei->dwDynamicParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
+	cout << endl;
+	cout << "  More details about supported parameters support: ";
+	if (pdei->dwEffType & DIEFT_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwEffType & DIEFT_FFATTACK) cout << " Attack";
+	if (pdei->dwEffType & DIEFT_FFFADE) cout << " Fade";
+	if (pdei->dwEffType & DIEFT_DEADBAND) cout << " DeadBand";
+	if (pdei->dwEffType & DIEFT_SATURATION) cout << " Saturation";
+	if (pdei->dwEffType & DIEFT_POSNEGSATURATION) cout << " PosNegaturation";
+	if (pdei->dwEffType & DIEFT_POSNEGCOEFFICIENTS) cout << " PosNegCoefficients";
+	if (pdei->dwEffType & DIEFT_HARDWARE) cout << " HardwareSpecific";
+	cout << endl;
+#endif
+
+    Effect::EForce eForce;
+	switch (DIEFT_GETTYPE(pdei->dwEffType))
+	{
+	    case DIEFT_CONSTANTFORCE:
+		    eForce = Effect::ConstantForce;
+			break;
+	    case DIEFT_RAMPFORCE:
+		    eForce = Effect::RampForce;
+			break;
+	    case DIEFT_PERIODIC:
+		    eForce = Effect::PeriodicForce;
+			break;
+	    case DIEFT_CONDITION:
+		    eForce = Effect::ConditionalForce;
+			break;
+	    case DIEFT_CUSTOMFORCE:
+		    eForce = Effect::CustomForce;
+			break;
+	    default:
+		    eForce = Effect::UnknownForce;
+#if defined (_DEBUG)
+			cout << "Win32ForceFeedback: DirectInput8 Effect type support not implemented: " 
+				 << "DIEFT_GETTYPE="<< (int)DIEFT_GETTYPE(pdei->dwEffType) << endl;
+#endif
+			return;
+	}
+
+	//Determine what the effect type is and how it corresponds to our OIS's Enums
+	//We could save the GUIDs too, however, we will just use the predefined ones later
 	if( pdei->guid == GUID_ConstantForce )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Constant );
+		_addEffectTypes(eForce, Effect::Constant );
 	else if( pdei->guid == GUID_Triangle )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Triangle );
+		_addEffectTypes(eForce, Effect::Triangle );
 	else if( pdei->guid == GUID_Spring )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Spring );
+		_addEffectTypes(eForce, Effect::Spring );
 	else if( pdei->guid == GUID_Friction )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Friction );
+		_addEffectTypes(eForce, Effect::Friction );
 	else if( pdei->guid == GUID_Square )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Square );
+		_addEffectTypes(eForce, Effect::Square );
 	else if( pdei->guid == GUID_Sine )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Sine );
+		_addEffectTypes(eForce, Effect::Sine );
 	else if( pdei->guid == GUID_SawtoothUp )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothUp );
+		_addEffectTypes(eForce, Effect::SawToothUp );
 	else if( pdei->guid == GUID_SawtoothDown )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothDown );
+		_addEffectTypes(eForce, Effect::SawToothDown );
 	else if( pdei->guid == GUID_Damper )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Damper );
+		_addEffectTypes(eForce, Effect::Damper );
 	else if( pdei->guid == GUID_Inertia )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Inertia );
+		_addEffectTypes(eForce, Effect::Inertia );
 	else if( pdei->guid == GUID_CustomForce )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Custom );
+		_addEffectTypes(eForce, Effect::Custom );
 	else if( pdei->guid == GUID_RampForce )
-		_addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Ramp );
+		_addEffectTypes(eForce, Effect::Ramp );
+
 #if defined (_DEBUG)
 	//Only care about this for Debugging Purposes
@@ -333,2 +536,8 @@
 #endif
 }
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_addFFAxis()
+{
+	mFFAxes++;
+}
Index: code/trunk/src/ois/win32/Win32ForceFeedback.h
===================================================================
--- code/trunk/src/ois/win32/Win32ForceFeedback.h	(revision 5693)
+++ code/trunk/src/ois/win32/Win32ForceFeedback.h	(revision 5695)
@@ -34,5 +34,5 @@
 		Win32ForceFeedback() {}
 	public:
-		Win32ForceFeedback(IDirectInputDevice8* joy);
+		Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps);
 		~Win32ForceFeedback();
 
@@ -52,8 +52,9 @@
 		void setAutoCenterMode( bool auto_on );
 
-		/** @copydoc ForceFeedback::getFFAxesNumber 
-			xxx todo - Actually return correct number
-		*/
-		short getFFAxesNumber() {return 1;}
+		/** @copydoc ForceFeedback::getFFAxesNumber */
+		short getFFAxesNumber();
+
+		/** @copydoc ForceFeedback::getFFMemoryLoad */
+		unsigned short getFFMemoryLoad();
 
 		/**
@@ -64,5 +65,13 @@
 		void _addEffectSupport( LPCDIEFFECTINFO pdei );
 
+		/**
+			@remarks
+			Internal use.. Used during axis enumeration to get number of FF axes
+			support effects.
+		*/
+		void _addFFAxis();
+
 	protected:
+
 		//Specific Effect Settings
 		void _updateConstantEffect( const Effect* effect );
@@ -71,18 +80,28 @@
 		void _updateConditionalEffect( const Effect* effect );
 		void _updateCustomEffect( const Effect* effect );
+
 		//Sets the common properties to all effects
 		void _setCommonProperties( DIEFFECT* diEffect, DWORD* rgdwAxes,
-									LONG* rglDirection, DWORD struct_size, 
-									LPVOID struct_type, const Effect* effect );
+									LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, 
+									LPVOID struct_type, const Effect* effect, const Envelope* envelope );
 		//Actually do the upload
 		void _upload( GUID, DIEFFECT*, const Effect* );
 
+		// Map of currently uploaded effects (handle => effect)
 		typedef std::map<int,LPDIRECTINPUTEFFECT> EffectList;
 		EffectList mEffectList;
-		//Simple unique handle creation - allows for upto 2+ million effects
+
+		//Simple unique handle creation - allows for upto 2+ billion effects
 		//during the lifetime of application. Hopefully, that is enough.
 		int mHandles;
 
+		// Joystick device descriptor.
 		IDirectInputDevice8* mJoyStick;
+		
+		// Joystick capabilities.
+		const DIDEVCAPS* mpDIJoyCaps;
+
+		// Number of axis supporting FF.
+		short mFFAxes;
 	};
 }
Index: code/trunk/src/ois/win32/Win32InputManager.cpp
===================================================================
--- code/trunk/src/ois/win32/Win32InputManager.cpp	(revision 5693)
+++ code/trunk/src/ois/win32/Win32InputManager.cpp	(revision 5695)
@@ -75,5 +75,5 @@
 	hInst = GetModuleHandle(0);
 
-	//Create the device
+	//Create the input system
 	hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
     if (FAILED(hr))	
@@ -82,4 +82,6 @@
 	//Ok, now we have DirectInput, parse whatever extra settings were sent to us
 	_parseConfigSettings( paramList );
+
+	// Enumerate devices ...
 	_enumerateDevices();
 }
@@ -116,11 +118,13 @@
 {
 	//Enumerate all attached devices
-	mDirectInput->EnumDevices(NULL, _DIEnumKbdCallback, this, DIEDFL_ATTACHEDONLY); 
-}
-
-//--------------------------------------------------------------------------------//
-BOOL CALLBACK Win32InputManager::_DIEnumKbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+	mDirectInput->EnumDevices(NULL , _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY); 
+}
+
+//--------------------------------------------------------------------------------//
+BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
 {
 	Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef);
+
+	// Register only game devices (keyboard and mouse are managed differently).
 	if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK ||
 		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD ||
Index: code/trunk/src/ois/win32/Win32InputManager.h
===================================================================
--- code/trunk/src/ois/win32/Win32InputManager.h	(revision 5693)
+++ code/trunk/src/ois/win32/Win32InputManager.h	(revision 5695)
@@ -81,5 +81,5 @@
 
 		//! Used during device enumeration
-		static BOOL CALLBACK _DIEnumKbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
+		static BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
 
 		//! Keep a list of all joysticks enumerated, but not in use
Index: code/trunk/src/ois/win32/Win32JoyStick.cpp
===================================================================
--- code/trunk/src/ois/win32/Win32JoyStick.cpp	(revision 5693)
+++ code/trunk/src/ois/win32/Win32JoyStick.cpp	(revision 5695)
@@ -82,9 +82,25 @@
 	mState.mAxes.clear();
 
-	delete ff_device;
-	ff_device = 0;
-
+	if (ff_device)
+	{
+		delete ff_device;
+		ff_device = 0;
+	}
+
+	// Create direct input joystick device.
+	if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL)))
+		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");
+
+	// Set DIJoystick2 data format.
+	if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
+		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");
+
+	// Set cooperative level as specified when creating input manager.
+	HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
+	if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
+		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");
+
+	// Set buffer size.
 	DIPROPDWORD dipdw;
-
 	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
 	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
@@ -93,19 +109,8 @@
 	dipdw.dwData            = JOYSTICK_DX_BUFFERSIZE;
 
-	if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL)))
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");
-
-	if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");
-
-	HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
-
-	if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");
-
 	if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
-		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set buffer size property" );
-
-	//Enumerate all axes/buttons/sliders/etc before aquiring
+		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize >> Failed to set buffer size property" );
+
+	// Enumerate all axes/buttons/sliders/force feedback/etc before aquiring
 	_enumerate();
 
@@ -118,21 +123,23 @@
 void Win32JoyStick::_enumerate()
 {
-	//We can check force feedback here too
-	DIDEVCAPS  DIJoyCaps;
-	DIJoyCaps.dwSize = sizeof(DIDEVCAPS);
-	mJoyStick->GetCapabilities(&DIJoyCaps);
-
-	mPOVs = (short)DIJoyCaps.dwPOVs;
-
-	mState.mButtons.resize(DIJoyCaps.dwButtons);
-	mState.mAxes.resize(DIJoyCaps.dwAxes);
+	// Get joystick capabilities.
+	mDIJoyCaps.dwSize = sizeof(DIDEVCAPS);
+	if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) )
+		OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" );
+
+	// => Number of POVs
+	mPOVs = (short)mDIJoyCaps.dwPOVs;
+
+	// => Number of buttons and axes.
+	mState.mButtons.resize(mDIJoyCaps.dwButtons);
+	mState.mAxes.resize(mDIJoyCaps.dwAxes);
+
+	// Enumerate all Force Feedback effects (if any)
+	mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
 
 	//Reset the axis mapping enumeration value
 	_AxisNumber = 0;
 
-	//Enumerate Force Feedback (if any)
-	mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
-
-	//Enumerate and set axis constraints (and check FF Axes)
+	// Enumerate and set axis constraints (and check FF Axes)
 	mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
 }
@@ -181,13 +188,22 @@
 		OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set min/max range property" );
 
-	//Check if FF Axes
+	//Check if FF Axes, and if so, increment counter
 	if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
 	{
 		if( _this->ff_device )
 		{
-			//todo - increment force feedback axis count
+			_this->ff_device->_addFFAxis();
 		}
 	}
 
+	//Force the flags for gain and auto-center support to true,
+	//as DInput has no API to query the device for these capabilities
+	//(the only way to know is to try them ...)
+	if( _this->ff_device )
+	{
+	    _this->ff_device->_setGainSupport(true);
+	    _this->ff_device->_setAutoCenterSupport(true);
+	}
+
 	return DIENUM_CONTINUE;
 }
@@ -198,7 +214,7 @@
 	Win32JoyStick* _this = (Win32JoyStick*)pvRef;
 
-	//Create the FF class after we know there is at least one effect type
+	//Create the FF instance only after we know there is at least one effect type
 	if( _this->ff_device == 0 )
-		_this->ff_device = new Win32ForceFeedback(_this->mJoyStick);
+	  _this->ff_device = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps);
 
 	_this->ff_device->_addEffectSupport( pdei );
Index: code/trunk/src/ois/win32/Win32JoyStick.h
===================================================================
--- code/trunk/src/ois/win32/Win32JoyStick.h	(revision 5693)
+++ code/trunk/src/ois/win32/Win32JoyStick.h	(revision 5695)
@@ -60,4 +60,6 @@
 		IDirectInput8* mDirectInput;
 		IDirectInputDevice8* mJoyStick;
+		DIDEVCAPS mDIJoyCaps;
+
 		DWORD coopSetting;
 		GUID deviceGuid;
Index: code/trunk/src/ois/win32/Win32KeyBoard.cpp
===================================================================
--- code/trunk/src/ois/win32/Win32KeyBoard.cpp	(revision 5693)
+++ code/trunk/src/ois/win32/Win32KeyBoard.cpp	(revision 5695)
@@ -238,8 +238,7 @@
 		return 0;
 
-	unsigned char buff[3] = {0,0,0};
-	int ascii = ToAsciiEx(vk, kc, keyState, (LPWORD) buff, 0, layout);
-	//WCHAR wide[3];
-	//int ascii = ToUnicodeEx(vk, kc, keyState, wide, 3, 0, layout);
+	WCHAR buff[3] = {0};
+	int ascii = ToUnicodeEx(vk, kc, keyState, buff, 3, 0, layout);
+
 	if(ascii == 1 && deadKey != '\0' )
 	{
Index: code/trunk/src/orxonox/LevelManager.cc
===================================================================
--- code/trunk/src/orxonox/LevelManager.cc	(revision 5693)
+++ code/trunk/src/orxonox/LevelManager.cc	(revision 5695)
@@ -30,5 +30,5 @@
 
 #include <map>
-#include <boost/filesystem.hpp>
+#include <OgreResourceGroupManager.h>
 
 #include "core/CommandLine.h"
@@ -135,17 +135,16 @@
         availableLevels_.clear();
 
-        boost::filesystem::directory_iterator file(Core::getMediaPathString() + "levels");
-        boost::filesystem::directory_iterator end;
+        availableLevels_ = *Ogre::ResourceGroupManager::getSingleton().findResourceNames(
+            Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "*.oxw");
 
-        while (file != end)
-        {
-            if (!boost::filesystem::is_directory(*file) && file->string()[file->string().length()-1] != '~')
+        for (std::vector<std::string>::iterator it = availableLevels_.begin(); it != availableLevels_.end();)
+            if (it->find("old/") == 0)
+                it = availableLevels_.erase(it);
+            else
             {
-                std::string filename = file->path().leaf();
-                if (filename.length() > 4)
-                    availableLevels_.push_back(filename.substr(0,filename.length()-4));
+                size_t pos = it->find(".oxw");
+                *it = it->substr(0, pos);
+                ++it;
             }
-            ++file;
-        }
     }
 }
Index: code/trunk/src/orxonox/Main.cc
===================================================================
--- code/trunk/src/orxonox/Main.cc	(revision 5693)
+++ code/trunk/src/orxonox/Main.cc	(revision 5695)
@@ -40,4 +40,6 @@
 #include "core/CommandLine.h"
 #include "core/Game.h"
+#include "core/LuaState.h"
+#include "ToluaBindOrxonox.h"
 #include "Main.h"
 
@@ -48,4 +50,6 @@
 SetCommandLineSwitch(dedicated).information("Start in dedicated server mode");
 SetCommandLineSwitch(standalone).information("Start in standalone mode");
+
+DeclareToluaInterface(Orxonox);
 
 namespace orxonox
Index: code/trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 5693)
+++ code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 5695)
@@ -28,4 +28,8 @@
 
 #include "GSDedicated.h"
+
+#include <iomanip>
+#include <iostream>
+#include <boost/bind.hpp>
 
 #include "util/Debug.h"
@@ -37,8 +41,4 @@
 #include "core/GameMode.h"
 #include "network/Server.h"
-
-#include <iostream>
-#include <iomanip>
-#include <boost/bind.hpp>
 
 #ifdef ORXONOX_PLATFORM_UNIX
Index: code/trunk/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 5693)
+++ code/trunk/src/orxonox/gamestates/GSGraphics.cc	(revision 5695)
@@ -96,5 +96,5 @@
         // load debug overlay
         COUT(3) << "Loading Debug Overlay..." << std::endl;
-        this->debugOverlay_ = new XMLFile(Core::getMediaPathString() + "overlay/debug.oxo");
+        this->debugOverlay_ = new XMLFile("debug.oxo");
         Loader::open(debugOverlay_);
 
Index: code/trunk/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 5693)
+++ code/trunk/src/orxonox/gamestates/GSLevel.cc	(revision 5695)
@@ -29,4 +29,6 @@
 
 #include "GSLevel.h"
+
+#include <OgreCompositorManager.h>
 
 #include "core/input/InputManager.h"
@@ -166,4 +168,9 @@
 */
 
+        if (GameMode::showsGraphics())
+        {
+            // unload all compositors (this is only necessary because we don't yet destroy all resources!)
+            Ogre::CompositorManager::getSingleton().removeAll();
+        }
 
         // this call will delete every BaseObject!
@@ -229,5 +236,5 @@
         // call the loader
         COUT(0) << "Loading level..." << std::endl;
-        startFile_s = new XMLFile(Core::getMediaPathString() + "levels" + '/' + LevelManager::getInstance().getDefaultLevel());
+        startFile_s = new XMLFile(LevelManager::getInstance().getDefaultLevel());
         Loader::open(startFile_s);
     }
Index: code/trunk/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSMainMenu.cc	(revision 5693)
+++ code/trunk/src/orxonox/gamestates/GSMainMenu.cc	(revision 5695)
@@ -52,4 +52,5 @@
         inputState_->setHandler(GUIManager::getInstancePtr());
         inputState_->setJoyStickHandler(&InputHandler::EMPTY);
+        inputState_->setIsExclusiveMouse(false);
 
         // create an empty Scene
@@ -70,5 +71,5 @@
     {
         // show main menu
-        GUIManager::getInstance().showGUI("mainmenu_4");
+        GUIManager::getInstance().showGUI("MainMenu");
         GUIManager::getInstance().setCamera(this->camera_);
         GraphicsManager::getInstance().setCamera(this->camera_);
Index: code/trunk/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 5693)
+++ code/trunk/src/orxonox/gamestates/GSRoot.cc	(revision 5695)
@@ -33,8 +33,5 @@
 #include "core/Game.h"
 #include "core/GameMode.h"
-#include "core/LuaBind.h"
 #include "network/NetworkFunction.h"
-#include "ToluaBindCore.h"
-#include "ToluaBindOrxonox.h"
 #include "tools/Timer.h"
 #include "tools/interfaces/TimeFactorListener.h"
@@ -54,8 +51,4 @@
         this->ccSetTimeFactor_ = 0;
         this->ccPause_ = 0;
-
-        // Tell LuaBind about all tolua interfaces
-        LuaBind::getInstance().addToluaInterface(&tolua_Core_open, "Core");
-        LuaBind::getInstance().addToluaInterface(&tolua_Orxonox_open, "Orxonox");
     }
 
@@ -86,5 +79,5 @@
         }
 
-        // create the global LevelManager
+        // create the LevelManager
         this->levelManager_ = new LevelManager();
     }
Index: code/trunk/src/orxonox/objects/Level.cc
===================================================================
--- code/trunk/src/orxonox/objects/Level.cc	(revision 5693)
+++ code/trunk/src/orxonox/objects/Level.cc	(revision 5695)
@@ -53,7 +53,4 @@
         this->registerVariables();
         this->xmlfilename_ = this->getFilename();
-
-        if (this->xmlfilename_.length() >= Core::getMediaPathString().length())
-            this->xmlfilename_ = this->xmlfilename_.substr(Core::getMediaPathString().length());
     }
 
@@ -101,5 +98,5 @@
         mask.include(Class(OverlayGroup)); // HACK to include the ChatOverlay
 
-        this->xmlfile_ = new XMLFile(Core::getMediaPathString() + this->xmlfilename_, mask);
+        this->xmlfile_ = new XMLFile(mask, this->xmlfilename_);
 
         Loader::open(this->xmlfile_);
Index: code/trunk/src/orxonox/objects/Script.cc
===================================================================
--- code/trunk/src/orxonox/objects/Script.cc	(revision 5693)
+++ code/trunk/src/orxonox/objects/Script.cc	(revision 5695)
@@ -29,40 +29,36 @@
 #include "Script.h"
 
-#include <tinyxml/ticpp.h>
 #include "core/CoreIncludes.h"
-#include "core/LuaBind.h"
+#include "core/LuaState.h"
+#include "core/XMLPort.h"
 
 namespace orxonox
 {
-  CreateFactory(Script);
+    CreateFactory(Script);
 
-  Script::Script(BaseObject* creator) : BaseObject(creator)
-  {
-    RegisterObject(Script);
+    Script::Script(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Script);
 
-    code_ = "";
-  }
+        // Get a new LuaState
+        luaState_ = new LuaState();
+    }
 
-  Script::~Script()
-  {
-  }
+    Script::~Script()
+    {
+        if (this->isInitialized())
+            delete luaState_;
+    }
 
-  /**
-  @brief XML loading and saving.
-  @param xmlelement The XML-element
-  @param loading Loading (true) or saving (false)
-   */
-  void Script::XMLPort(Element& xmlelement, XMLPort::Mode mode)
-  {
-    BaseObject::XMLPort(xmlelement, mode);
+    void Script::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        BaseObject::XMLPort(xmlelement, mode);
 
-    code_ = xmlelement.GetText(false);
-  }
+        XMLPortParam(Script, "code", setCode, getCode, xmlelement, mode);
+    }
 
-  void Script::execute()
-  {
-    LuaBind& lua = LuaBind::getInstance();
-    lua.loadString(this->code_);
-    lua.run();
-  }
+    void Script::execute()
+    {
+        luaState_->doString(code_);
+    }
 }
Index: code/trunk/src/orxonox/objects/Script.h
===================================================================
--- code/trunk/src/orxonox/objects/Script.h	(revision 5693)
+++ code/trunk/src/orxonox/objects/Script.h	(revision 5695)
@@ -37,15 +37,19 @@
 namespace orxonox
 {
-  class _OrxonoxExport Script : public BaseObject
-  {
+    class _OrxonoxExport Script : public BaseObject
+    {
     public:
-      Script(BaseObject* creator);
-      ~Script();
-      void XMLPort(Element& xmlelement, XMLPort::Mode mode);
-      void execute();
+        Script(BaseObject* creator);
+        ~Script();
+        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        void execute();
+
+        void setCode(const std::string& code) { code_ = code; }
+        const std::string& getCode() const { return code_; }
 
     private:
-      std::string code_;
-  };
+        std::string code_;
+        LuaState* luaState_;
+    };
 }
 
Index: code/trunk/src/orxonox/orxonox-main.vcproj.user.in
===================================================================
--- code/trunk/src/orxonox/orxonox-main.vcproj.user.in	(revision 5693)
+++ code/trunk/src/orxonox/orxonox-main.vcproj.user.in	(revision 5695)
@@ -11,5 +11,5 @@
 			<DebugSettings
 				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
-				Environment="Path=${ORXONOX_RUNTIME_LIBRARY_DIRECTORY}"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
 				EnvironmentMerge="true"
 			/>
@@ -20,5 +20,5 @@
 			<DebugSettings
 				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
-				Environment="Path=${ORXONOX_RUNTIME_LIBRARY_DIRECTORY}"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
 				EnvironmentMerge="true"
 			/>
@@ -29,5 +29,5 @@
 			<DebugSettings
 				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
-				Environment="Path=${ORXONOX_RUNTIME_LIBRARY_DIRECTORY}"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
 				EnvironmentMerge="true"
 			/>
@@ -38,5 +38,5 @@
 			<DebugSettings
 				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
-				Environment="Path=${ORXONOX_RUNTIME_LIBRARY_DIRECTORY}"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
 				EnvironmentMerge="true"
 			/>
Index: code/trunk/src/orxonox/sound/SoundBase.cc
===================================================================
--- code/trunk/src/orxonox/sound/SoundBase.cc	(revision 5693)
+++ code/trunk/src/orxonox/sound/SoundBase.cc	(revision 5695)
@@ -36,4 +36,5 @@
 #include "util/Math.h"
 #include "core/Core.h"
+#include "core/Resource.h"
 #include "orxonox/objects/worldentities/WorldEntity.h"
 #include "SoundManager.h"
@@ -134,7 +135,5 @@
     }
 
-    bool SoundBase::loadFile(std::string filename) {
-        filename = Core::getMediaPathString() + "/audio/" + filename;
-
+    bool SoundBase::loadFile(const std::string& filename) {
         if(!SoundManager::getInstance().isSoundAvailable())
         {
@@ -144,5 +143,18 @@
 
         COUT(3) << "Sound: OpenAL ALUT: loading file " << filename << std::endl;
-        this->buffer_ = alutCreateBufferFromFile(filename.c_str());
+        // Get DataStream from the resources
+        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(filename);
+        if (fileInfo == NULL) {
+            COUT(2) << "Warning: Sound file '" << filename << "' not found" << std::endl;
+            return false;
+        }
+        DataStreamPtr stream = Resource::open(filename);
+        // Read everything into a temporary buffer
+        char* buffer = new char[fileInfo->size];
+        stream->read(buffer, fileInfo->size);
+
+        this->buffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size);
+        delete[] buffer;
+
         if(this->buffer_ == AL_NONE) {
             COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
Index: code/trunk/src/orxonox/sound/SoundBase.h
===================================================================
--- code/trunk/src/orxonox/sound/SoundBase.h	(revision 5693)
+++ code/trunk/src/orxonox/sound/SoundBase.h	(revision 5695)
@@ -55,5 +55,5 @@
         bool isStopped();
 
-        bool loadFile(std::string filename);
+        bool loadFile(const std::string& filename);
 
     private:
Index: code/trunk/src/orxonox/tools/CMakeLists.txt
===================================================================
--- code/trunk/src/orxonox/tools/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/orxonox/tools/CMakeLists.txt	(revision 5695)
@@ -5,4 +5,6 @@
   Mesh.cc
   ParticleInterface.cc
+  ResourceCollection.cc
+  ResourceLocation.cc
   Shader.cc
   TextureGenerator.cc
Index: code/trunk/src/orxonox/tools/Mesh.cc
===================================================================
--- code/trunk/src/orxonox/tools/Mesh.cc	(revision 5693)
+++ code/trunk/src/orxonox/tools/Mesh.cc	(revision 5695)
@@ -71,4 +71,5 @@
                 this->entity_->setCastShadows(this->bCastShadows_);
 
+#if OGRE_VERSION < 0x010600
                 this->entity_->setNormaliseNormals(true);
                 /*
@@ -79,4 +80,5 @@
                     I don't know exactly what this means, but I put this here if there will be problems with shaders.
                 */
+#endif
             }
             catch (...)
Index: code/trunk/src/orxonox/tools/ResourceCollection.cc
===================================================================
--- code/trunk/src/orxonox/tools/ResourceCollection.cc	(revision 5695)
+++ code/trunk/src/orxonox/tools/ResourceCollection.cc	(revision 5695)
@@ -0,0 +1,99 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ResourceCollection.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/Resource.h"
+#include "core/XMLPort.h"
+#include "ResourceLocation.h"
+
+namespace orxonox
+{
+    CreateFactory(ResourceCollection);
+
+    ResourceCollection::ResourceCollection(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(ResourceCollection);
+
+        // Default group is "General"
+        this->setResourceGroup(Resource::DEFAULT_GROUP);
+    }
+
+    ResourceCollection::~ResourceCollection()
+    {
+    }
+
+    void ResourceCollection::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        XMLPortParam(ResourceCollection, "resourceGroup", setResourceGroup, getResourceGroup, xmlElement, mode);
+        XMLPortObject(ResourceCollection, ResourceLocation, "", addResourceLocation, getResourceLocation, xmlElement, mode);
+    }
+
+    void ResourceCollection::setResourceGroup(const std::string& resourceGroup)
+    {
+        if (resourceGroup.empty())
+        {
+            COUT(2) << "Warning: \"\" is not a valid resource group." << std::endl;
+            return;
+        }
+        if (!resourceLocations_.empty())
+            ThrowException(InitialisationFailed, "ResourceGroup: Group change not allowed with locations already added!");
+        resourceGroup_ = resourceGroup;
+    }
+
+    void ResourceCollection::addResourceLocation(ResourceLocation* location)
+    {
+        location->load(resourceGroup_);
+        this->resourceLocations_.push_back(location);
+    }
+
+    void ResourceCollection::removeResourceLocation(ResourceLocation* location)
+    {
+        for (std::vector<ResourceLocation*>::iterator it = resourceLocations_.begin(); it != resourceLocations_.end(); )
+        {
+            if (*it == location)
+            {
+                it = resourceLocations_.erase(it);
+                location->unload(); // doesn't throw
+            }
+            else
+                ++it;
+        }
+    }
+
+    ResourceLocation* ResourceCollection::getResourceLocation(unsigned int index) const
+    {
+        if (index >= resourceLocations_.size())
+            return NULL;
+        else
+            return resourceLocations_[index];
+    }
+}
Index: code/trunk/src/orxonox/tools/ResourceCollection.h
===================================================================
--- code/trunk/src/orxonox/tools/ResourceCollection.h	(revision 5695)
+++ code/trunk/src/orxonox/tools/ResourceCollection.h	(revision 5695)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ResourceCollection_H__
+#define _ResourceCollection_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class ResourceLocation;
+
+    class _ToolsExport ResourceCollection : public BaseObject
+    {
+    public:
+        ResourceCollection(BaseObject* creator);
+        virtual ~ResourceCollection();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setResourceGroup(const std::string& resourceGroup);
+        const std::string& getResourceGroup() const { return resourceGroup_; }
+
+        void addResourceLocation(ResourceLocation* location);
+        void removeResourceLocation(ResourceLocation* location);
+        ResourceLocation* getResourceLocation(unsigned int index) const;
+
+    private:
+        ResourceCollection(const ResourceCollection&);
+
+        std::string resourceGroup_;
+        std::vector<ResourceLocation*> resourceLocations_;
+    };
+}
+
+#endif /* _ResourceCollection_H__ */
Index: code/trunk/src/orxonox/tools/ResourceLocation.cc
===================================================================
--- code/trunk/src/orxonox/tools/ResourceLocation.cc	(revision 5695)
+++ code/trunk/src/orxonox/tools/ResourceLocation.cc	(revision 5695)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ResourceLocation.h"
+
+#include <OgreResourceGroupManager.h>
+#include <boost/filesystem.hpp>
+
+#include "util/Exception.h"
+#include "core/Core.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLFile.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(ResourceLocation);
+
+    ResourceLocation::ResourceLocation(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(ResourceLocation);
+
+        // Default values
+        archiveType_ = "FileSystem";
+        bRecursive_  = true;
+    }
+
+    ResourceLocation::~ResourceLocation()
+    {
+    }
+
+    void ResourceLocation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        XMLPortParam(ResourceLocation, "path",        setPath,        getPath,        xmlElement, mode);
+        XMLPortParam(ResourceLocation, "archiveType", setArchiveType, getArchiveType, xmlElement, mode);
+        XMLPortParam(ResourceLocation, "recursive",   setRecursive,   getRecursive,   xmlElement, mode);
+        if (path_.empty())
+            ThrowException(AbortLoading, "ResourceLocation: No path given.");
+    }
+
+    void ResourceLocation::load(const std::string& resourceGroup)
+    {
+        if (path_.empty())
+            ThrowException(InitialisationFailed, "ResourceLocation: Trying to add one without the path being set");
+
+        // Find the path
+        boost::filesystem::path path;
+        if (boost::filesystem::exists(Core::getDataPath() / this->getPath()))
+            path = Core::getDataPath() / this->getPath();
+        else if (Core::isDevelopmentRun() && boost::filesystem::exists(Core::getExternalDataPath() / this->getPath()))
+            path = Core::getExternalDataPath() / this->getPath();
+        else
+        {
+            COUT(2) << "Warning: ResourceLocation '" << this->getPath() << "' does not seem to exist" << std::endl;
+            return;
+        }
+
+        // Add it to the Ogre paths
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
+            path.string(), this->getArchiveType(), resourceGroup, this->getRecursive());
+        resourceGroup_ = resourceGroup;
+    }
+
+    void ResourceLocation::unload()
+    {
+        // Remove from Ogre paths
+        resourceGroup_.erase();
+        try
+        {
+            Ogre::ResourceGroupManager::getSingleton().removeResourceLocation(
+                this->getPath(), this->getResourceGroup());
+        }
+        catch (const std::exception& ex)
+        {
+            COUT(1) << "Removing of a ResourceLocation failed: " << ex.what() << std::endl;
+        }
+    }
+}
Index: code/trunk/src/orxonox/tools/ResourceLocation.h
===================================================================
--- code/trunk/src/orxonox/tools/ResourceLocation.h	(revision 5695)
+++ code/trunk/src/orxonox/tools/ResourceLocation.h	(revision 5695)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ResourceLocation_H__
+#define _ResourceLocation_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ToolsExport ResourceLocation : public BaseObject
+    {
+        // for load/unload
+        friend class ResourceCollection;
+
+    public:
+        ResourceLocation(BaseObject* creator);
+        virtual ~ResourceLocation();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setPath(const std::string& path) { path_ = path; }
+        const std::string& getPath() const { return path_; }
+
+        void setArchiveType(const std::string& archiveType) { archiveType_ = archiveType; }
+        const std::string& getArchiveType() const { return archiveType_; }
+
+        void setRecursive(bool bRecursive) { bRecursive_ = bRecursive; }
+        bool getRecursive() const { return bRecursive_; }
+
+        const std::string& getResourceGroup() const { return resourceGroup_; }
+
+    private:
+        ResourceLocation(const ResourceLocation&);
+
+        void load(const std::string& resourceGroup);
+        void unload();
+
+        std::string path_;
+        std::string archiveType_;
+        std::string resourceGroup_;
+        bool bRecursive_;
+    };
+}
+
+#endif /* _ResourceLocation_H__ */
Index: code/trunk/src/util/CMakeLists.txt
===================================================================
--- code/trunk/src/util/CMakeLists.txt	(revision 5693)
+++ code/trunk/src/util/CMakeLists.txt	(revision 5695)
@@ -34,4 +34,35 @@
 )
 
+SET_SOURCE_FILES(UTIL_HDR_FILES
+  CRC32.h
+  Clipboard.h
+  Convert.h
+  Debug.h
+  Exception.h
+  ExprParser.h
+  Math.h
+  MathConvert.h
+  mbool.h
+  MultiType.h
+  MultiTypeValue.h
+  OgreForwardRefs.h
+  OrxAssert.h
+  OrxEnum.h
+  OutputBuffer.h
+  OutputHandler.h
+  RefToValue.h
+  ScopeGuard.h
+  Serialise.h
+  SignalHandler.h
+  Singleton.h
+  Sleep.h
+  StringUtils.h
+  SubString.h
+  TemplateUtils.h
+  TypeTraits.h
+  UTFStringConversions.h
+  UtilPrereqs.h
+)
+
 IF(GCC_NO_SYSTEM_HEADER_SUPPORT)
   # Get around displaying a few hundred lines of warning code
@@ -40,5 +71,4 @@
 
 ORXONOX_ADD_LIBRARY(util
-  FIND_HEADER_FILES
   DEFINE_SYMBOL
     "UTIL_SHARED_BUILD"
@@ -46,4 +76,4 @@
     ${OGRE_LIBRARY}
   SOURCE_FILES
-    ${UTIL_SRC_FILES}
+    ${UTIL_SRC_FILES} ${UTIL_HDR_FILES}
 )
Index: code/trunk/src/util/Debug.h
===================================================================
--- code/trunk/src/util/Debug.h	(revision 5693)
+++ code/trunk/src/util/Debug.h	(revision 5695)
@@ -29,5 +29,5 @@
 /**
     @file
-    @brief Handles different output-levels of errors, warnings, infos and debug informations.
+    @brief Handles different output-levels of errors, warnings, infos and debug information.
 
     The COUT(level) macro acts like std::cout, but the output is only performed if the given
@@ -45,8 +45,8 @@
      1: Errors
      2: Warnings
-     3: Informations
+     3: Information
      4: Debug information
      5: More debug information
-     6: Crazy debug informations
+     6: Crazy debug information
 
     @example
