private boolean evaluate(List<String> matchKeys, Object value) {
      if (value == null || "".equals(value)) {
        return matchWhenMissing;
      } else if (value instanceof Collection<?> c) {
        if (c.isEmpty()) {
          return matchWhenMissing;
        } else {
          for (var item : c) {
            if (evaluate(matchKeys, item)) {
              return true;
            }
          }
          return false;
        }
      } else if (value instanceof Map<?, ?>) {
        return false;
      } else {
        String str = value.toString();
        // when field is null, we rely on a dynamic getter function so when exactMatches is empty we match
        // on any value
        if (exactMatches.contains(str) || (field == null && exactMatches.isEmpty())) {
          matchKeys.add(field);
          return true;
        }
        if (pattern != null && pattern.matcher(str).matches()) {
          matchKeys.add(field);
          return true;
        }
        return false;
      }
    }
Evaluates to true if the value for {@code field} tag is any of {@code exactMatches} or contains any of
{@code wildcards}.

@param values           all raw string values that were initially provided
@param exactMatches     the input {@code values} that should be treated as exact matches
@param pattern          regular expression that the value must match, or null
@param matchWhenMissing if {@code values} contained ""
planetiler-core/src/main/java/com/onthegomap/planetiler/expression/Expression.java