public Tuple<bool, CodeCompletionKeyPressResult> TryComplete(ITextEditor editor, char ch, IInsightWindowHandler insightWindowHandler)
        {
            int cursor_offset = editor.Caret.Offset;
            if(ch == '['){
                var list = CompletionDataHelper.GenerateCompletionList(SemanticInfo.Keys.ToList(),
                                                                       SemanticInfo.Select(info => BVE5ResourceManager.GetDocumentationString(info.Value.Doc)).ToList(),
                                                                      null);
                editor.ShowCompletionWindow(list);
                return Tuple.Create(true, CodeCompletionKeyPressResult.Completed);
            }else if(char.IsLetter(ch)){
                var caret_line_num = editor.Caret.Line;
                var tree = parser.Parse(editor.Document.GetText(0, editor.Document.PositionToOffset(caret_line_num, 1)), "<string>", true);
                var section_stmts = tree.FindNodes(node => node.Type == NodeType.SectionStmt).OfType<SectionStatement>();	//retrieve all section statements up to the current caret position
                var context_stmt = section_stmts.LastOrDefault();

                //if the context statement is null, it must be in a vehicle parameters file
                var section_name = (context_stmt != null) ? context_stmt.SectionName.Name : "Global";
                var section_semantic_info = SemanticInfo[section_name];
                var list = CompletionDataHelper.GenerateCompletionList(section_semantic_info.Keys.Select(key => key.Name).ToList(),
                                                                       section_semantic_info.Keys.Select(key => BVE5ResourceManager.GetDocumentationString(key.Doc)).ToList(),
                                                                      null);
                editor.ShowCompletionWindow(list);
                return Tuple.Create(true, CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion);
            }

            return Tuple.Create(false, CodeCompletionKeyPressResult.None);
        }
        public Tuple<bool, CodeCompletionKeyPressResult> TryComplete(ITextEditor editor, char ch, IInsightWindowHandler insightWindowHandler)
        {
            int cursor_offset = editor.Caret.Offset;
            if(char.IsLetterOrDigit(ch) && CodeCompletionOptions.InsightEnabled){
                var insight_window = editor.ShowInsightWindow(new []{ProvideInsight(editor)});
                if(insight_window != null && insightWindowHandler != null){
                    insightWindowHandler.InitializeOpenedInsightWindow(editor, insight_window);
                    insightWindowHandler.HighlightParameter(insight_window, 0);
                }
                return Tuple.Create(true, CodeCompletionKeyPressResult.Completed);
            }

            return Tuple.Create(false, CodeCompletionKeyPressResult.None);
        }
        public Tuple<bool, CodeCompletionKeyPressResult> TryComplete(ITextEditor editor, char ch, IInsightWindowHandler insightWindowHandler)
        {
            int cursor_offset = editor.Caret.Offset;
            if(ch == '['){
                var line = editor.Document.GetLineForOffset(cursor_offset);
                current_context_type = line.Text.Trim();
                var provider = new UserDefinedNameCompletionItemProvider(current_context_type);
                var list = provider.Provide(editor);
                if(list != null){
                    editor.ShowCompletionWindow(list);
                    return Tuple.Create(true, CodeCompletionKeyPressResult.Completed);
                }else{
                    return Tuple.Create(false, CodeCompletionKeyPressResult.None);
                }
            }else if(ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled){
                IInsightWindow insight_window;
                if(insightWindowHandler.InsightRefreshOnComma(editor, ch, out insight_window))
                    return Tuple.Create(true, CodeCompletionKeyPressResult.Completed);
            }else if(ch == '.'){
                var line = editor.Document.GetLineForOffset(cursor_offset);
                var type_name = (current_context_type != null) ? current_context_type : line.Text.Trim();
                var semantic_infos = BVE5ResourceManager.RouteFileSemanticInfos;
                var result = CodeCompletionKeyPressResult.None;
                if(semantic_infos.ContainsKey(type_name)){
                    var type_semantic_info = semantic_infos[type_name];

                    var names = type_semantic_info
                        .Where(member => member.Key != "indexer")
                        .Select(m => m.Key)
                        .Distinct()
                        .ToList();
                    var descriptions = type_semantic_info
                        .Where(member => member.Key != "indexer")
                        .Select(m => BVE5ResourceManager.GetDocumentationString(m.Value[0].Doc))
                        .ToList();

                    var list = CompletionDataHelper.GenerateCompletionList(names, descriptions);
                    editor.ShowCompletionWindow(list);
                    result = CodeCompletionKeyPressResult.Completed;
                }

                if(current_context_type != null) current_context_type = null;

                return Tuple.Create(result != CodeCompletionKeyPressResult.None, result);
            }else if(ch == '(' && CodeCompletionOptions.InsightEnabled){
                var insight_window = editor.ShowInsightWindow(ProvideInsight(editor));
                if(insight_window != null && insightWindowHandler != null){
                    insightWindowHandler.InitializeOpenedInsightWindow(editor, insight_window);
                    insightWindowHandler.HighlightParameter(insight_window, 0);
                }
                return Tuple.Create(true, CodeCompletionKeyPressResult.Completed);
            }

            if(char.IsLetter(ch) && CodeCompletionOptions.CompleteWhenTyping){
                var builtin_type_names = BVE5ResourceManager.GetAllTypeNames();
                var list = CompletionDataHelper.GenerateCompletionList(builtin_type_names);
                list = AddTemplateCompletionItems(editor, list, ch);
                editor.ShowCompletionWindow(list);
                return Tuple.Create(true, CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion);
            }

            return Tuple.Create(false, CodeCompletionKeyPressResult.None);
        }