function findSelectorAtDocumentPos(editor, pos) {
        var cm = editor._codeMirror;
        var ctx = TokenUtils.getInitialContext(cm, $.extend({}, pos));
        var selector = "", foundChars = false;
        var isPreprocessorDoc = isCSSPreprocessorFile(editor.document.file.fullPath);
        var selectorArray = [];

        function _skipToOpeningBracket(ctx, startChar) {
            var unmatchedBraces = 0;
            if (!startChar) {
                startChar = "}";
            }
            while (true) {
                if (startChar === ctx.token.string) {
                    unmatchedBraces++;
                } else if (ctx.token.string.match(_invertedBracketPairs[startChar])) {
                    unmatchedBraces--;
                    if (unmatchedBraces <= 0) {
                        return;
                    }
                }

                if (!TokenUtils.movePrevToken(ctx)) {
                    return;
                }
            }
        }

        // Parse a selector. Assumes ctx is pointing at the opening
        // { that is after the selector name.
        function _parseSelector(ctx) {
            var selector = "";

            // Skip over {
            TokenUtils.movePrevToken(ctx);

            while (true) {
                if (ctx.token.type !== "comment") {
                    // Stop once we've reached a {, }, or ;
                    if (/[\{\}\;]/.test(ctx.token.string)) {
                        break;
                    }

                    // Stop once we've reached a <style ...> tag
                    if (ctx.token.string === "style" && ctx.token.type === "tag") {
                        // Remove everything up to end-of-tag from selector
                        var eotIndex = selector.indexOf(">");
                        if (eotIndex !== -1) {
                            selector = selector.substring(eotIndex + 1);
                        }
                        break;
                    }

                    selector = ctx.token.string + selector;
                }
                if (!TokenUtils.movePrevToken(ctx)) {
                    break;
                }
            }

            return selector;
        }

        var skipPrevSibling = false,
            state           = _getContextState(ctx);

        // If the cursor is inside a non-whitespace token with "block" or "top" state, then it is inside a
        // selector. The only exception is when it is immediately after the '{'.
        if (isPreprocessorDoc && _hasNonWhitespace(ctx.token.string) && ctx.token.string !== "{" &&
                (state.state === "block" || state.state === "top")) {
            foundChars = true;
        }

        // scan backwards to see if the cursor is in a rule
        do {
            if (ctx.token.type !== "comment") {
                if (ctx.token.string === "}") {
                    if (isPreprocessorDoc) {
                        if (state.state === "top") {
                            break;
                        }
                        skipPrevSibling = true;
                        // Skip past the entire preceding block until the matching "{"
                        _skipToOpeningBracket(ctx, "}");
                    } else {
                        break;
                    }
                } else if (ctx.token.string === "{") {
                    selector = _parseSelector(ctx);
                    if (isPreprocessorDoc) {
                        if (!skipPrevSibling && !/^\s*@/.test(selector)) {
                            selectorArray.unshift(selector);
                        }
                        if (skipPrevSibling) {
                            skipPrevSibling = false;
                        }
                    } else {
                        break;
                    }
                } else {
                    if (!isPreprocessorDoc && _hasNonWhitespace(ctx.token.string)) {
                        foundChars = true;
                    }
                    TokenUtils.movePrevToken(ctx);
                }
            } else {
                TokenUtils.movePrevToken(ctx);
            }
        } while (!TokenUtils.isAtStart(ctx));

        selector = _stripAtRules(selector);

        // Reset the context to original scan position
        ctx = TokenUtils.getInitialContext(cm, $.extend({}, pos));

        // special case - we aren't in a selector and haven't found any chars,
        // look at the next immediate token to see if it is non-whitespace.
        // For preprocessor documents we need to move the cursor to next non-whitespace
        // token so that we can collect the current selector if the cursor is inside it.
        if ((!selector && !foundChars && !isPreprocessorDoc) ||
                (isPreprocessorDoc && (ctx.token.string === "" || /\s+/.test(ctx.token.string)))) {
            if (TokenUtils.moveNextToken(ctx) && ctx.token.type !== "comment" && _hasNonWhitespace(ctx.token.string)) {
                foundChars = true;
                ctx = TokenUtils.getInitialContext(cm, $.extend({}, pos));
            }
        }

        // At this point if we haven't found a selector, but have seen chars when
        // scanning, assume we are in the middle of a selector. For a preprocessor
        // document we also need to collect the current selector if the cursor is
        // within the selector or whitespaces immediately before or after it.
        if ((!selector || isPreprocessorDoc) && foundChars) {
            // scan forward to see if the cursor is in a selector
            while (true) {
                if (ctx.token.type !== "comment") {
                    if (ctx.token.string === "{") {
                        selector = _parseSelector(ctx);
                        if (isPreprocessorDoc && !/^\s*@/.test(selector)) {
                            selectorArray.push(selector);
                        }
                        break;
                    } else if (ctx.token.string === "}" || ctx.token.string === ";") {
                        break;
                    }
                }
                if (!TokenUtils.moveNextToken(ctx)) {
                    break;
                }
            }
        }

        if (isPreprocessorDoc) {
            return _getSelectorInFinalCSSForm(selectorArray);
        }

        return _stripAtRules(selector);
    }
Returns the selector(s) of the rule at the specified document pos, or "" if the position is
is not within a style rule.

@param {!Editor} editor Editor to search
@param {!{line: number, ch: number}} pos Position to search
@return {string} Selector(s) for the rule at the specified position, or "" if the position
         is not within a style rule. If the rule has multiple selectors, a comma-separated
         selector string is returned.