public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
        {
            bool isKeyValueArray = false; // This is false unless we en-counter a : symbol.

            // 1: = [1, 2, 3, 4];
            // 2: = ["foo": 1, "bar": 2, @t1: @t2];
            var items = new List<List<Token>>();
            var namedTokens = new Dictionary<List<Token>, List<Token>>();

            // There are only used if the we building a (key => value) array.
            int index = 0;
            List<Token> identifier = null;

            while (sourceCode.CurrentCode != ']')
            {
                List<Token> chunk = engine.BuildTokens(ref sourceCode, ref script, new[] {':', ',', ']'});
                if (sourceCode.CurrentCode == ':')
                {
                    isKeyValueArray = true;
                    identifier = chunk;
                }
                else if (sourceCode.CurrentCode == ',' || sourceCode.CurrentCode == ']')
                {
                    // End of current item.
                    if (isKeyValueArray)
                    {
                        if (identifier == null)
                        {
                            var id = new List<Token> {new ObjectToken<Number>(new Number(index))};
                            index++;
                            namedTokens[id] = chunk;
                        }
                        else
                        {
                            namedTokens[identifier] = chunk;
                        }
                        identifier = null;
                    }
                    else
                    {
                        items.Add(chunk);
                    }
                }
                if (sourceCode.CurrentCode != ']')
                {
                    sourceCode++;
                }
            }

            return isKeyValueArray ? new ArrayToken(namedTokens) : new ArrayToken(items);
        }
        public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
        {
            if (lastToken is VaraibleToken)
            {
                var arguments = new List<List<Token>>();
                // We are invoking a method.
                while (!sourceCode.EOF && sourceCode.GetOffset(1) != ')')
                {
                    arguments.Add(engine.BuildTokens(ref sourceCode, ref script, new[] {',', ')'}));
                    if (sourceCode.CurrentCode == ')')
                    {
                        break;
                    }
                    sourceCode++;
                }
                return new MethodInvokeToken(arguments);
            }
            else
            {
                List<Token> code = engine.BuildTokens(ref sourceCode, ref script, new[] {')'});

                return new RoundBracketToken(code);
            }
        }
        public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
        {
            sourceCode += 5;

            if (!sourceCode.SeekToNext('('))
            {
                sourceCode.Throw(String.Format("Expected '(', got '{0}' instead", sourceCode.NextCode));
            }

            List<Token> tokens = engine.BuildTokens(ref sourceCode, ref script, new[] {')'});

            sourceCode.SeekToNext(';'); // Go to the ;

            return new FixedToken(tokens);
        }
 public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
 {
     //sourceCode++;
     var arguments = new List<List<Token>>();
     while (!sourceCode.EOF && sourceCode.GetOffset(1) != ']')
     {
         arguments.Add(engine.BuildTokens(ref sourceCode, ref script, new[] {',', ']'}));
         if (sourceCode.CurrentCode == ']')
         {
             break;
         }
         sourceCode++;
     }
     return new ArrayAccessToken(arguments);
 }
        public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
        {
            // using (arg1, arg2, arg3) { }

            sourceCode += 5;

            if (!sourceCode.SeekToNext('('))
            {
                sourceCode.Throw("Expected (");
            }

            // Build up the arguments.
            Dictionary<string, List<Token>> items = new Dictionary<string, List<Token>>();

            while (sourceCode.CurrentCode != ')')
            {

                string name = sourceCode.NextWord();

                if (sourceCode.CurrentCode != '=')
                {
                    sourceCode.Throw(String.Format("Unexpected character, {0}.", sourceCode.CurrentCode));
                }

                // Otherwise...
                List<Token> code = engine.BuildTokens(ref sourceCode, ref script, new char[] {',', ')'});

                items.Add(name, code);

            }

            if (!sourceCode.SeekToNext('{'))
            {
                sourceCode.Throw(String.Format("Unexpected character, {0}", sourceCode.NextCode));
            }

            List<List<List<Token>>> codeBlock = engine.BuildLongTokens(ref sourceCode, ref script, new char[] {'}'});

            return new UsingToken(items, codeBlock);
        }
        public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
        {
            // Variable
            // Method()
            // Method<T>()
            // Method(args...)
            // Method<T>(args...)
            string name = "";
            var templates = new List<string>();
            var arguments = new List<List<Token>>();

            bool space = false;

            sourceCode++;

            // Firstly, get the name of the method.
            while (!sourceCode.EOF && !IsEndCondition(sourceCode.CurrentCode))
            {
                if (sourceCode.CurrentCode == ' ')
                {
                    space = true;
                }
                else
                {
                    if (space)
                    {
                        throw new Exception("Unexpected Whitespace");
                    }
                    name += sourceCode.CurrentCode;
                }
                sourceCode++;
            }

            if (sourceCode.EOF)
            {
                throw new Exception("Unexpected EOF");
            }

            var opens = new[] {'[', '.', '+', '-', '/', '%', '*', '&', ')', ']'};

            if (opens.Contains(sourceCode.CurrentCode))
            {
                // Opening statement, return what we have.
                return new TypeFunctionToken(name, new List<List<Token>>(), new List<string>(), false);
            }

            space = false;

            // Once we get here...
            if (sourceCode.CurrentCode == '<')
            {
                // Do Generics.
                string currentG = "";
                while (!sourceCode.EOF && sourceCode.CurrentCode != '>')
                {
                    if (sourceCode.CurrentCode == ' ')
                    {
                        space = true;
                    }
                    else
                    {
                        if (sourceCode.CurrentCode == ',')
                        {
                            templates.Add(currentG);
                            space = false;
                            currentG = "";
                        }
                        else
                        {
                            if (space)
                            {
                                throw new Exception("Unexpected Whitespace");
                            }
                            currentG += sourceCode.CurrentCode;
                        }
                    }
                }
                if (sourceCode.EOF)
                {
                    throw new Exception("Unexpected EOF");
                }
            }

            // We then expect a (...
            if (sourceCode.CurrentCode != '(' && sourceCode.CurrentCode != ';')
            {
                throw new Exception("Expected a (");
            }
            else
            {
                if (sourceCode.CurrentCode == ';')
                {
                    return new TypeFunctionToken(name, arguments, templates, false);
                }
                while (!sourceCode.EOF && sourceCode.GetOffset(1) != ')')
                {
                    arguments.Add(engine.BuildTokens(ref sourceCode, ref script, new[] {',', ')'}));
                    if (sourceCode.CurrentCode == ')')
                    {
                        break;
                    }
                    sourceCode++;
                }
            }

            return new TypeFunctionToken(name, arguments, templates);
        }
        public override Token Build(Token lastToken, ScriptEngine engine, Script script, ref SourceCode sourceCode)
        {
            // new {objectID}[<{templateArgs}

            sourceCode += 3;
            while (sourceCode.SpecialChar)
            {
                sourceCode++;
            }

            string name = "";
            var templates = new List<string>();
            var arguments = new List<List<Token>>();

            bool space = false;

            // Firstly, get the name of the method.
            while (!sourceCode.EOF && (sourceCode.CurrentCode != '<' && sourceCode.CurrentCode != '('))
            {
                if (sourceCode.CurrentCode == ' ')
                {
                    space = true;
                }
                else
                {
                    if (space)
                    {
                        throw new Exception("Unexpected Whitespace");
                    }
                    name += sourceCode.CurrentCode;
                }
                sourceCode++;
            }

            if (sourceCode.EOF)
            {
                throw new Exception("Unexpected EOF");
            }

            space = false;

            // Once we get here...
            if (sourceCode.CurrentCode == '<')
            {
                // Do Generics.
                string currentG = "";
                while (!sourceCode.EOF && sourceCode.CurrentCode != '>')
                {
                    if (sourceCode.CurrentCode == ' ')
                    {
                        space = true;
                    }
                    else
                    {
                        if (sourceCode.CurrentCode == ',')
                        {
                            templates.Add(currentG);
                            space = false;
                            currentG = "";
                        }
                        else
                        {
                            if (space)
                            {
                                throw new Exception("Unexpected Whitespace");
                            }
                            currentG += sourceCode.CurrentCode;
                        }
                    }
                }
                if (sourceCode.EOF)
                {
                    throw new Exception("Unexpected EOF");
                }
            }

            // We then expect a (...
            if (sourceCode.CurrentCode != '(' && sourceCode.CurrentCode != ';')
            {
                throw new Exception("Expected a (");
            }
            else
            {
                if (sourceCode.CurrentCode == ';')
                {
                    return new TypeFunctionToken(name, arguments, templates, false);
                }
                while (!sourceCode.EOF && sourceCode.GetOffset(1) != ')')
                {
                    arguments.Add(engine.BuildTokens(ref sourceCode, ref script, new[] {',', ')'}));
                    if (sourceCode.CurrentCode == ')')
                    {
                        break;
                    }
                    sourceCode++;
                }
            }

            return new NewTypeToken(name, arguments, templates);
        }
            public override void Build(ref SourceCode code, ref Script script, ScriptEngine engine, ConfigBuilder config)
            {
                var items = new Dictionary<string, List<Token>>();

                code += _identifier.Length;
                if (code.Peek() != '{')
                {
                    throw new Exception("Syntax Error: Expected a {");
                }

                code.SeekToNext('{');

                while (!(++code).EOF && code.Peek() != '}')
                {
                    // We are expecting: identifier = (code);
                    while (code.SpecialChar)
                    {
                        code++;
                    }
                    string id = "";
                    bool space = false;
                    while (!code.EOF && code.CurrentCode != '=')
                    {
                        if (code.CurrentCode == ' ')
                        {
                            space = true;
                        }
                        else
                        {
                            if (space)
                            {
                                code--; // Rewind, so the error is where the space is.
                                code.Throw("Unexpected whitespace...");
                            }
                            id += code.CurrentCode;
                        }
                        code++;
                    }
                    if (code.EOF)
                    {
                        code.Throw("Unexpected EOF");
                    }
                    // Otherwise
                    code++;

                    List<Token> tokens = engine.BuildTokens(ref code, ref script, new[] {';'});

                    items.Add(id, tokens);
                }

                code.SeekToNext('}');

                config.AddReturnElement(_identifier, items);
            }