class QueryMatchers {

    private Set<String> caseSensitiveTerms;
    private Set<String> caseInsensitiveTerms;
    private List<LineMatcher> matchers;
    private Map<String, Boolean> fields;

    /**
     * Get the terms from a query and returns a list of DFAs which match a stream
     * of tokens.
     *
     * @param query the query to generate matchers for
     * @param fields a map whose keys tell which fields to create matchers for,
     * and whose values tell if the field is case insensitive (true) or case
     * sensitive (false)
     * @return list of LineMatching DFAs
     */
    public LineMatcher[] getMatchers(Query query, Map<String, Boolean> fields) {
        caseSensitiveTerms = new HashSet<>();
        caseInsensitiveTerms = new HashSet<>();
        matchers = new ArrayList<>();
        this.fields = fields;
        getTerms(query);
        if (!caseSensitiveTerms.isEmpty()) {
            matchers.add(0, new TokenSetMatcher(caseSensitiveTerms, false));
        }
        if (!caseInsensitiveTerms.isEmpty()) {
            matchers.add(0, new TokenSetMatcher(caseInsensitiveTerms, true));
        }
        if (matchers.isEmpty()) {
            return null;
        }
        return matchers.toArray(new LineMatcher[0]);
    }

    private void getTerms(Query query) {
        if (query instanceof BooleanQuery) {
            getBooleans((BooleanQuery) query);
        } else if (query instanceof PhraseQuery) {
            getPhrases((PhraseQuery) query);
        } else if (query instanceof WildcardQuery) {
            getWildTerm((WildcardQuery) query);
        } else if (query instanceof TermQuery) {
            getTerm((TermQuery) query);
        } else if (query instanceof PrefixQuery) {
            getPrefix((PrefixQuery) query);
        } else if (query instanceof RegexpQuery) {
            getRegexp((RegexpQuery) query);
        }
    }

    private void getRegexp(RegexpQuery query) {
        if (useTerm(query.getField())) {
            String term = query.toString(query.getField());
            term = term.substring(1, term.length() - 1); //trim / from /regexp/
            matchers.add(new RegexpMatcher(term, true));
        }
    }

    private void getBooleans(BooleanQuery query) {
        for (BooleanClause clause : query) {
            if (!clause.isProhibited()) {
                getTerms(clause.getQuery());
            }
        }
    }

    private void getPhrases(PhraseQuery query) {
        Term[] queryTerms = query.getTerms();
        if (queryTerms.length > 0 && useTerm(queryTerms[0])) {
            boolean caseInsensitive = isCaseInsensitive(queryTerms[0]);
            String[] termsArray = new String[queryTerms.length];
            for (int i = 0; i < queryTerms.length; i++) {
                termsArray[i] = queryTerms[i].text();
            }
            matchers.add(new PhraseMatcher(termsArray, caseInsensitive));
        }
    }

    private void getTerm(TermQuery query) {
        Term term = query.getTerm();
        if (useTerm(term)) {
            String text = term.text();
            if (isCaseInsensitive(term)) {
                caseInsensitiveTerms.add(text);
            } else {
                caseSensitiveTerms.add(text);
            }
        }
    }

    private void getWildTerm(WildcardQuery query) {<FILL_FUNCTION_BODY>}

    private void getPrefix(PrefixQuery query) {
        Term term = query.getPrefix();
        if (useTerm(term)) {
            matchers.add(
                    new PrefixMatcher(term.text(), isCaseInsensitive(term)));
        }
    }

    /**
     * Check whether a matcher should be created for a term.
     */
    private boolean useTerm(Term term) {
        return useTerm(term.field());
    }

    /**
     * Check whether a matcher should be created for a term.
     */
    private boolean useTerm(String termField) {
        return fields.containsKey(termField);
    }

    /**
     * Check if a term should be matched in a case-insensitive manner. Should
     * only be called on terms for which {@link #useTerm(Term)} returns true.
     */
    private boolean isCaseInsensitive(Term term) {
        return fields.get(term.field());
    }
}

        Term term = query.getTerm();
        if (useTerm(term)) {
            matchers.add(
                    new WildCardMatcher(term.text(), isCaseInsensitive(term)));
        }
    
<no_super_class>