//////////////////////////////////////////////////////////////////////////
        private ScriptScope ParseFunction(ref List<ScriptToken>.Enumerator TokenEnum)
        {
            ScriptToken Token = TokenEnum.Current;
            if(Token==null) return null;

            // setup function
            ScriptFunction Func = new ScriptFunction();
            Func.Signature = Token.Value + " ";
            Func.Line = Token.OrigLine;
            Func.Filename = Token.Filename;
            switch(Token.Value)
            {
                case "function":
                    Func.Type = ScriptFunctionType.Function;
                    break;
                case "method":
                    Func.Type = ScriptFunctionType.Method;
                    break;
                case "external":
                    Func.Type = ScriptFunctionType.External;
                    break;
                default:
                    Func.Type = ScriptFunctionType.Unknown;
                    break;
            }

            // setup scope
            ScriptScope Scope = new ScriptScope();
            Scope.Owner = Func;
            Scope.StartLine = Token.StartLine;
            Scope.StartCol = Token.StartCol;

            bool ReadingName = true;
            bool ReadingParams = false;

            while (TokenEnum.MoveNext())
            {
                Token = TokenEnum.Current;
                if (Token.IsComment) continue;

                if (ReadingName)
                {
                    if (!Token.IsIdentifier)
                    {
                        if(Func.Type==ScriptFunctionType.External)
                        {
                            Func.Signature += Token.Value + " ";
                        }
                        else return null;
                    }
                    else
                    {
                        Func.Name = Token.Value;
                        Func.Signature += Token.Value;

                        ReadingName = false;
                    }
                }
                else if(ReadingParams)
                {
                    if (Token.IsOperator && Token.Value == ")")
                    {
                        Func.Signature += Token.Value;
                        break;
                    }
                    else if(Token.IsOperator && Token.Value==",")
                    {
                        Func.Signature += Token.Value + " ";
                    }
                    else
                    {
                        ScriptVariable Var = ParseVariable(ref TokenEnum, true);
                        if (Var == null) return null;
                        else
                        {
                            Func.Signature += Var.Signature;
                            Func.Params.Add(Var.Signature);

                            if(Var.Name!="") Scope.Variables.Add(Var);

                            // hack because of unnamed external's parameters
                            Token = TokenEnum.Current;
                            if(Token.IsOperator && Token.Value==")")
                            {
                                Func.Signature += Token.Value;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    if (Token.IsOperator && Token.Value == "(")
                    {
                        ReadingParams = true;
                        Func.Signature += Token.Value;
                    }
                    else return null;
                }
            }

            Functions.Add(Func);
            return Scope;
        }
        //////////////////////////////////////////////////////////////////////////
        private ScriptScope ParseFunction(ref List <ScriptToken> .Enumerator TokenEnum)
        {
            ScriptToken Token = TokenEnum.Current;

            if (Token == null)
            {
                return(null);
            }

            // setup function
            ScriptFunction Func = new ScriptFunction();

            Func.Signature = Token.Value + " ";
            Func.Line      = Token.OrigLine;
            Func.Filename  = Token.Filename;
            switch (Token.Value)
            {
            case "function":
                Func.Type = ScriptFunctionType.Function;
                break;

            case "method":
                Func.Type = ScriptFunctionType.Method;
                break;

            case "external":
                Func.Type = ScriptFunctionType.External;
                break;

            default:
                Func.Type = ScriptFunctionType.Unknown;
                break;
            }

            // setup scope
            ScriptScope Scope = new ScriptScope();

            Scope.Owner     = Func;
            Scope.StartLine = Token.StartLine;
            Scope.StartCol  = Token.StartCol;

            bool ReadingName   = true;
            bool ReadingParams = false;

            while (TokenEnum.MoveNext())
            {
                Token = TokenEnum.Current;
                if (Token.IsComment)
                {
                    continue;
                }

                if (ReadingName)
                {
                    if (!Token.IsIdentifier)
                    {
                        if (Func.Type == ScriptFunctionType.External)
                        {
                            Func.Signature += Token.Value + " ";
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        Func.Name       = Token.Value;
                        Func.Signature += Token.Value;

                        ReadingName = false;
                    }
                }
                else if (ReadingParams)
                {
                    if (Token.IsOperator && Token.Value == ")")
                    {
                        Func.Signature += Token.Value;
                        break;
                    }
                    else if (Token.IsOperator && Token.Value == ",")
                    {
                        Func.Signature += Token.Value + " ";
                    }
                    else
                    {
                        ScriptVariable Var = ParseVariable(ref TokenEnum, true);
                        if (Var == null)
                        {
                            return(null);
                        }
                        else
                        {
                            Func.Signature += Var.Signature;
                            Func.Params.Add(Var.Signature);

                            if (Var.Name != "")
                            {
                                Scope.Variables.Add(Var);
                            }

                            // hack because of unnamed external's parameters
                            Token = TokenEnum.Current;
                            if (Token.IsOperator && Token.Value == ")")
                            {
                                Func.Signature += Token.Value;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    if (Token.IsOperator && Token.Value == "(")
                    {
                        ReadingParams   = true;
                        Func.Signature += Token.Value;
                    }
                    else
                    {
                        return(null);
                    }
                }
            }

            Functions.Add(Func);
            return(Scope);
        }