public void InitializeOpenedInsightWindow(ITextEditor editor, IInsightWindow insightWindow)
        {
            EventHandler<TextChangeEventArgs> on_document_changed = delegate{
                // whenever the document is changed, recalculate EndOffset
                var remaining_doc = editor.Document.CreateReader(insightWindow.StartOffset, editor.Document.TextLength - insightWindow.StartOffset);
                var lexer = new BVE5CommonLexer(remaining_doc);
                var line = editor.Document.GetLineForOffset(insightWindow.StartOffset);
                lexer.SetInitialLocation(line.LineNumber, insightWindow.StartOffset - editor.Document.PositionToOffset(line.LineNumber, 1));
                Token token;

                lexer.Advance();
                while((token = lexer.Current) != null && token.Kind != TokenKind.EOF){
                    if(token.Kind == TokenKind.EOL){
                        MarkInsightWindowEndOffset(insightWindow, editor, token.StartLoc);
                        break;
                    }
                    lexer.Advance();
                }
            };

            insightWindow.DocumentChanged += on_document_changed;
            insightWindow.SelectedItemChanged += delegate { HighlightParameter(insightWindow, highlighted_parameter); };
            on_document_changed(null, null);
        }
 // any-string(including file path)
 LiteralExpression ParseString(BVE5CommonLexer lexer)
 {
     Token token = lexer.Current;
     Debug.Assert(token.Kind == TokenKind.StringLiteral, "Really meant a string?");
     lexer.Advance();
     return AstNode.MakeLiteral(token.Literal, token.StartLoc, lexer.Current.StartLoc);
 }
        // number ':' number ':' number
        TimeFormatLiteral ParseTimeLiteral(BVE5CommonLexer lexer)
        {
            Token token = lexer.Current;
            Debug.Assert(token.Kind == TokenKind.IntegerLiteral, "Really meant a time literal?");
            int[] nums = new int[3];
            Token start_token = lexer.Current;

            for(int i = 0; i < 3; ++i){
                if(token.Kind == TokenKind.EOF){
                    AddError(ErrorCode.UnexpectedEOF, token.Line, token.Column, "Unexpected EOF!");
                    if(enable_strict_parsing)
                        return null;
                    else
                        break;
                }

                nums[i] = Convert.ToInt32(token.Literal);

                lexer.Advance();
                if(i == 2) break;

                token = lexer.Current;
                if(token.Kind == TokenKind.EOF){
                    AddError(ErrorCode.UnexpectedEOF, token.Line, token.Column, "Unexpected EOF!");
                    if(enable_strict_parsing)
                        return null;
                    else
                        break;
                }else if(token.Literal != ":"){
                    AddError(ErrorCode.SyntaxError, token.Line, token.Column, "Expected ':' but got " + token.Literal);
                    if(enable_strict_parsing)
                        return null;
                }

                lexer.Advance();
                token = lexer.Current;
            }

            return AstNode.MakeTimeFormat(nums[0], nums[1], nums[2], start_token.StartLoc, token.StartLoc);
        }
 // sequence '\n'
 Statement ParseStatement(BVE5CommonLexer lexer)
 {
     var command_invoke = ParseCommandInvoke(lexer);
     Token token = lexer.Current;
     if(token.Kind != TokenKind.EOL){
         AddError(ErrorCode.SyntaxError, token.Line, token.Column, "Expected EOL but got " + token.Literal + ".");
         if(enable_strict_parsing)
             return null;
     }else{
         lexer.Advance();
     }
     return AstNode.MakeStatement(command_invoke, command_invoke.StartLocation, token.EndLoc);
 }
 // number
 LiteralExpression ParseLiteral(BVE5CommonLexer lexer)
 {
     Token token = lexer.Current;
     Debug.Assert(token.Kind == TokenKind.IntegerLiteral || token.Kind == TokenKind.FloatLiteral, "Really meant a literal?");
     lexer.Advance();
     if(token.Kind == TokenKind.FloatLiteral)
         return AstNode.MakeLiteral(Convert.ToDouble(token.Literal), token.StartLoc, token.EndLoc);
     else
         return AstNode.MakeLiteral(Convert.ToInt32(token.Literal), token.StartLoc, token.EndLoc);
 }
        SyntaxTree ParseImpl(string src, string fileName, bool parseHeader)
        {
            lock(parse_lock){
                if(!src.EndsWith("\n"))
                    src += "\n";

                using(var reader = new StringReader(src)){
                    var lexer = new BVE5CommonLexer(reader);
                    lexer.Advance();

                    string version_str = "unknown";
                    if(parseHeader){
                        var token = lexer.Current;
                        lexer.Advance();

                        var meta_header_match = MetaHeaderRegexp.Match(token.Literal);
                        if(!meta_header_match.Success){
                            AddError(ErrorCode.InvalidFileHeader, 1, 1, "Invalid " + FileKind + " file!");
                            return null;
                        }else{
                            version_str = meta_header_match.Groups[1].Value;
                        }
                    }

                    if(lexer.Current.Kind == TokenKind.EOL)
                        lexer.Advance();

                    BVE5Language.Ast.Statement stmt = null;
                    var stmts = new List<BVE5Language.Ast.Statement>();
                    while(lexer.Current != Token.EOF){
                        stmt = ParseStatement(lexer);
                        if(enable_strict_parsing && !has_error_reported || !enable_strict_parsing)
                            stmts.Add(stmt);

                        if(has_error_reported)
                            has_error_reported = false;
                    }

                    return AstNode.MakeSyntaxTree(stmts, fileName, version_str, FileKind, new TextLocation(1, 1), stmts.Last().EndLocation, Errors.ToList());
                }
            }
        }
        // argument {',' argument}
        InvocationExpression ParseCommandInvoke(BVE5CommonLexer lexer)
        {
            Token token = lexer.Current;
            var start_loc = token.StartLoc;
            Expression expr = null;
            var children = new List<Expression>();
            while(token.Kind != TokenKind.EOF && token.Kind != TokenKind.EOL){
                expr = ParseArgument(lexer);
                children.Add(expr);
                token = lexer.Current;
                if(token.Literal == ","){
                    lexer.Advance();
                    token = lexer.Current;
                }
            }

            return AstNode.MakeInvoke(AstNode.MakeIdent(FileKind.ToString(), start_loc, start_loc), children, start_loc, token.StartLoc);
        }
        // literal
        Expression ParseArgument(BVE5CommonLexer lexer)
        {
            if(has_error_reported) return null;

            Token token = lexer.Current;
            switch(token.Kind){
            case TokenKind.StringLiteral:
                return ParseString(lexer);

            case TokenKind.IntegerLiteral:
            case TokenKind.FloatLiteral:
                var la = lexer.Peek;
                if(la.Literal == ":")
                    return ParseTimeLiteral(lexer);
                else
                    return ParseLiteral(lexer);

            default:
                AddError(ErrorCode.SyntaxError, token.Line, token.Column, "An argument must be a string, a literal or a time format literal!");
                return null;
            }
        }