Index: code/branches/gui/src/core/CommandLine.cc
===================================================================
--- code/branches/gui/src/core/CommandLine.cc	(revision 1663)
+++ code/branches/gui/src/core/CommandLine.cc	(revision 1664)
@@ -31,4 +31,8 @@
 namespace orxonox
 {
+    /**
+    @brief
+        Destructor destroys all CommandLineArguments with it.
+    */
     CommandLine::~CommandLine()
     {
@@ -39,5 +43,9 @@
         }
     }
-    
+
+    /**
+    @brief
+        Returns a unique instance (Meyers Singleton).
+    */
     CommandLine& CommandLine::_getInstance()
     {
@@ -46,6 +54,18 @@
     }
 
-    void CommandLine::_parse(int argc, char** argv)
-    {
+    /**
+    @brief
+        Reads the command line parses the values of each argument.
+        It is then stored in the corresponding CommandLineArgument.
+    @note
+        The reason that you have to provide the string to be parsed as
+        space separted list is because of argc and argv. If you only have
+        a whole string, simply use getAllStrings() of SubString.
+    @param arguments
+        Vector of space separated strings.
+    */
+    void CommandLine::_parse(const std::vector<std::string>& arguments)
+    {
+        // why this? See bFirstTimeParse_ declaration.
         if (bFirstTimeParse_)
         {
@@ -64,55 +84,92 @@
         std::string name;
         std::string shortcut;
-        std::string val;
-        for (int i = 1; i < argc; ++i)
-        {
-            if (argv[i][0] == '-')
+        std::string value;
+        for (unsigned int i = 0; i < arguments.size(); ++i)
+        {
+            if (arguments[i].size() != 0)
             {
-                if (argv[i][1] <= 57 && argv[i][1] >= 48)
+                // sure not ""
+                if (arguments[i][0] == '-')
                 {
-                    // negative number as a value
-                    val += std::string(argv[i]) + " ";
+                    // start with "-"
+                    if (arguments[i].size() == 1)
+                    {
+                        // argument[i] is "-", probably a minus sign
+                        value += "- ";
+                    }
+                    else if (arguments[i][1] <= 57 && arguments[i][1] >= 48)
+                    {
+                        // negative number as a value
+                        value += arguments[i] + " ";
+                    }
+                    else
+                    {
+                        // can be shortcut or full name argument
+
+                        // save old data first
+                        if (name != "")
+                        {
+                            checkFullArgument(name, value);
+                            name = "";
+                            assert(shortcut == "");
+                        }
+                        else if (shortcut != "")
+                        {
+                            checkShortcut(shortcut, value);
+                            shortcut = "";
+                            assert(name == "");
+                        }
+
+                        if (arguments[i][1] == '-')
+                        {
+                            // full name argument with "--name"
+                            name = arguments[i].substr(2);
+                        }
+                        else
+                        {
+                            // shortcut with "-s"
+                            shortcut = arguments[i].substr(1);
+                        }
+
+                        // reset value string
+                        value = "";
+                    }
                 }
                 else
                 {
-                    // save old data first
-                    if (name != "")
-                    {
-                        checkFullArgument(name, val);
-                        name = "";
-                        assert(shortcut == "");
-                    }
-                    else if (shortcut != "")
-                    {
-                        checkShortcut(shortcut, val);
-                        shortcut = "";
-                        assert(name == "");
-                    }
-
-                    if (argv[i][1] == '-')
-                    {
-                        // full name argument
-                        name = argv[i] + 2;
-                    }
-                    else
-                    {
-                        // short cut
-                        shortcut = argv[i] + 1;
-                    }
-                    val = "";
+                    // value string
+
+                    if (name == "" && shortcut == "")
+                    {
+                        ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
+                    }
+
+                    // Concatenate strings as long as there's no new argument by "-" or "--"
+                    value += arguments[i] + ' ';
                 }
             }
-            else // value
-            {
-                if (name == "" && shortcut == "")
-                {
-                    ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
-                }
-
-                val += argv[i];
-            }
-        }
-    }
-
+        }
+
+        // parse last argument
+        if (name != "")
+        {
+            checkFullArgument(name, value);
+            assert(shortcut == "");
+        }
+        else if (shortcut != "")
+        {
+            checkShortcut(shortcut, value);
+            assert(name == "");
+        }
+    }
+
+    /**
+    @brief
+        Parses an argument based on its full name.
+    @param name
+        Full name of the argument
+    @param value
+        String containing the value
+    */
     void CommandLine::checkFullArgument(const std::string& name, const std::string& value)
     {
@@ -124,4 +181,12 @@
     }
 
+    /**
+    @brief
+        Parses an argument based on its shortcut.
+    @param shortcut
+        Shotcut to the argument
+    @param value
+        String containing the value
+    */
     void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value)
     {
@@ -132,3 +197,16 @@
         it->second->parse(value);
     }
