/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

importScript("cm/codemirror.js");
importScript("cm/css.js");
importScript("cm/javascript.js");
importScript("cm/xml.js");
importScript("cm/htmlmixed.js");

importScript("cm/matchbrackets.js");
importScript("cm/closebrackets.js");
importScript("cm/markselection.js");
importScript("cm/comment.js");
importScript("cm/overlay.js");

importScript("cm/htmlembedded.js");
importScript("cm/clike.js");
importScript("cm/coffeescript.js");
importScript("cm/php.js");
importScript("cm/python.js");
importScript("cm/shell.js");
importScript("CodeMirrorUtils.js");

/**
 * @constructor
 * @extends {WebInspector.View}
 * @implements {WebInspector.TextEditor}
 * @param {?string} url
 * @param {WebInspector.TextEditorDelegate} delegate
 */
WebInspector.CodeMirrorTextEditor = function(url, delegate)
{
    WebInspector.View.call(this);
    this._delegate = delegate;
    this._url = url;

    this.registerRequiredCSS("cm/codemirror.css");
    this.registerRequiredCSS("cm/cmdevtools.css");

    this._codeMirror = window.CodeMirror(this.element, {
        lineNumbers: true,
        gutters: ["CodeMirror-linenumbers"],
        matchBrackets: true,
        smartIndent: false,
        styleSelectedText: true,
        electricChars: false,
        autoCloseBrackets: { explode: false }
    });
    this._codeMirror._codeMirrorTextEditor = this;

    CodeMirror.keyMap["devtools-common"] = {
        "Left": "goCharLeft",
        "Right": "goCharRight",
        "Up": "goLineUp",
        "Down": "goLineDown",
        "End": "goLineEnd",
        "Home": "goLineStartSmart",
        "PageUp": "goPageUp",
        "PageDown": "goPageDown",
        "Delete": "delCharAfter",
        "Backspace": "delCharBefore",
        "Tab": "defaultTab",
        "Shift-Tab": "indentLess",
        "Enter": "smartNewlineAndIndent",
        "Ctrl-Space": "autocomplete"
    };

    CodeMirror.keyMap["devtools-pc"] = {
        "Ctrl-A": "selectAll",
        "Ctrl-Z": "undoAndReveal",
        "Shift-Ctrl-Z": "redoAndReveal",
        "Ctrl-Y": "redo",
        "Ctrl-Home": "goDocStart",
        "Ctrl-Up": "goDocStart",
        "Ctrl-End": "goDocEnd",
        "Ctrl-Down": "goDocEnd",
        "Ctrl-Left": "goGroupLeft",
        "Ctrl-Right": "goGroupRight",
        "Alt-Left": "goLineStart",
        "Alt-Right": "goLineEnd",
        "Ctrl-Backspace": "delGroupBefore",
        "Ctrl-Delete": "delGroupAfter",
        "Ctrl-/": "toggleComment",
        fallthrough: "devtools-common"
    };

    CodeMirror.keyMap["devtools-mac"] = {
        "Cmd-A" : "selectAll",
        "Cmd-Z" : "undoAndReveal",
        "Shift-Cmd-Z": "redoAndReveal",
        "Cmd-Up": "goDocStart",
        "Cmd-Down": "goDocEnd",
        "Alt-Left": "goGroupLeft",
        "Alt-Right": "goGroupRight",
        "Cmd-Left": "goLineStartSmart",
        "Cmd-Right": "goLineEnd",
        "Alt-Backspace": "delGroupBefore",
        "Alt-Delete": "delGroupAfter",
        "Cmd-/": "toggleComment",
        fallthrough: "devtools-common"
    };

    WebInspector.settings.textEditorIndent.addChangeListener(this._updateEditorIndentation, this);
    this._updateEditorIndentation();
    WebInspector.settings.showWhitespacesInEditor.addChangeListener(this._updateCodeMirrorMode, this);

    this._codeMirror.setOption("keyMap", WebInspector.isMac() ? "devtools-mac" : "devtools-pc");
    this._codeMirror.setOption("flattenSpans", false);
    this._codeMirror.setOption("maxHighlightLength", 1000);
    this._codeMirror.setOption("mode", null);
    this._codeMirror.setOption("crudeMeasuringFrom", 1000);

    this._shouldClearHistory = true;
    this._lineSeparator = "\n";

    this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this._codeMirror);
    this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror);
    this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror);
    this._autocompleteController = new WebInspector.CodeMirrorTextEditor.AutocompleteController(this, this._codeMirror);

    this._codeMirror.on("change", this._change.bind(this));
    this._codeMirror.on("beforeChange", this._beforeChange.bind(this));
    this._codeMirror.on("gutterClick", this._gutterClick.bind(this));
    this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this));
    this._codeMirror.on("scroll", this._scroll.bind(this));
    this._codeMirror.on("focus", this._focus.bind(this));
    this._codeMirror.on("blur", this._blur.bind(this));
    this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false);

    this.element.addStyleClass("fill");
    this.element.style.overflow = "hidden";
    this.element.firstChild.addStyleClass("source-code");
    this.element.firstChild.addStyleClass("fill");
    this._elementToWidget = new Map();
    this._nestedUpdatesCounter = 0;

    this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
    this.element.addEventListener("keydown", this._handleKeyDown.bind(this), true);
    this.element.tabIndex = 0;

    this._setupSelectionColor();
    this._setupWhitespaceHighlight();
}

WebInspector.CodeMirrorTextEditor.autocompleteCommand = function(codeMirror)
{
    codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete();
}
CodeMirror.commands.autocomplete = WebInspector.CodeMirrorTextEditor.autocompleteCommand;

