private boolean looksLikeExactEnd(int end) {
        int parens = parensToEat;
        boolean wantStar = true;
        boolean wantBang = true;
        boolean eatDigit = false;

        int endLimit = source.length();

        while (end < endLimit) {
            char c = source.charAt(end++);

            if (Character.isWhitespace(c)) {
                // ends in whitespace
                return true;
            }
            // handle digits (after a ! sign)
            if (eatDigit && Character.isDigit(c)) {
                continue;
            }
            eatDigit = false;

            // ! digits or any number of ! signs:
            if (wantBang && c == '!') {
                eatDigit = true;
                while (end < endLimit) {
                    c = source.charAt(end);
                    if (c == '!') {
                        end++;
                        // more than one ! -> do not eat digits
                        eatDigit = false;
                    } else {
                        break;
                    }
                }
                wantBang = false;
                continue;
            }

            // star meaning prefix after a string:
            if (wantStar && (c == '*' || c == '\uFF0A')) {
                wantStar = false;
                continue;
            }

            // parens ending a group:
            if (parens > 0 && c == ')') {
                parens--;
                continue;
            }

            // something else
            return false;
        }
        // end of field
        return true;
    }
Resets this tokenizer and create tokens from the given string.

@param string the string to tokenize
@param defaultIndexName the name of the index to use as default
@param indexFacts information about the indexes we will search
@return a read-only list of tokens. This list can only be used by this thread
container-search/src/main/java/com/yahoo/prelude/query/parser/Tokenizer.java