+
+    std::string CommandLine::getUsageInformation()
+    {
+        CommandLine* inst = &_getInstance();
+        std::string infoStr;
+        for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin();
+            it != inst->cmdLineArgs_.end(); ++it)
+        {
+            infoStr += "[--" + it->second->getName() + " " + it->second->getInformation() + "] ";
+        }
+        return infoStr;
+    }
+
 }
Index: code/branches/gui/src/core/CommandLine.h
===================================================================
--- code/branches/gui/src/core/CommandLine.h	(revision 1663)
+++ code/branches/gui/src/core/CommandLine.h	(revision 1664)
@@ -36,11 +36,32 @@
 #include "Exception.h"
 
-
 #define SetCommandLineArgument(name, defaultValue) \
     BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
     = orxonox::CommandLine::addCommandLineArgument(#name, defaultValue)
+#define SetCommandLineSwitch(name) \
+    BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLine::addCommandLineArgument(#name, false)
+
 
 namespace orxonox
 {
+    /**
+    @brief
+        Template struct which creates a distinct type for every integer constant.
+    @note
+        This allows to select a different function depending on a boolean value
+        when creating a new CommandLineArgument.
+        From 'Modern C++ Design' (Alexandrescu 2001).
+    */
+    template <int v>
+    struct Int2Type
+    {
+        enum { value = v };
+    };
+
+    /**
+    @brief
+        Base class for CommandLineArguments.
+    */
     class _CoreExport BaseCommandLineArgument
     {
@@ -48,9 +69,21 @@
 
     public:
+        //! Tells whether the value has been changed by the command line.
         bool hasDefaultValue() const { return bHasDefaultValue_; }
+        //! Returns the name of the argument.
         const std::string& getName() const { return name_; }
+
+        //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument.
+        //! Evaluates to "" if none there is none.
         const std::string& getShortcut() const { return shortcut_; }
+        //! Sets the shortcut for the argument
         BaseCommandLineArgument& setShortcut(const std::string& shortcut)
         { this->shortcut_ = shortcut; return *this; }
+
+        //! Returns the usage information
+        const std::string& getInformation() const { return this->usageInformation_; }
+        //! Sets the option information when displaying orxonox usage.
+        BaseCommandLineArgument& setInformation(const std::string& usage)
+        { this->usageInformation_ = usage; return *this; }
 
     protected:
@@ -60,27 +93,52 @@
         { }
 
+        //! Undefined copy constructor
         BaseCommandLineArgument(const BaseCommandLineArgument& instance);
         virtual ~BaseCommandLineArgument() { }
 
+        //! Parses the value string of a command line argument.
         virtual void parse(const std::string& value) = 0;
 
+        //! Tells whether the value has been changed by the command line.
         bool bHasDefaultValue_;
 
     private:
-        std::string name_;
-        std::string shortcut_;
+        std::string name_;             //!< Name of the argument
+        std::string shortcut_;         //!< Shortcut of the argument. @see getShortcut().
+        std::string usageInformation_; //!< Tells about the usage of this parameter
     };
 
 
+    /**
+    @brief
+        Container class for a command line argument of type T.
+        
+        Whenever you want to have an option specified by a command line switch,
+        you need to first define it with SetCommandLineArgument(name, defaultValue).
+        It is then added to a map and possibly changed when the command line is being parsed.
+        If the option was not given, you can detect this by asking hasDefaultValue().
+        
+        There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20".
+        Note the difference between "-" and "--"!
+        Also, there is no restriction to the number of strings you add after --name.
+        So "--startVector (2, 4, 5)" is perfectly legal.
+
+        Retrieving an argument is possible with the getCommandLineArgument function of the
+        CommandLine class. It is a Singleton, but the public interface is static.
+    */
     template <class T>
     class CommandLineArgument : public BaseCommandLineArgument
     {
+        // Only let CommandLine change the value.
         friend class CommandLine;
 
     public:
+        //! Returns the actual value of the argument. Can be equal to default value.
         T getValue() const { return value_; }
+        //! Returns the given default value as type T.
         T getDefaultValue() const { return defaultValue_; }
 
     private:
+        //! Constructor initialises both value_ and defaultValue_ with defaultValue.
         CommandLineArgument(const std::string& name, const T& defaultValue)
             : BaseCommandLineArgument(name)
@@ -91,8 +149,13 @@
         virtual void parse(const std::string& value);
 
-        T value_;
-        T defaultValue_;
+        T value_;            //!< The actual value
+        T defaultValue_;     //!< Default value. Should not be changed.
     };
 
+    /**
+    @brief
+        Parses a value string for a command line argument.
+        It simply uses convertValue(Output, Input) to do that.
+    */
     template <class T>
     void CommandLineArgument<T>::parse(const std::string& value)
@@ -108,19 +171,61 @@
     }
 
-
+    /**
+    @brief
+        Parses a value string for a command line argument.
+        It simply uses convertValue(Output, Input) to do that.
+        This is a template specialisation for bool type. That is necessary
+        so that you can have simple command line switches.
+    */
+    template <>
+    inline void CommandLineArgument<bool>::parse(const std::string& value)
+    {
+        if (convertValue(&this->value_, value))
+        {
+            this->bHasDefaultValue_ = false;
+        }
+        else if (value == "")
+        {
+            this->bHasDefaultValue_ = false;
+            this->value_ = true;
+        }
+        else
+        {
+            ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
+        }
+    }
+
+
+    /**
+    @brief
+        Global interface to command line options.
+        Allows to add and retrieve command line arguments. Also does the parsing.
+    @note
+        Internally it is a Singleton, but the public interface is static.
+    @see
+        CommandLineArgument
+    */
     class _CoreExport CommandLine
     {
     public:
 
-        static void parse(int argc, char** argv) { _getInstance()._parse(argc, argv); }
+        //! Parse redirection to internal member method.
+        static void parse(const std::vector<std::string>& arguments) { _getInstance()._parse(arguments); }
+
+        static std::string getUsageInformation();
 
         template <class T>
         static const CommandLineArgument<T>* getCommandLineArgument(const std::string& name);
-        template <class T>
-        static BaseCommandLineArgument& addCommandLineArgument(const std::string& name,
-            const T& defaultValue);
+        //! Writes the argument value in the given parameter.
+        template <class T>
+        static void getCommandLineValue(const std::string& name, T* value)
+        { *value = getCommandLineArgument<T>(name)->getValue(); }
+        template <class T>
+        static BaseCommandLineArgument& addCommandLineArgument(const std::string& name, T defaultValue);
 
     private:
+        //! Constructor initialises bFirstTimeParse_ with true.
         CommandLine() : bFirstTimeParse_(true) { }
+        //! Undefined copy constructor
         CommandLine(const CommandLine& instance);
         ~CommandLine();
@@ -128,15 +233,34 @@
         static CommandLine& _getInstance();
 
-        void _parse(int argc, char** argv);
+        void _parse(const std::vector<std::string>& arguments);
         void checkFullArgument(const std::string& name, const std::string& value);
         void checkShortcut(const std::string& shortcut, const std::string& value);
 
+        template <class T>
+        BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<0> isString);
+        template <class T>
+        BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<1> isString);
+
+        /**
+            Tells whether we parse the first expression. The CommmandLineArguments are added before main().
+            So when we call parse() the first time, we need to create a map with all shortcuts since these
+            get added after addCommandLineArgument().
+        */
         bool bFirstTimeParse_;
 
+        //! Holds all pointers to the arguments and serves as a search map by name.
         std::map<std::string, BaseCommandLineArgument*> cmdLineArgs_;
+        //! Search map by chortcut for the arguments.
         std::map<std::string, BaseCommandLineArgument*> cmdLineArgsShortcut_;
     };
 
 