CodeMirror.commands.smartNewlineAndIndent = function(codeMirror)
{
    codeMirror.operation(innerSmartNewlineAndIndent.bind(this, codeMirror));

    function countIndent(line)
    {
        for(var i = 0; i < line.length; ++i) {
            if (!WebInspector.TextUtils.isSpaceChar(line[i]))
                return i;
        }
        return line.length;
    }

    function innerSmartNewlineAndIndent(codeMirror)
    {
        var cur = codeMirror.getCursor("start");
        var line = codeMirror.getLine(cur.line);
        var indent = cur.line > 0 ? countIndent(line) : 0;
        if (cur.ch <= indent) {
            codeMirror.replaceSelection("\n" + line.substring(0, cur.ch), "end", "+input");
            codeMirror.setSelection(new CodeMirror.Pos(cur.line + 1, cur.ch));
        } else
            codeMirror.execCommand("newlineAndIndent");
    }
}

CodeMirror.commands.undoAndReveal = function(codemirror)
{
    var scrollInfo = codemirror.getScrollInfo();
    codemirror.execCommand("undo");
    var cursor = codemirror.getCursor("start");
    codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
}

CodeMirror.commands.redoAndReveal = function(codemirror)
{
    var scrollInfo = codemirror.getScrollInfo();
    codemirror.execCommand("redo");
    var cursor = codemirror.getCursor("start");
    codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
}

WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000;
WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16;

