public static Element ParseString(IToken token, string value, Element[] parameters, int depth = 0)
        {
            value = value.ToLower();

            if (depth == 0)
            {
                Log.Write($"\"{value}\"");
            }

            string debug = new string(' ', depth * 4);

            for (int i = 0; i < searchOrder.Length; i++)
            {
                string searchString = searchOrder[i];

                string regex =
                    Regex.Replace(Escape(searchString)
                                  , "({[0-9]})", @"(([a-z_.<>0-9-]+ ?)|(.+))"); // Converts {0} {1} {2} to (.+) (.+) (.+)
                regex = $"^{regex}$";
                var match = Regex.Match(value, regex);

                if (match.Success)
                {
                    Log.Write(debug + searchString);
                    V_String str = new V_String(token, searchString);

                    bool           valid            = true;
                    List <Element> parsedParameters = new List <Element>();
                    for (int g = 1; g < match.Groups.Count; g += 3)
                    {
                        string currentParameterValue = match.Groups[g].Captures[0].Value;

                        Match parameterString = Regex.Match(currentParameterValue, "^<([0-9]+)>$");
                        if (parameters != null && parameterString.Success)
                        {
                            int index = int.Parse(parameterString.Groups[1].Value);

                            if (index >= parameters.Length)
                            {
                                throw new SyntaxErrorException($"Tried to set the <{index}> format, but there are only {parameters.Length} parameters. Check your string.", token);
                            }

                            Log.Write($"{debug}    <param {index}>");
                            parsedParameters.Add(parameters[index]);
                        }
                        else
                        {
                            var p = ParseString(token, currentParameterValue, parameters, depth + 1);
                            if (p == null)
                            {
                                Log.Write($"{debug}{searchString} combo fail");
                                valid = false;
                                break;
                            }
                            parsedParameters.Add(p);
                        }
                    }
                    str.ParameterValues = parsedParameters.ToArray();

                    if (!valid)
                    {
                        continue;
                    }
                    return(str);
                }
            }

            if (depth > 0)
            {
                return(null);
            }
            else
            {
                throw new SyntaxErrorException($"Could not parse the string {value}.", token);
            }
        }
        //private static readonly string[] multiwordStrings = Constants.Strings.Where(str => str.Contains("_")).ToArray();

        public static Element ParseString(LanguageServer.Location location, string value, Element[] parameters, int depth = 0)
        {
            value = value.ToLower();

            Stopwatch time = null;

            if (depth == 0 && Log.LogLevel == LogLevel.Verbose)
            {
                Log.Write(LogLevel.Verbose, $"Parsing String ", new ColorMod(value, ConsoleColor.Cyan));
                time = new Stopwatch();
                time.Start();
            }

            //if (depth == 0)
            //foreach(string multiword in multiwordStrings)
            //value = value.Replace(multiword.Replace('_', ' '), multiword);

            string debug = new string(' ', depth * 4);

            // Loop through every string to search for.
            for (int i = 0; i < searchOrder.Length; i++)
            {
                string searchString = searchOrder[i];

                // Converts string parameters ({0}, {1}, {2}) to regex expressions to get the values.
                // {#} -> (.+)
                string regex =
                    Regex.Replace(Escape(searchString)
                                  , "({[0-9]})", @"(([a-z_.<>0-9-]+ ?)|(.+))");

                // Add the regex expressions start-of-line and end-of-line to ensure that the entire string is parsed.
                regex = "^" + regex + "$";

                // Match
                var match = Regex.Match(value, regex);
                if (match.Success)
                {
                    Log.Write(LogLevel.Verbose, new ColorMod(debug + searchString, ConsoleColor.Gray));

                    // Create a string element with the found string.
                    V_String str = new V_String(location, searchString);

                    bool           valid            = true;                 // Confirms that the arguments were able to successfully parse.
                    List <Element> parsedParameters = new List <Element>(); // The parameters that were successfully parsed.

                    // Iterate through the parameters.
                    for (int g = 1; g < match.Groups.Count; g += 3)
                    {
                        string currentParameterValue = match.Groups[g].Captures[0].Value;

                        // Test if the parameter is a format parameter, for example <0>, <1>, <2>, <3>...
                        Match parameterString = Regex.Match(currentParameterValue, "^<([0-9]+)>$");
                        if (parameters != null && parameterString.Success)
                        {
                            int index = int.Parse(parameterString.Groups[1].Value);

                            // Throw syntax error if the number of parameters is less than the parameter index being set.
                            if (index >= parameters.Length)
                            {
                                throw SyntaxErrorException.StringParameterCount(index, parameters.Length, location);
                            }

                            Log.Write(LogLevel.Verbose, $"{debug}    <param {index}>");
                            parsedParameters.Add(parameters[index]);
                        }
                        else
                        {
                            // Parse the parameter. If it fails it will return null and the string being checked is probably false.
                            var p = ParseString(location, currentParameterValue, parameters, depth + 1);
                            if (p == null)
                            {
                                Log.Write(LogLevel.Verbose, $"{debug}{searchString} ", new ColorMod("combo fail", ConsoleColor.DarkRed));
                                valid = false;
                                break;
                            }
                            parsedParameters.Add(p);
                        }
                    }
                    str.ParameterValues = parsedParameters.ToArray();

                    if (!valid)
                    {
                        continue;
                    }

                    if (depth == 0 && time != null)
                    {
                        Log.Write(LogLevel.Verbose,
                                  $"String build ",
                                  new ColorMod("completed", ConsoleColor.DarkGreen),
                                  " in ",
                                  new ColorMod(time.ElapsedMilliseconds.ToString(), ConsoleColor.DarkCyan),
                                  " ms.");
                    }

                    return(str);
                }
            }

            if (depth > 0)
            {
                return(null);
            }
            else
            {
                // If the depth is 0, throw a syntax error.
                throw SyntaxErrorException.StringParseFailed(value, location);
            }
        }