+    /**
+    @brief
+        Retrieves a CommandLineArgument.
+        The method throws an exception if 'name' was not found or the value could not be converted.
+    @note
+        You shold of course not call this method before the command line has been parsed.
+    */
     template <class T>
     const CommandLineArgument<T>* CommandLine::getCommandLineArgument(const std::string& name)
@@ -162,7 +286,21 @@
     }
 
-    template <class T>
-    BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name,
-                                             const T& defaultValue)
+    /**
+    @brief
+        Adds a new CommandLineArgument to the internal map.
+        Note that only such arguments are actually valid.
+    @param name
+        Name of the argument. Shortcut can be added later.
+    @param defaultValue
+        Default value that is used when argument was not given.
+    @note
+        In order to store char* strings as std::string too, there's
+        little bit of template programming involved:
+        StaticConversions::exists determines whether T converts to std::string.
+        Int2Type<int> is then used to call the right function. One returns
+        a CommandLineArgument<T> and the other CommandLineArgument<std::string>.
+    */
+    template <class T>
+    BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name, T defaultValue)
     {
         std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
@@ -170,5 +308,24 @@
             "Cannot add a command line argument with name '" + name + "' twice.");
 
-        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument<T>(name, defaultValue));
+        return *(_getInstance().cmdLineArgs_[name] = 
+            _getInstance().createArg(name, defaultValue, Int2Type<StaticConversion<T, std::string>::exists>()));
+    }
+
+    /**
+        Returns a new CommandLineArgument<T>.
+    */
+    template <class T>
+    BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<0> isPrime)
+    {
+        return new CommandLineArgument<T>(name, defaultValue);
+    }
+
+    /**
+        Returns a new CommandLineArgument<std::string>.
+    */
+    template <class T>
+    BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<1> isPrime)
+    {
+        return new CommandLineArgument<std::string>(name, defaultValue);
     }
 }