WebInspector.CodeMirrorTextEditor.prototype = {
    wasShown: function()
    {
        this._codeMirror.refresh();
    },

    _guessIndentationLevel: function()
    {
        var tabRegex = /^\t+/;
        var tabLines = 0;
        var indents = {};
        function processLine(lineHandle)
        {
            var text = lineHandle.text;
            if (text.length === 0 || !WebInspector.TextUtils.isSpaceChar(text[0]))
                return;
            if (tabRegex.test(text)) {
                ++tabLines;
                return;
            }
            var i = 0;
            while (i < text.length && WebInspector.TextUtils.isSpaceChar(text[i]))
                ++i;
            if (i % 2 !== 0)
                return;
            indents[i] = 1 + (indents[i] || 0);
        }
        this._codeMirror.eachLine(processLine);

        var onePercentFilterThreshold = this.linesCount / 100;
        if (tabLines && tabLines > onePercentFilterThreshold)
            return "\t";
        var minimumIndent = Infinity;
        for (var i in indents) {
            if (indents[i] < onePercentFilterThreshold)
                continue;
            var indent = parseInt(i, 10);
            if (minimumIndent > indent)
                minimumIndent = indent;
        }
        if (minimumIndent === Infinity)
            return WebInspector.TextUtils.Indent.FourSpaces;
        return new Array(minimumIndent + 1).join(" ");
    },

    _updateEditorIndentation: function()
    {
        var extraKeys = {};
        var indent = WebInspector.settings.textEditorIndent.get();
        if (WebInspector.settings.textEditorAutoDetectIndent.get())
            indent = this._guessIndentationLevel();
        if (indent === WebInspector.TextUtils.Indent.TabCharacter) {
            this._codeMirror.setOption("indentWithTabs", true);
            this._codeMirror.setOption("indentUnit", 4);
        } else {
            this._codeMirror.setOption("indentWithTabs", false);
            this._codeMirror.setOption("indentUnit", indent.length);
            extraKeys.Tab = function(codeMirror)
            {
                if (codeMirror.somethingSelected())
                    return CodeMirror.Pass;
                var pos = codeMirror.getCursor("head");
                codeMirror.replaceRange(indent.substring(pos.ch % indent.length), codeMirror.getCursor());
            }
        }
        this._codeMirror.setOption("extraKeys", extraKeys);
        this._indentationLevel = indent;
    },

    /**
     * @return {string}
     */
    indent: function()
    {
        return this._indentationLevel;
    },

    /**
     * @param {!RegExp} regex
     * @param {WebInspector.TextRange} range
     */
    highlightSearchResults: function(regex, range)
    {
        function innerHighlightRegex()
        {
            if (range) {
                this.revealLine(range.startLine);
                this.setSelection(WebInspector.TextRange.createFromLocation(range.startLine, range.startColumn));
            } else {
                // Collapse selection to end on search start so that we jump to next occurence on the first enter press.
                this.setSelection(this.selection().collapseToEnd());
            }
            this._tokenHighlighter.highlightSearchResults(regex, range);
        }

        this._codeMirror.operation(innerHighlightRegex.bind(this));
    },

    cancelSearchResultsHighlight: function()
    {
        this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
    },

    undo: function()
    {
        this._codeMirror.undo();
    },

    redo: function()
    {
        this._codeMirror.redo();
    },

    _setupSelectionColor: function()
    {
        if (WebInspector.CodeMirrorTextEditor._selectionStyleInjected)
            return;
        WebInspector.CodeMirrorTextEditor._selectionStyleInjected = true;
        var backgroundColor = WebInspector.getSelectionBackgroundColor();
        var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : "";
        var foregroundColor = WebInspector.getSelectionForegroundColor();
        var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!important;}" : "";
        if (!foregroundColorRule && !backgroundColorRule)
            return;

        var style = document.createElement("style");
        style.textContent = backgroundColorRule + foregroundColorRule;
        document.head.appendChild(style);
    },

    _setupWhitespaceHighlight: function()
    {
        if (WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected || !WebInspector.settings.showWhitespacesInEditor.get())
            return;
        WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected = true;
        const classBase = ".cm-whitespace-";
        const spaceChar = "·";
        var spaceChars = "";
        var rules = "";
        for(var i = 1; i <= WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan; ++i) {
            spaceChars += spaceChar;
            var rule = classBase + i + "::before { content: '" + spaceChars + "';}\n";
            rules += rule;
        }
        rules += ".cm-tab:before { display: block !important; }\n";
        var style = document.createElement("style");
        style.textContent = rules;
        document.head.appendChild(style);
    },

    _handleKeyDown: function(e)
    {
        if (this._autocompleteController.keyDown(e))
            e.consume(true);
    },

    _shouldProcessWordForAutocompletion: function(word)
    {
        return word.length && (word[0] < '0' || word[0] > '9');
    },

    /**
     * @param {string} text
     */
    _addTextToCompletionDictionary: function(text)
    {
        var words = WebInspector.TextUtils.textToWords(text);
        for(var i = 0; i < words.length; ++i) {
            if (this._shouldProcessWordForAutocompletion(words[i]))
                this._dictionary.addWord(words[i]);
        }
    },

    /**
     * @param {string} text
     */
    _removeTextFromCompletionDictionary: function(text)
    {
        var words = WebInspector.TextUtils.textToWords(text);
        for(var i = 0; i < words.length; ++i) {
            if (this._shouldProcessWordForAutocompletion(words[i]))
                this._dictionary.removeWord(words[i]);
        }
    },

    /**
     * @param {WebInspector.CompletionDictionary} dictionary
     */
    setCompletionDictionary: function(dictionary)
    {
        this._dictionary = dictionary;
        this._addTextToCompletionDictionary(this.text());
    },

    /**
     * @param {number} lineNumber
     * @param {number} column
     * @return {?{x: number, y: number, height: number}}
     */
    cursorPositionToCoordinates: function(lineNumber, column)
    {
        if (lineNumber >= this._codeMirror.lineCount() || lineNumber < 0 || column < 0 || column > this._codeMirror.getLine(lineNumber).length)
            return null;

        var metrics = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, column));

        return {
            x: metrics.left,
            y: metrics.top,
            height: metrics.bottom - metrics.top
        };
    },

    /**
     * @param {number} x
     * @param {number} y
     * @return {?WebInspector.TextRange}
     */
    coordinatesToCursorPosition: function(x, y)
    {
        var element = document.elementFromPoint(x, y);
        if (!element || !element.isSelfOrDescendant(this._codeMirror.getWrapperElement()))
            return null;
        var gutterBox = this._codeMirror.getGutterElement().boxInWindow();
        if (x >= gutterBox.x && x <= gutterBox.x + gutterBox.width &&
            y >= gutterBox.y && y <= gutterBox.y + gutterBox.height)
            return null;
        var coords = this._codeMirror.coordsChar({left: x, top: y});
        return this._toRange(coords, coords);
    },

    /**
     * @param {number} lineNumber
     * @param {number} column
     * @return {?{startColumn: number, endColumn: number, type: string}}
     */
    tokenAtTextPosition: function(lineNumber, column)
    {
        if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
            return null;
        var token = this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber, (column || 0) + 1));
        if (!token || !token.type)
            return null;
        var convertedType = WebInspector.CodeMirrorUtils.convertTokenType(token.type);
        if (!convertedType)
            return null;
        return {
            startColumn: token.start,
            endColumn: token.end - 1,
            type: convertedType
        };
    },

    /**
     * @param {WebInspector.TextRange} textRange
     * @return {string}
     */
    copyRange: function(textRange)
    {
        var pos = this._toPos(textRange.normalize());
        return this._codeMirror.getRange(pos.start, pos.end);
    },

    /**
     * @return {boolean}
     */
    isClean: function()
    {
        return this._codeMirror.isClean();
    },

    markClean: function()
    {
        this._codeMirror.markClean();
    },

    _hasLongLines: function()
    {
        function lineIterator(lineHandle)
        {
            if (lineHandle.text.length > WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold)
                hasLongLines = true;
            return hasLongLines;
        }
        var hasLongLines = false;
        this._codeMirror.eachLine(lineIterator);
        return hasLongLines;
    },

    /**
     * @param {string} mimeType
     * @return {string}
     */
    _whitespaceOverlayMode: function(mimeType)
    {
        var modeName = CodeMirror.mimeModes[mimeType] + "+whitespaces";
        if (CodeMirror.modes[modeName])
            return modeName;

        function modeConstructor(config, parserConfig)
        {
            function nextToken(stream)
            {
                if (stream.peek() === " ") {
                    var spaces = 0;
                    while (spaces < WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan && stream.peek() === " ") {
                        ++spaces;
                        stream.next();
                    }
                    return "whitespace whitespace-" + spaces;
                }
                while (!stream.eol() && stream.peek() !== " ")
                    stream.next();
                return null;
            }
            var whitespaceMode = {
                token: nextToken
            };
            return CodeMirror.overlayMode(CodeMirror.getMode(config, mimeType), whitespaceMode, false);
        }
        CodeMirror.defineMode(modeName, modeConstructor);
        return modeName;
    },

    _enableLongLinesMode: function()
    {
        this._codeMirror.setOption("styleSelectedText", false);
        this._longLinesMode = true;
    },

    _disableLongLinesMode: function()
    {
        this._codeMirror.setOption("styleSelectedText", true);
        this._longLinesMode = false;
    },

    _updateCodeMirrorMode: function()
    {
        var showWhitespaces = WebInspector.settings.showWhitespacesInEditor.get();
        this._codeMirror.setOption("mode", showWhitespaces ? this._whitespaceOverlayMode(this._mimeType) : this._mimeType);
    },

    /**
     * @param {string} mimeType
     */
    setMimeType: function(mimeType)
    {
        this._mimeType = mimeType;
        if (this._hasLongLines())
            this._enableLongLinesMode();
        else
            this._disableLongLinesMode();
        this._updateCodeMirrorMode();
    },

    /**
     * @param {boolean} readOnly
     */
    setReadOnly: function(readOnly)
    {
        this.element.enableStyleClass("CodeMirror-readonly", readOnly)
        this._codeMirror.setOption("readOnly", readOnly);
    },

    /**
     * @return {boolean}
     */
    readOnly: function()
    {
        return !!this._codeMirror.getOption("readOnly");
    },

    /**
     * @param {Object} highlightDescriptor
     */
    removeHighlight: function(highlightDescriptor)
    {
        highlightDescriptor.clear();
    },

    /**
     * @param {WebInspector.TextRange} range
     * @param {string} cssClass
     * @return {Object}
     */
    highlightRange: function(range, cssClass)
    {
        cssClass = "CodeMirror-persist-highlight " + cssClass;
        var pos = this._toPos(range);
        ++pos.end.ch;
        return this._codeMirror.markText(pos.start, pos.end, {
            className: cssClass,
            startStyle: cssClass + "-start",
            endStyle: cssClass + "-end"
        });
    },

    /**
     * @param {string} regex
     * @param {string} cssClass
     * @return {Object}
     */
    highlightRegex: function(regex, cssClass) { },

    /**
     * @return {Element}
     */
    defaultFocusedElement: function()
    {
        return this.element;
    },

    focus: function()
    {
        this._codeMirror.focus();
    },

    _handleElementFocus: function()
    {
        this._codeMirror.focus();
    },

    beginUpdates: function()
    {
        ++this._nestedUpdatesCounter;
    },

    endUpdates: function()
    {
        if (!--this._nestedUpdatesCounter)
            this._codeMirror.refresh();
    },

    /**
     * @param {number} lineNumber
     */
    revealLine: function(lineNumber)
    {
        this._innerRevealLine(lineNumber, this._codeMirror.getScrollInfo());
    },

    /**
     * @param {number} lineNumber
     * @param {{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}} scrollInfo
     */
    _innerRevealLine: function(lineNumber, scrollInfo)
    {
        var topLine = this._codeMirror.lineAtHeight(scrollInfo.top, "local");
        var bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local");
        var linesPerScreen = bottomLine - topLine + 1;
        if (lineNumber < topLine) {
            var topLineToReveal = Math.max(lineNumber - (linesPerScreen / 2) + 1, 0) | 0;
            this._codeMirror.scrollIntoView(new CodeMirror.Pos(topLineToReveal, 0));
        } else if (lineNumber > bottomLine) {
            var bottomLineToReveal = Math.min(lineNumber + (linesPerScreen / 2) - 1, this.linesCount - 1) | 0;
            this._codeMirror.scrollIntoView(new CodeMirror.Pos(bottomLineToReveal, 0));
        }
    },

    _gutterClick: function(instance, lineNumber, gutter, event)
    {
        this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: lineNumber, event: event });
    },

    _contextMenu: function(event)
    {
        var contextMenu = new WebInspector.ContextMenu(event);
        var target = event.target.enclosingNodeOrSelfWithClass("CodeMirror-gutter-elt");
        if (target)
            this._delegate.populateLineGutterContextMenu(contextMenu, parseInt(target.textContent, 10) - 1);
        else
            this._delegate.populateTextAreaContextMenu(contextMenu, 0);
        contextMenu.show();
    },

    /**
     * @param {number} lineNumber
     * @param {boolean} disabled
     * @param {boolean} conditional
     */
    addBreakpoint: function(lineNumber, disabled, conditional)
    {
        if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
            return;
        var className = "cm-breakpoint" + (conditional ? " cm-breakpoint-conditional" : "") + (disabled ? " cm-breakpoint-disabled" : "");
        this._codeMirror.addLineClass(lineNumber, "wrap", className);
    },

    /**
     * @param {number} lineNumber
     */
    removeBreakpoint: function(lineNumber)
    {
        if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
            return;
        var wrapClasses = this._codeMirror.getLineHandle(lineNumber).wrapClass;
        if (!wrapClasses)
            return;
        var classes = wrapClasses.split(" ");
        for(var i = 0; i < classes.length; ++i) {
            if (classes[i].startsWith("cm-breakpoint"))
                this._codeMirror.removeLineClass(lineNumber, "wrap", classes[i]);
        }
    },

    /**
     * @param {number} lineNumber
     */
    setExecutionLine: function(lineNumber)
    {
        this._executionLine = this._codeMirror.getLineHandle(lineNumber);
        this._codeMirror.addLineClass(this._executionLine, "wrap", "cm-execution-line");
    },

    clearExecutionLine: function()
    {
        if (this._executionLine)
            this._codeMirror.removeLineClass(this._executionLine, "wrap", "cm-execution-line");
        delete this._executionLine;
    },

    /**
     * @param {number} lineNumber
     * @param {Element} element
     */
    addDecoration: function(lineNumber, element)
    {
        var widget = this._codeMirror.addLineWidget(lineNumber, element);
        this._elementToWidget.put(element, widget);
    },

    /**
     * @param {number} lineNumber
     * @param {Element} element
     */
    removeDecoration: function(lineNumber, element)
    {
        var widget = this._elementToWidget.remove(element);
        if (widget)
            this._codeMirror.removeLineWidget(widget);
    },

    /**
     * @param {number} lineNumber
     * @param {number=} columnNumber
     */
    highlightPosition: function(lineNumber, columnNumber)
    {
        if (lineNumber < 0)
            return;
        lineNumber = Math.min(lineNumber, this._codeMirror.lineCount() - 1);
        if (typeof columnNumber !== "number" || columnNumber < 0 || columnNumber > this._codeMirror.getLine(lineNumber).length)
            columnNumber = 0;

        this.clearPositionHighlight();
        this._highlightedLine = this._codeMirror.getLineHandle(lineNumber);
        if (!this._highlightedLine)
          return;
        this.revealLine(lineNumber);
        this._codeMirror.addLineClass(this._highlightedLine, null, "cm-highlight");
        this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
        if (!this.readOnly())
            this._codeMirror.setSelection(new CodeMirror.Pos(lineNumber, columnNumber));
    },

    clearPositionHighlight: function()
    {
        if (this._clearHighlightTimeout)
            clearTimeout(this._clearHighlightTimeout);
        delete this._clearHighlightTimeout;

         if (this._highlightedLine)
            this._codeMirror.removeLineClass(this._highlightedLine, null, "cm-highlight");
        delete this._highlightedLine;
    },

    /**
     * @return {Array.<Element>}
     */
    elementsToRestoreScrollPositionsFor: function()
    {
        return [];
    },

    /**
     * @param {WebInspector.TextEditor} textEditor
     */
    inheritScrollPositions: function(textEditor)
    {
    },

    /**
     * @param {number} width
     * @param {number} height
     */
    _updatePaddingBottom: function(width, height)
    {
        var scrollInfo = this._codeMirror.getScrollInfo();
        var newPaddingBottom;
        var linesElement = this.element.firstChild.querySelector(".CodeMirror-lines");
        var lineCount = this._codeMirror.lineCount();
        if (lineCount <= 1)
            newPaddingBottom = 0;
        else
            newPaddingBottom = Math.max(scrollInfo.clientHeight - this._codeMirror.getLineHandle(this._codeMirror.lastLine()).height, 0);
        newPaddingBottom += "px";
        linesElement.style.paddingBottom = newPaddingBottom;
        this._codeMirror.setSize(width, height);
    },

    _resizeEditor: function()
    {
        var parentElement = this.element.parentElement;
        if (!parentElement || !this.isShowing())
            return;
        var scrollInfo = this._codeMirror.getScrollInfo();
        var width = parentElement.offsetWidth;
        var height = parentElement.offsetHeight;
        this._codeMirror.setSize(width, height);
        this._updatePaddingBottom(width, height);
        this._codeMirror.scrollTo(scrollInfo.left, scrollInfo.top);
    },

    onResize: function()
    {
        this._resizeEditor();
    },

    /**
     * @param {WebInspector.TextRange} range
     * @param {string} text
     * @return {WebInspector.TextRange}
     */
    editRange: function(range, text)
    {
        var pos = this._toPos(range);
        this._codeMirror.replaceRange(text, pos.start, pos.end);
        var newRange = this._toRange(pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length));
        this._delegate.onTextChanged(range, newRange);
        if (WebInspector.settings.textEditorAutoDetectIndent.get())
            this._updateEditorIndentation();
        return newRange;
    },

    /**
     * @param {number} lineNumber
     * @param {number} column
     * @param {boolean=} prefixOnly
     * @return {?WebInspector.TextRange}
     */
    _wordRangeForCursorPosition: function(lineNumber, column, prefixOnly)
    {
        var line = this.line(lineNumber);
        if (column === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(column - 1)))
            return null;
        var wordStart = column - 1;
        while(wordStart > 0 && WebInspector.TextUtils.isWordChar(line.charAt(wordStart - 1)))
            --wordStart;
        if (prefixOnly)
            return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, column);
        var wordEnd = column;
        while(wordEnd < line.length && WebInspector.TextUtils.isWordChar(line.charAt(wordEnd)))
            ++wordEnd;
        return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, wordEnd);
    },

    _beforeChange: function(codeMirror, changeObject)
    {
        if (!this._dictionary)
            return;
        this._updatedLines = this._updatedLines || {};
        for(var i = changeObject.from.line; i <= changeObject.to.line; ++i)
            this._updatedLines[i] = this.line(i);
    },

    /**
     * @param {CodeMirror} codeMirror
     * @param {{origin: string, text: Array.<string>, removed: Array.<string>}} changeObject
     */
    _change: function(codeMirror, changeObject)
    {
        // We do not show "scroll beyond end of file" span for one line documents, so we need to check if "document has one line" changed.
        var hasOneLine = this._codeMirror.lineCount() === 1;
        if (hasOneLine !== this._hasOneLine)
            this._resizeEditor();
        this._hasOneLine = hasOneLine;
        var widgets = this._elementToWidget.values();
        for (var i = 0; i < widgets.length; ++i)
            this._codeMirror.removeLineWidget(widgets[i]);
        this._elementToWidget.clear();

        if (this._updatedLines) {
            for(var lineNumber in this._updatedLines)
                this._removeTextFromCompletionDictionary(this._updatedLines[lineNumber]);
            delete this._updatedLines;
        }

        var linesToUpdate = {};
        var singleCharInput = false;
        do {
            var oldRange = this._toRange(changeObject.from, changeObject.to);
            var newRange = oldRange.clone();
            var linesAdded = changeObject.text.length;
            singleCharInput = (changeObject.origin === "+input" && changeObject.text.length === 1 && changeObject.text[0].length === 1) ||
                (changeObject.origin === "+delete" && changeObject.removed.length === 1 && changeObject.removed[0].length === 1);
            if (linesAdded === 0) {
                newRange.endLine = newRange.startLine;
                newRange.endColumn = newRange.startColumn;
            } else if (linesAdded === 1) {
                newRange.endLine = newRange.startLine;
                newRange.endColumn = newRange.startColumn + changeObject.text[0].length;
            } else {
                newRange.endLine = newRange.startLine + linesAdded - 1;
                newRange.endColumn = changeObject.text[linesAdded - 1].length;
            }

            if (!this._muteTextChangedEvent)
                this._delegate.onTextChanged(oldRange, newRange);

            for(var i = newRange.startLine; i <= newRange.endLine; ++i) {
                linesToUpdate[i] = true;
            }
            if (this._dictionary) {
                for(var i = newRange.startLine; i <= newRange.endLine; ++i)
                    linesToUpdate[i] = this.line(i);
            }
        } while (changeObject = changeObject.next);
        if (this._dictionary) {
            for(var lineNumber in linesToUpdate)
                this._addTextToCompletionDictionary(linesToUpdate[lineNumber]);
        }
        if (singleCharInput)
            this._autocompleteController.autocomplete();
    },

    _cursorActivity: function()
    {
        var start = this._codeMirror.getCursor("anchor");
        var end = this._codeMirror.getCursor("head");
        this._delegate.selectionChanged(this._toRange(start, end));
        if (!this._tokenHighlighter.highlightedRegex())
            this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
    },

    _scroll: function()
    {
        if (this._scrollTimer)
            clearTimeout(this._scrollTimer);
        var topmostLineNumber = this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, "local");
        this._scrollTimer = setTimeout(this._delegate.scrollChanged.bind(this._delegate, topmostLineNumber), 100);
    },

    _focus: function()
    {
        this._delegate.editorFocused();
    },

    _blur: function()
    {
        this._autocompleteController.finishAutocomplete();
    },

    /**
     * @param {number} lineNumber
     */
    scrollToLine: function(lineNumber)
    {
        var pos = new CodeMirror.Pos(lineNumber, 0);
        var coords = this._codeMirror.charCoords(pos, "local");
        this._codeMirror.scrollTo(0, coords.top);
    },

    /**
     * @return {number}
     */
    firstVisibleLine: function()
    {
        return this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, "local");
    },

    /**
     * @return {number}
     */
    lastVisibleLine: function()
    {
        var scrollInfo = this._codeMirror.getScrollInfo();
        return this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local");
    },

    /**
     * @return {WebInspector.TextRange}
     */
    selection: function()
    {
        var start = this._codeMirror.getCursor("anchor");
        var end = this._codeMirror.getCursor("head");

        return this._toRange(start, end);
    },

    /**
     * @return {WebInspector.TextRange?}
     */
    lastSelection: function()
    {
        return this._lastSelection;
    },

    /**
     * @param {WebInspector.TextRange} textRange
     */
    setSelection: function(textRange)
    {
        this._lastSelection = textRange;
        var pos = this._toPos(textRange);
        this._codeMirror.setSelection(pos.start, pos.end);
    },

    /**
     * @param {string} text
     */
    _detectLineSeparator: function(text)
    {
        this._lineSeparator = text.indexOf("\r\n") >= 0 ? "\r\n" : "\n";
    },

    /**
     * @param {string} text
     */
    setText: function(text)
    {
        this._muteTextChangedEvent = true;
        this._codeMirror.setValue(text);
        this._updateEditorIndentation();
        if (this._shouldClearHistory) {
            this._codeMirror.clearHistory();
            this._shouldClearHistory = false;
        }
        this._detectLineSeparator(text);
        delete this._muteTextChangedEvent;
    },

    /**
     * @return {string}
     */
    text: function()
    {
        return this._codeMirror.getValue().replace(/\n/g, this._lineSeparator);
    },

    /**
     * @return {WebInspector.TextRange}
     */
    range: function()
    {
        var lineCount = this.linesCount;
        var lastLine = this._codeMirror.getLine(lineCount - 1);
        return this._toRange(new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length));
    },

    /**
     * @param {number} lineNumber
     * @return {string}
     */
    line: function(lineNumber)
    {
        return this._codeMirror.getLine(lineNumber);
    },

    /**
     * @return {number}
     */
    get linesCount()
    {
        return this._codeMirror.lineCount();
    },

    /**
     * @param {number} line
     * @param {string} name
     * @param {Object?} value
     */
    setAttribute: function(line, name, value)
    {
        if (line < 0 || line >= this._codeMirror.lineCount())
            return;
        var handle = this._codeMirror.getLineHandle(line);
        if (handle.attributes === undefined) handle.attributes = {};
        handle.attributes[name] = value;
    },

    /**
     * @param {number} line
     * @param {string} name
     * @return {?Object} value
     */
    getAttribute: function(line, name)
    {
        if (line < 0 || line >= this._codeMirror.lineCount())
            return null;
        var handle = this._codeMirror.getLineHandle(line);
        return handle.attributes && handle.attributes[name] !== undefined ? handle.attributes[name] : null;
    },

    /**
     * @param {number} line
     * @param {string} name
     */
    removeAttribute: function(line, name)
    {
        if (line < 0 || line >= this._codeMirror.lineCount())
            return;
        var handle = this._codeMirror.getLineHandle(line);
        if (handle && handle.attributes)
            delete handle.attributes[name];
    },

    /**
     * @param {WebInspector.TextRange} range
     * @return {{start: CodeMirror.Pos, end: CodeMirror.Pos}}
     */
    _toPos: function(range)
    {
        return {
            start: new CodeMirror.Pos(range.startLine, range.startColumn),
            end: new CodeMirror.Pos(range.endLine, range.endColumn)
        }
    },

    _toRange: function(start, end)
    {
        return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch);
    },

    __proto__: WebInspector.View.prototype
}

