InlineShorthandEditor.prototype._done = function (event) {
        var newText = this.doc.getText(),
            start   = this.startBookmark.find(),
            end     = this.endBookmark.find();
        
        if (newText !== this.longhandText && start && end && this.provider) {
            var self = this;

            var longhandDeclList = ShorthandManager.parseDeclarationList(newText),
                shorthandDecl = self.provider.convertLonghandToShorthand(longhandDeclList),
                shorthandDeclList = [ shorthandDecl ],
                shorthandText = ShorthandManager.unparseDeclarationList(shorthandDeclList);

            // unparseDeclarationList() generates whole lines, which is great
            // for generating longhand for editor, but when replacing original
            // text in doc, we need to strip trailing newline because original
            // text doesn't have newline.
            shorthandText = shorthandText.replace(/\n$/, "");

            self.hostEditor.document.replaceRange(shorthandText, start, end);
        }

        this.close();
    };
    InlineShorthandEditor.prototype.load = function (hostEditor, startBookmark, endBookmark, decl) {
        InlineShorthandEditor.prototype.parentClass.load.apply(this, arguments);
        
        // FUTURE: when we migrate to CodeMirror v3, we might be able to use markText()
        // instead of two bookmarks to track the range. (In our current old version of
        // CodeMirror v2, markText() isn't robust enough for this case.)
        this.startBookmark = startBookmark;
        this.endBookmark   = endBookmark;
        
        // We don't create the actual editor here--that will happen the first time
        // setInlineContent() is called.
        this.$htmlContent.addClass("inline-shorthand-editor");
        $(shorthandEditorTemplate).appendTo(this.$htmlContent);
        this.$header = $(".inline-editor-header", this.$htmlContent);
        this.$editorHolder = $(".inline-editor-holder", this.$htmlContent);
        
        this._done = this._done.bind(this);
        this.$btnDone = this.$htmlContent.find(".btn-shorthand-done")
            .click(this._done);
        
        this._cancel = this._cancel.bind(this);
        this.$btnCancel = this.$htmlContent.find(".btn-shorthand-cancel")
            .click(this._cancel);
        
        var self = this;
        
        // Convert shorthand declaration to longhand declaration list
        if (this.provider) {
            this.longhandText = ShorthandManager.unparseDeclarationList(
                this.provider.convertShorthandToLonghand(decl)
            );
        }

        // Create an in-memory document with longhand text
        var filename = "temp-longhand.css",
            file = new InMemoryFile(filename, FileSystem);
        
        this.doc = new DocumentModule.Document(file, (new Date()), this.longhandText);

        var inlineContent = this.$editorHolder.get(0);
        
        // Create editor
        this.editor = new Editor(this.doc, true, inlineContent);

// TODO - Undo is not working (Redo, Cut, Copy, Paste, ...)

        // Always update the widget height when an inline editor completes a
        // display update
        $(this.editor).on("update", function (event, editor) {
            self.sizeInlineWidgetToContents(true);
        });

        // Size editor to content whenever text changes (via edits here or any
        // other view of the doc: Editor fires "change" any time its text
        // changes, regardless of origin)
        $(this.editor).on("change", function (event, editor) {
            if (self.hostEditor.isFullyVisible()) {
                self.sizeInlineWidgetToContents(true);
            }
        });

        // Prevent touch scroll events from bubbling up to the parent editor.
        this.$editorHolder.on("mousewheel.InlineShorthandEditor", function (e) {
            e.stopPropagation();
        });

        // Listen for clicks directly on us, so we can set focus back to the editor
        var clickHandler = this._onClick.bind(this);
        this.$htmlContent.on("click.InlineShorthandEditor", clickHandler);

        // Also handle mouseup in case the user drags a little bit
        this.$htmlContent.on("mouseup.InlineShorthandEditor", clickHandler);
    };