/**
 * Copyright 2009-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.javacrumbs.jsonunit.core.internal;

import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;

import static java.util.stream.Collectors.toList;

abstract class PathMatcher {
    private static final PathMatcher EMPTY = new PathMatcher() {
        @Override
        boolean matches(String pathToMatch) {
            return false;
        }
    };

    abstract boolean matches(String pathToMatch);

    static PathMatcher create(Collection<String> paths) {
        if (paths == null || paths.isEmpty()) {
            return EMPTY;
        }
        List<PathMatcher> matchers = paths.stream().map(PathMatcher::create).collect(toList());
        return new AggregatePathMatcher(matchers);
    }

    static PathMatcher create(String path) {
        if (path.contains("[*]")) {
            return new ArrayWildcardMatcher(path);
        } else {
            return new SimplePathMatcher(path);
        }
    }

    private static class SimplePathMatcher extends PathMatcher {
        private final String path;

        SimplePathMatcher(String path) {
            this.path = path;
        }

        @Override
        boolean matches(String pathToMatch) {
            return path.equals(pathToMatch) || path.equals("$." + pathToMatch);
        }
    }

    /**
     * Matches array[*].something to array[1].something
     */
    private static class ArrayWildcardMatcher extends PathMatcher {
        private final Pattern pattern;

        ArrayWildcardMatcher(String path) {
            StringBuilder regexp = new StringBuilder();
            int from = 0;
            int to;
            while ((to = path.indexOf("[*]", from)) >= 0) {
                regexp
                    .append("\\Q")
                    .append(path.substring(from, to))
                    .append("\\E")
                    .append("\\[\\d+\\]");
                from = to + 3; // length of the placeholder [*]
            }
            // End of the pattern if any
            if (from < path.length()) {
                regexp
                    .append("\\Q")
                    .append(path.substring(from))
                    .append("\\E");
            }
            pattern = Pattern.compile(regexp.toString());
        }

        @Override
        boolean matches(String pathToMatch) {
            return pattern.matcher(pathToMatch).matches();
        }
    }

    private static class AggregatePathMatcher extends PathMatcher {

        private final Iterable<PathMatcher> pathMatchers;

        private AggregatePathMatcher(Iterable<PathMatcher> pathMatchers) {
            this.pathMatchers = pathMatchers;
        }

        @Override
        boolean matches(String path) {
            for (PathMatcher matcher : pathMatchers) {
                if (matcher.matches(path)) {
                    return true;
                }
            }
            return false;
        }
    }
}

@@ -3099,24 +3099,26 @@
 e final 
-Iterable
+Collection
 %3CPathMat
@@ -3179,16 +3179,18 @@
 her(
-Iterable
+Collection
 %3CPat
@@ -3345,14 +3345,16 @@
     
-for (P
+return p
 athM
@@ -3363,169 +3363,51 @@
 cher
- matcher : pathMatchers) %7B%0A                if (matcher.matches(path)) %7B%0A                    return true;%0A                %7D%0A            %7D%0A            return false
+s.stream().anyMatch(pm -%3E pm.matches(path))
 ;%0A  

Simplify matcher code