/**
 * @constructor
 * @param {CodeMirror} codeMirror
 */
WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(codeMirror)
{
    this._codeMirror = codeMirror;
}

WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
    /**
     * @param {RegExp} regex
     * @param {WebInspector.TextRange} range
     */
    highlightSearchResults: function(regex, range)
    {
        var oldRegex = this._highlightRegex;
        this._highlightRegex = regex;
        this._highlightRange = range;
        if (this._searchResultMarker) {
            this._searchResultMarker.clear();
            delete this._searchResultMarker;
        }
        if (this._highlightDescriptor && this._highlightDescriptor.selectionStart)
            this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection");
        var selectionStart = this._highlightRange ? new CodeMirror.Pos(this._highlightRange.startLine, this._highlightRange.startColumn) : null;
        if (selectionStart)
            this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection");
        if (this._highlightRegex === oldRegex) {
            // Do not re-add overlay mode if regex did not change for better performance.
            if (this._highlightDescriptor)
                this._highlightDescriptor.selectionStart = selectionStart;
        } else {
            this._removeHighlight();
            this._setHighlighter(this._searchHighlighter.bind(this, this._highlightRegex, this._highlightRange), selectionStart);
        }
        if (selectionStart) {
            var pos = WebInspector.CodeMirrorTextEditor.prototype._toPos(this._highlightRange);
            this._searchResultMarker = this._codeMirror.markText(pos.start, pos.end, {className: "cm-column-with-selection"});
        }
    },

    highlightedRegex: function()
    {
        return this._highlightRegex;
    },

    highlightSelectedTokens: function()
    {
        delete this._highlightRegex;
        delete this._highlightRange;

        if (this._highlightDescriptor && this._highlightDescriptor.selectionStart)
            this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection");
        this._removeHighlight();
        var selectionStart = this._codeMirror.getCursor("start");
        var selectionEnd = this._codeMirror.getCursor("end");
        if (selectionStart.line !== selectionEnd.line)
            return;
        if (selectionStart.ch === selectionEnd.ch)
            return;

        var selectedText = this._codeMirror.getSelection();
        if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, selectionEnd.ch)) {
            if (selectionStart)
                this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection")
            this._setHighlighter(this._tokenHighlighter.bind(this, selectedText, selectionStart), selectionStart);
        }
    },

    /**
     * @param {string} selectedText
     * @param {number} lineNumber
     * @param {number} startColumn
     * @param {number} endColumn
     */
    _isWord: function(selectedText, lineNumber, startColumn, endColumn)
    {
        var line = this._codeMirror.getLine(lineNumber);
        var leftBound = startColumn === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(startColumn - 1));
        var rightBound = endColumn === line.length || !WebInspector.TextUtils.isWordChar(line.charAt(endColumn));
        return leftBound && rightBound && WebInspector.TextUtils.isWord(selectedText);
    },

    _removeHighlight: function()
    {
        if (this._highlightDescriptor) {
            this._codeMirror.removeOverlay(this._highlightDescriptor.overlay);
            delete this._highlightDescriptor;
        }
    },

    /**
     * @param {RegExp} regex
     * @param {WebInspector.TextRange} range
     * @param {CodeMirror.StringStream} stream
     */
    _searchHighlighter: function(regex, range, stream)
    {
        if (stream.column() === 0)
            delete this._searchMatchLength;
        if (this._searchMatchLength) {
            if (this._searchMatchLength > 1) {
                for (var i = 0; i < this._searchMatchLength - 2; ++i)
                    stream.next();
                this._searchMatchLength = 1;
                return "search-highlight";
            } else {
                stream.next();
                delete this._searchMatchLength;
                return "search-highlight search-highlight-end";
            }
        }
        var match = stream.match(regex, false);
        if (match) {
            stream.next();
            var matchLength = match[0].length;
            if (matchLength === 1)
                return "search-highlight search-highlight-full";
            this._searchMatchLength = matchLength;
            return "search-highlight search-highlight-start";
        }

        while (!stream.match(regex, false) && stream.next()) {};
    },

    /**
     * @param {string} token
     * @param {CodeMirror.Pos} selectionStart
     * @param {CodeMirror.StringStream} stream
     */
    _tokenHighlighter: function(token, selectionStart, stream)
    {
        var tokenFirstChar = token.charAt(0);
        if (stream.match(token) && (stream.eol() || !WebInspector.TextUtils.isWordChar(stream.peek())))
            return stream.column() === selectionStart.ch ? "token-highlight column-with-selection" : "token-highlight";

        var eatenChar;
        do {
            eatenChar = stream.next();
        } while (eatenChar && (WebInspector.TextUtils.isWordChar(eatenChar) || stream.peek() !== tokenFirstChar));
    },

    /**
     * @param {function(CodeMirror.StringStream)} highlighter
     */
    _setHighlighter: function(highlighter, selectionStart)
    {
        var overlayMode = {
            token: highlighter
        };
        this._codeMirror.addOverlay(overlayMode);
        this._highlightDescriptor = {
            overlay: overlayMode,
            selectionStart: selectionStart
        };
    }
}

