/**
   * Returns a function that filters a document map based on the given include and exclude rules.
   *
   * @see #filter(Map, String[], String[]) for details
   */
  public static Function<Map<String, ?>, Map<String, Object>> filter(
      String[] includes, String[] excludes) {
    CharacterRunAutomaton matchAllAutomaton = new CharacterRunAutomaton(Automata.makeAnyString());

    CharacterRunAutomaton include;
    if (includes == null || includes.length == 0) {
      include = matchAllAutomaton;
    } else {
      Automaton includeA = Regex.simpleMatchToAutomaton(includes);
      includeA = makeMatchDotsInFieldNames(includeA);
      include = new CharacterRunAutomaton(includeA);
    }

    Automaton excludeA;
    if (excludes == null || excludes.length == 0) {
      excludeA = Automata.makeEmpty();
    } else {
      excludeA = Regex.simpleMatchToAutomaton(excludes);
      excludeA = makeMatchDotsInFieldNames(excludeA);
    }
    CharacterRunAutomaton exclude = new CharacterRunAutomaton(excludeA);

    // NOTE: We cannot use Operations.minus because of the special case that
    // we want all sub properties to match as soon as an object matches

    return (map) -> filter(map, include, 0, exclude, 0, matchAllAutomaton);
  }
 /**
  * Build the {@link CharacterRunAutomaton} that represents the reindex-from-remote whitelist and
  * make sure that it doesn't whitelist the world.
  */
 static CharacterRunAutomaton buildRemoteWhitelist(List<String> whitelist) {
   if (whitelist.isEmpty()) {
     return new CharacterRunAutomaton(Automata.makeEmpty());
   }
   Automaton automaton = Regex.simpleMatchToAutomaton(whitelist.toArray(Strings.EMPTY_ARRAY));
   automaton =
       MinimizationOperations.minimize(automaton, Operations.DEFAULT_MAX_DETERMINIZED_STATES);
   if (Operations.isTotal(automaton)) {
     throw new IllegalArgumentException(
         "Refusing to start because whitelist "
             + whitelist
             + " accepts all addresses. "
             + "This would allow users to reindex-from-remote any URL they like effectively having Elasticsearch make HTTP GETs "
             + "for them.");
   }
   return new CharacterRunAutomaton(automaton);
 }