public static List<String> filterMatches(@Nullable List<String> candidates,
                                           @Nullable Pattern[] positivePatterns,
                                           @Nullable Pattern[] negativePatterns) {
    if (candidates == null || candidates.isEmpty()) {
      return Collections.emptyList();
    }
    final Pattern[] positive = (positivePatterns == null || positivePatterns.length == 0) ?
            MATCH_ALL_PATTERN : positivePatterns;
    final Pattern[] negative = negativePatterns == null ? EMPTY_PATTERN : negativePatterns;

    return candidates.stream()
            .filter(c -> Arrays.stream(positive).anyMatch(p -> p.matcher(c).matches()))
            .filter(c -> Arrays.stream(negative).noneMatch(p -> p.matcher(c).matches()))
            .collect(Collectors.toList());
  }
@Test
  public void filterMatchesNegative() {
    List<String> candidates = ImmutableList.of("a", "b");
    List<String> expected = ImmutableList.of("a");
    assertThat(filterMatches(candidates, null, new Pattern[]{Pattern.compile("b")}),
            is(expected));
  }