/**
 * @constructor
 * @param {CodeMirror} codeMirror
 */
WebInspector.CodeMirrorTextEditor.BlockIndentController = function(codeMirror)
{
    codeMirror.addKeyMap(this);
}

WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype = {
    name: "blockIndentKeymap",

    Enter: function(codeMirror)
    {
        if (codeMirror.somethingSelected())
            return CodeMirror.Pass;
        var cursor = codeMirror.getCursor();
        if (cursor.ch === 0)
            return CodeMirror.Pass;
        var line = codeMirror.getLine(cursor.line);
        if (line.substr(cursor.ch - 1, 2) === "{}") {
            codeMirror.execCommand("newlineAndIndent");
            codeMirror.setCursor(cursor);
            codeMirror.execCommand("newlineAndIndent");
            codeMirror.execCommand("indentMore");
        } else if (line.substr(cursor.ch - 1, 1) === "{") {
            codeMirror.execCommand("newlineAndIndent");
            codeMirror.execCommand("indentMore");
        } else
            return CodeMirror.Pass;
    },

    "'}'": function(codeMirror)
    {
        var cursor = codeMirror.getCursor();
        var line = codeMirror.getLine(cursor.line);
        for(var i = 0 ; i < line.length; ++i)
            if (!WebInspector.TextUtils.isSpaceChar(line.charAt(i)))
                return CodeMirror.Pass;

        codeMirror.replaceRange("}", cursor);
        var matchingBracket = codeMirror.findMatchingBracket();
        if (!matchingBracket || !matchingBracket.match)
            return;

        line = codeMirror.getLine(matchingBracket.to.line);
        var desiredIndentation = 0;
        while (desiredIndentation < line.length && WebInspector.TextUtils.isSpaceChar(line.charAt(desiredIndentation)))
            ++desiredIndentation;

        codeMirror.replaceRange(line.substr(0, desiredIndentation) + "}", new CodeMirror.Pos(cursor.line, 0), new CodeMirror.Pos(cursor.line, cursor.ch + 1));
    }
}

