function _insertFontCompletionAtCursor(completion, editor, cursor) {
        var token;
        var actualCompletion = completion;
        var stringChar = "\"";
        
        if (_documentIsCSS(editor.document)) { // on the off-chance we changed documents, don't change anything
            token = parser.getFontTokenAtCursor(editor, cursor);
            if (token) {
                // get the correct string character if there is already one in use
                if (token.className === "string") {
                    stringChar = token.string.substring(0, 1);
                }

                // wrap the completion in string character if either 
                //  a.) we're inserting into a string, or 
                //  b.) the slug contains a space
                if (token.className === "string" || whitespaceRegExp.test(actualCompletion)) {
                    actualCompletion = stringChar + actualCompletion + stringChar;
                }

                // Check if we're modifying an existing string. If so, it's possible that we're
                // in a situation with only one quote (i.e. the parser thinks the rest of the
                // line is a string. So, we want to stop at the first occurrence of a comma or 
                // semi-colon.
                var endChar = token.end;
                if (token.className === "string") {
                    // Find the *first* comma or semi
                    var match = commaSemiRegExp.exec(token.string);
                    if (match) {
                        endChar = token.start + match.index;
                    }
                    
                }
                
                // HACK (tracking adobe/brackets#1688): We talk to the private CodeMirror instance
                // directly to replace the range instead of using the Document, as we should. The
                // reason is due to a flaw in our current document synchronization architecture when
                // inline editors are open.
                if (token.className === "string" || token.className === "variable-2" || token.className === "string-2") { // replace
                    editor._codeMirror.replaceRange(actualCompletion,
                                                 {line: cursor.line, ch: token.start},
                                                 {line: cursor.line, ch: endChar});
                } else { // insert
                    editor._codeMirror.replaceRange(actualCompletion, cursor);
                }
            }
        }
        
        // record it in our font history
        var i = lastTwentyFonts.indexOf(completion);
        if (i >= 0) {
            lastTwentyFonts.splice(i, 1);
        }
        lastTwentyFonts.splice(0, 0, completion); // add completion to front of array
        if (lastTwentyFonts.length > 20) {
            lastTwentyFonts.splice(20, lastTwentyFonts.length - 20);
        }
        prefs.setValue(PREFERENCES_FONT_HISTORY_KEY, lastTwentyFonts);
    }
 FontHints.prototype.hasHints = function (editor, implicitChar) {
     this.editor = editor;
     if (_documentIsCSS(editor.document)) {
         if (!implicitChar) {
             if (parser.getFontTokenAtCursor(editor, editor.getCursorPos())) {
                 return true;
             }
         } else if (fontnameStartRegExp.test(implicitChar)) {
             // We only display the hint list implicitly if the following conditions are both met:
             //   1. The implicit char is a word character or a quote (covered by the test above)
             //   2. We're in a font-family rule (covered by checking parser.getFontTokenAtCursor !== null)
             // We check them in this order because checking the implict char is much cheaper.
             var currentPosition = editor.getCursorPos();
             if (currentPosition.ch >= 1) {
                 var currentToken = parser.getFontTokenAtCursor(editor, editor.getCursorPos());
                 if (currentToken) {
                     return true;
                 }
             }
         }
     }
     return false;
 };
    FontHints.prototype.getHints = function (key) {
        var editor = this.editor,
            cursor = editor.getCursorPos(),
            query,
            lowerCaseQuery,
            token;
        
        if (_documentIsCSS(editor.document)) {
            token = parser.getFontTokenAtCursor(editor, cursor);
            if (token) {
                if (token.className === "string") { // is wrapped in quotes        
                    if (token.start < cursor.ch) { // actually in the text
                        query = token.string.substring(1, cursor.ch - token.start);
                        if (token.end === cursor.ch) { // at the end, so need to clip off closing quote
                            query = query.substring(0, query.length - 1);
                        }
                    } else { // not in the text
                        query = "";
                    }
                } else if (token.className === "variable-2" || token.className === "string-2") { // is not wrapped in quotes
                    query = token.string.substring(0, cursor.ch - token.start);
                } else { // after a ":", a space, or a ","
                    query = "";
                }

                // candidate hints are lower case, so the query should be too
                lowerCaseQuery = query.toLocaleLowerCase();

                // we're going to handle this query, so we need to add our UI
                setTimeout(_augmentCodeHintUI, 1);

                var candidates = parser.parseCurrentEditor(true);
                candidates = candidates.concat(lastTwentyFonts);
                candidates = candidates.concat(webfont.getWebsafeFonts());
                candidates = webfont.lowerSortUniqStringArray(candidates);
                candidates = webfont.filterAndSortArray(query, candidates);
                candidates = candidates.map(function (hint) {
                    var index       = hint.indexOf(lowerCaseQuery),
                        $hintObj    = $('<span>'),
                        slugs       = webfont.searchBySlug(hint);

                    // load the matching font scripts individually for cachability
                    slugs.forEach(function (slug) {
                        var font = webfont.getFontBySlug(slug),
                            script;
                        if (!(scriptCache.hasOwnProperty(slug))) {
                            script = webfont.createInclude([font]);
                            $(script).appendTo("head");
                            scriptCache[slug] = true;
                        }
                    });

                    // emphasize the matching substring
                    if (index >= 0) {
                        $hintObj.append(hint.slice(0, index))
                            .append($('<span>')
                                    .append(hint.slice(index, index + query.length))
                                    .css('font-weight', 'bold'))
                            .append(hint.slice(index + query.length));
                    } else {
                        $hintObj.text(hint);
                    }

                    // set the font family and attach the hint string as data
                    $hintObj
                        .append($('<span>')
                                .append(Strings.SAMPLE_TEXT)
                                .css('padding-right', '10px')
                                .css('float', 'right')
                                .css('font-family', hint + ", AdobeBlank"))
                        .data('hint', hint);
                    return $hintObj;
                });

                return {
                    hints: candidates,
                    match: null,
                    selectInitial: true
                };
            }
        }
        return null;
    };