Index: code/branches/gui/src/core/Exception.cc
===================================================================
--- code/branches/gui/src/core/Exception.cc	(revision 1663)
+++ code/branches/gui/src/core/Exception.cc	(revision 1664)
@@ -52,27 +52,32 @@
     { }
 
-    std::string Exception::getFullDescription() const
+    const std::string& Exception::getFullDescription() const
     {
-        std::ostringstream fullDesc;
+        if (fullDescription_ == "")
+        {
+            std::ostringstream fullDesc;
 
-        fullDesc << this->getTypeName() << "_EXCEPTION";
+            fullDesc << this->getTypeName() << "_EXCEPTION";
 
-        if (this->fileName_ != "")
-        {
-            fullDesc << " in " << this->fileName_;
-            if (this->lineNumber_)
-                fullDesc << "(" << this->lineNumber_ << ")";
+            if (this->fileName_ != "")
+            {
+                fullDesc << " in " << this->fileName_;
+                if (this->lineNumber_)
+                    fullDesc << "(" << this->lineNumber_ << ")";
+            }
+
+            if (this->functionName_ != "")
+                fullDesc << " in function '" << this->functionName_ << "'";
+
+            fullDesc << ": ";
+            if (this->description_ != "")
+                fullDesc << this->description_;
+            else
+                fullDesc << "No description available.";
+
+            this->fullDescription_ = std::string(fullDesc.str());
         }
 
-        if (this->functionName_ != "")
-            fullDesc << " in function '" << this->functionName_ << "'";
-
-        fullDesc << ": ";
-        if (this->description_ != "")
-            fullDesc << this->description_;
-        else
-            fullDesc << "No description available.";
-
-        return fullDesc.str();
+        return fullDescription_;
     }
 
Index: code/branches/gui/src/core/Exception.h
===================================================================
--- code/branches/gui/src/core/Exception.h	(revision 1663)
+++ code/branches/gui/src/core/Exception.h	(revision 1664)
@@ -73,5 +73,5 @@
         virtual ~Exception() throw() { }
 
-        virtual std::string        getFullDescription() const;
+        virtual const std::string& getFullDescription() const;
         virtual ExceptionType      getType()            const = 0;
         virtual std::string        getTypeName()        const = 0;
@@ -88,4 +88,6 @@
         std::string functionName_;
         std::string fileName_;
+        // mutable because of "what()" is a const method
+        mutable std::string fullDescription_;
     };
 