/**
 * @constructor
 * @param {CodeMirror} codeMirror
 */
WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror)
{
    function moveLeft(shift, codeMirror)
    {
        var cursor = codeMirror.getCursor("head");
        if (cursor.ch !== 0 || cursor.line === 0)
            return CodeMirror.Pass;
        codeMirror.setExtending(shift);
        codeMirror.execCommand("goLineUp");
        codeMirror.execCommand("goLineEnd")
        codeMirror.setExtending(false);
    }
    function moveRight(shift, codeMirror)
    {
        var cursor = codeMirror.getCursor("head");
        var line = codeMirror.getLine(cursor.line);
        if (cursor.ch !== line.length || cursor.line + 1 === codeMirror.lineCount())
            return CodeMirror.Pass;
        codeMirror.setExtending(shift);
        codeMirror.execCommand("goLineDown");
        codeMirror.execCommand("goLineStart");
        codeMirror.setExtending(false);
    }
    function delWordBack(codeMirror)
    {
        if (codeMirror.somethingSelected())
            return CodeMirror.Pass;
        var cursor = codeMirror.getCursor("head");
        if (cursor.ch === 0)
            codeMirror.execCommand("delCharBefore");
        else
            return CodeMirror.Pass;
    }

    var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl";
    var leftKey = modifierKey + "-Left";
    var rightKey = modifierKey + "-Right";
    var keyMap = {};
    keyMap[leftKey] = moveLeft.bind(this, false);
    keyMap[rightKey] = moveRight.bind(this, false);
    keyMap["Shift-" + leftKey] = moveLeft.bind(this, true);
    keyMap["Shift-" + rightKey] = moveRight.bind(this, true);
    keyMap[modifierKey + "-Backspace"] = delWordBack.bind(this);
    codeMirror.addKeyMap(keyMap);
}

