private static void ParseConsoleString(string consoleString, CancelEventArgs cancelEventArgs)
        {
            List <string> consoleStringParts = consoleString.Split(' ').ToList();

            foreach (ConsoleCommand command in Commands)
            {
                // console string not command -> continue;
                if (command.Command.ToLower() != consoleStringParts[0].ToLower() &&
                    !command.CommandAliases.Select(ca => ca.ToLower())
                    .Contains(consoleStringParts[0].ToLower()))
                {
                    continue;
                }

                // Cancle event
                cancelEventArgs.Cancel = true;

                // Remove command
                string enteredCommand = consoleStringParts[0];
                consoleStringParts.Remove(enteredCommand);

                // Check for parameters
                List <object>   parameterValues   = new List <object>();
                ParameterInfo[] commandParameters = command.MethodInfo.GetParameters();

                string currentParameterString = string.Empty;
                for (int i = 0; i < commandParameters.Length; i++)
                {
                    // No more string parameters -> break;
                    if (consoleStringParts.FirstOrDefault() == null)
                    {
                        break;
                    }

                    // append or set string parameters
                    currentParameterString += consoleStringParts.FirstOrDefault();
                    consoleStringParts.Remove(currentParameterString);

                    // String argument with quote -> wait for end quote.
                    if (currentParameterString.StartsWith("\""))
                    {
                        if (!currentParameterString.EndsWith("\""))
                        {
                            i--;
                            continue;
                        }

                        // Remove quotes
                        currentParameterString = currentParameterString
                                                 .Remove(currentParameterString.Length - 1, 1)
                                                 .Remove(0, 1);
                    }

                    // Try parse & reset string
                    try
                    {
                        // Barse boolean parameter for Convert functions
                        if (commandParameters[i].ParameterType == typeof(bool))
                        {
                            if (currentParameterString == "1")
                            {
                                currentParameterString = "true";
                            }
                            else if (currentParameterString == "0")
                            {
                                currentParameterString = "false";
                            }
                        }


                        object parameterValue =
                            Convert.ChangeType(currentParameterString, commandParameters[i].ParameterType);
                        currentParameterString = string.Empty;

                        if (parameterValue == null)
                        {
                            break;
                        }

                        parameterValues.Add(parameterValue);
                    }
                    catch (InvalidCastException)
                    {
                        ConsoleOutput.WriteLine(ConsoleType.Error,
                                                $"The type ~w~{commandParameters[i].ParameterType}~;~ can't be used as command parameter!");
                        return;
                    }
                    catch
                    {
                        ConsoleOutput.WriteLine(ConsoleType.Error,
                                                $"Invalid type given for parameter {commandParameters[i].Name}.");
                        return;
                    }
                }

                // Not enough parameter values -> message & next;
                if (commandParameters.Count(info => !info.IsOptional) > parameterValues.Count)
                {
                    ConsoleOutput.WriteLine(ConsoleType.ConsoleCommand,
                                            $"Incorrect parameter values for the command ~o~{enteredCommand}~;~. " +
                                            $"Type ~b~\"/help {enteredCommand}\"~;~ for more information.");
                    return;
                }

                // Add optional parameters if not given, to parametersValues
                if (commandParameters.Length != parameterValues.Count)
                {
                    for (int i = commandParameters.Length - parameterValues.Count; i < commandParameters.Length; i++)
                    {
                        parameterValues.Add(commandParameters[i].DefaultValue);
                    }
                }

                //TODO: check for optional parameters needed

                // Invoke command
                command.MethodInfo.Invoke(command.ClassInstance, parameterValues.ToArray());
                return;
            }

            ConsoleOutput.WriteLine(ConsoleType.Error, $"~w~No command found for ~r~\"{consoleStringParts[0]}\"~w~!");
        }
        /// <summary>
        ///     Inspects a class for Commands.
        /// </summary>
        /// <param name="moduleInstance">The instance of the module wich should be inspected.</param>
        internal static void InspectModule(object moduleInstance)
        {
            List <ConsoleCommand> validCommands   = new List <ConsoleCommand>();
            List <ConsoleCommand> invalidCommands = new List <ConsoleCommand>();

            // Parse commands direct in module
            ParseCommands(moduleInstance);

            // Parse all field & Property infos
            foreach (FieldInfo fieldInfo in moduleInstance.GetType().GetFields())
            {
                ParseMemberInfo(null, fieldInfo, moduleInstance);
            }

            foreach (PropertyInfo propertyInfo in moduleInstance.GetType().GetProperties())
            {
                ParseMemberInfo(propertyInfo, null, moduleInstance);
            }

            // Parse static commands
            ParseStaticCommands();

            // Check for invalid commands & write message if given
            ParseInvalidCommands();
            if (invalidCommands.Any())
            {
                ConsoleOutput.SetPrefix(ConsoleOutput.GetPrefix().Replace(">", "~r~!"));

                foreach (ConsoleCommand invalidCommand in invalidCommands)
                {
                    ConsoleOutput.WriteLine(ConsoleType.ConsoleCommand,
                                            "~r~" + invalidCommand.Command + "~c~ " + invalidCommand.FullName());
                }

                ConsoleOutput.SetPrefix(ConsoleOutput.GetPrefix().Replace("~r~!", ">"));
            }

            // Register commands
            if (validCommands.Any())
            {
                foreach (ConsoleCommand command in validCommands)
                {
                    if (AddToCommands(command)) // On working command
                    {
                        ConsoleOutput.SetPrefix(ConsoleOutput.GetPrefix().Replace(">", "~g~+"));

                        // Highlight important commands
                        string commandColorCode = command.ImportantCommand ? "~#f66e00~" : "~g~";
                        // Command aliases
                        string aliasString =
                            $"{(command.CommandAliases.Any() ? $"~w~({commandColorCode}" : "")}{string.Join($"~w~, {commandColorCode}", command.CommandAliases)}{(command.CommandAliases.Any() ? "~w~)" : "")}";

                        ConsoleOutput.WriteLine(ConsoleType.ConsoleCommand,
                                                $"{commandColorCode}{command.Command} {aliasString} ~c~{command.FullName()}");

                        // Description
                        if (!string.IsNullOrEmpty(command.Description))
                        {
                            string currentPrefix = ConsoleOutput.GetPrefix();
                            ConsoleOutput.SetPrefix("\t\t~c~ > ~;~");
                            ConsoleOutput.WriteLine(ConsoleType.ConsoleCommand, command.Description);
                            ConsoleOutput.SetPrefix(currentPrefix);
                        }
                    }
                    else // on warnings
                    {
                        ConsoleOutput.SetPrefix(ConsoleOutput.GetPrefix().Replace(">", "~o~?"));
                        ConsoleOutput.WriteLine(ConsoleType.ConsoleCommand,
                                                "~o~" + command.Command + "~c~ " + command.FullName());
                    }

                    ConsoleOutput.SetPrefix(ConsoleOutput.GetPrefix().Replace("~g~+", ">").Replace("~o~?", ">"));
                }
            }

            void ParseInvalidCommands()
            {
                foreach (Type type in moduleInstance.GetType().Assembly.GetTypes())
                {
                    foreach (MethodInfo methodInfo in type.GetMethods())
                    {
                        object[] attributes = methodInfo.GetCustomAttributes(typeof(ConsoleCommand), true);

                        if (attributes.Length <= 0)
                        {
                            continue;
                        }

                        foreach (object commandObject in attributes)
                        {
                            // Method is registered as valid -> next.
                            if (validCommands.Any(cmd => cmd.MethodInfo == methodInfo))
                            {
                                continue;
                            }

                            ConsoleCommand command = (ConsoleCommand)commandObject;

                            // Save MethodInfo and Class instance
                            command.MethodInfo = methodInfo;
                            invalidCommands.Add(command);
                        }
                    }
                }
            }

            void ParseStaticCommands()
            {
                foreach (Type type in moduleInstance.GetType().Assembly.GetTypes())
                {
                    foreach (MethodInfo methodInfo in type.GetMethods()
                             .Where(info => info.IsStatic && info.IsPublic && !info.IsConstructor))
                    {
                        object[] attributes = methodInfo.GetCustomAttributes(typeof(ConsoleCommand), true);

                        if (attributes.Length <= 0)
                        {
                            continue;
                        }

                        foreach (object commandObject in attributes)
                        {
                            ConsoleCommand command = (ConsoleCommand)commandObject;

                            // Save MethodInfo and Class instance
                            command.MethodInfo    = methodInfo;
                            command.ClassInstance = null;
                            validCommands.Add(command);
                        }
                    }
                }
            }

            void ParseCommands(object instance)
            {
                foreach (MethodInfo methodInfo in instance.GetType().GetMethods()
                         .Where(info => !info.IsStatic && info.IsPublic && !info.IsConstructor))
                {
                    object[] attributes = methodInfo.GetCustomAttributes(typeof(ConsoleCommand), true);

                    if (attributes.Length <= 0)
                    {
                        continue;
                    }

                    foreach (object commandObject in attributes)
                    {
                        ConsoleCommand command = (ConsoleCommand)commandObject;

                        // Save MethodInfo and Class instance
                        command.MethodInfo    = methodInfo;
                        command.ClassInstance = instance;
                        validCommands.Add(command);
                    }
                }
            }

            void ParseMemberInfo(PropertyInfo propertyInfo, FieldInfo fieldInfo, object classInstance)
            {
                object instance = propertyInfo?.GetValue(classInstance) ?? fieldInfo?.GetValue(classInstance);

                if (instance == null ||
                    instance.GetType().Assembly != moduleInstance.GetType().Assembly || !instance.GetType().IsClass)
                {
                    return;
                }

                // Search for commands
                ParseCommands(instance);
                foreach (FieldInfo field in instance.GetType().GetFields())
                {
                    ParseMemberInfo(null, field, instance);
                }

                foreach (PropertyInfo property in instance.GetType().GetProperties())
                {
                    ParseMemberInfo(property, null, instance);
                }
            }
        }