/**
 * @constructor
 * @implements {WebInspector.SuggestBoxDelegate}
 * @param {WebInspector.CodeMirrorTextEditor} textEditor
 * @param {CodeMirror} codeMirror
 */
WebInspector.CodeMirrorTextEditor.AutocompleteController = function(textEditor, codeMirror)
{
    this._textEditor = textEditor;
    this._codeMirror = codeMirror;
    this._codeMirror.on("scroll", this._onScroll.bind(this));
    this._codeMirror.on("cursorActivity", this._onCursorActivity.bind(this));
}

WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
    autocomplete: function()
    {
        var dictionary = this._textEditor._dictionary;
        if (!dictionary || this._codeMirror.somethingSelected()) {
            this.finishAutocomplete();
            return;
        }

        var cursor = this._codeMirror.getCursor();
        var substituteRange = this._textEditor._wordRangeForCursorPosition(cursor.line, cursor.ch, false);
        if (!substituteRange || substituteRange.startColumn === cursor.ch) {
            this.finishAutocomplete();
            return;
        }
        var prefixRange = substituteRange.clone();
        prefixRange.endColumn = cursor.ch;

        var substituteWord = this._textEditor.copyRange(substituteRange);
        var hasPrefixInDictionary = dictionary.hasWord(substituteWord);
        if (hasPrefixInDictionary)
            dictionary.removeWord(substituteWord);
        var wordsWithPrefix = dictionary.wordsWithPrefix(this._textEditor.copyRange(prefixRange));
        if (hasPrefixInDictionary)
            dictionary.addWord(substituteWord);

        function sortSuggestions(a, b)
        {
            return dictionary.wordCount(b) - dictionary.wordCount(a) || a.length - b.length;
        }

        wordsWithPrefix.sort(sortSuggestions);

        if (!this._suggestBox) {
            this._suggestBox = new WebInspector.SuggestBox(this, this._textEditor.element, "generic-suggest", 6);
            this._anchorBox = this._anchorBoxForPosition(cursor.line, cursor.ch);
        }
        this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix, 0, true, this._textEditor.copyRange(prefixRange));
        this._prefixRange = prefixRange;
        if (!this._suggestBox.visible())
            this.finishAutocomplete();
    },

    finishAutocomplete: function()
    {
        if (!this._suggestBox)
            return;
        this._suggestBox.hide();
        this._suggestBox = null;
        this._prefixRange = null;
        this._anchorBox = null;
    },

    /**
     * @param {Event} e
     */
    keyDown: function(e)
    {
        if (!this._suggestBox)
            return false;
        if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
            this.finishAutocomplete();
            return true;
        }
        if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
            this._suggestBox.acceptSuggestion();
            this.finishAutocomplete();
            return true;
        }
        return this._suggestBox.keyPressed(e);
    },

    /**
     * @param {string} suggestion
     * @param {boolean=} isIntermediateSuggestion
     */
    applySuggestion: function(suggestion, isIntermediateSuggestion)
    {
        this._currentSuggestion = suggestion;
    },

    acceptSuggestion: function()
    {
        if (this._prefixRange.endColumn - this._prefixRange.startColumn !== this._currentSuggestion.length) {
            var pos = this._textEditor._toPos(this._prefixRange);
            this._codeMirror.replaceRange(this._currentSuggestion, pos.start, pos.end, "+autocomplete");
        }
    },

    _onScroll: function()
    {
        if (!this._suggestBox)
            return;
        var cursor = this._codeMirror.getCursor();
        var scrollInfo = this._codeMirror.getScrollInfo();
        var topmostLineNumber = this._codeMirror.lineAtHeight(scrollInfo.top, "local");
        var bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, "local");
        if (cursor.line < topmostLineNumber || cursor.line > bottomLine)
            this.finishAutocomplete();
        else {
            this._anchorBox = this._anchorBoxForPosition(cursor.line, cursor.ch);
            this._suggestBox.setPosition(this._anchorBox);
        }
    },

    _onCursorActivity: function()
    {
        if (!this._suggestBox)
            return;
        var cursor = this._codeMirror.getCursor();
        if (cursor.line !== this._prefixRange.startLine || cursor.ch > this._prefixRange.endColumn || cursor.ch < this._prefixRange.startColumn)
            this.finishAutocomplete();
    },

    /**
     * @param {number} line
     * @param {number} column
     * @return {AnchorBox}
     */
    _anchorBoxForPosition: function(line, column)
    {
        var metrics = this._textEditor.cursorPositionToCoordinates(line, column);
        return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null;
    },
}
