package aQute.bnd.maven.lib.configuration;

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

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.apache.maven.plugin.MojoExecutionException;

import aQute.libg.glob.AntGlob;

public class FileTree {
	private List<File>			files		= new ArrayList<>();
	private List<Pattern>		includes	= new ArrayList<>();
	private List<Pattern>		excludes	= new ArrayList<>();

	public FileTree() {}

	/**
	 * Can be used by subclasses to add specific files to the return value of
	 * {@link #getFiles(File, String)}.
	 * 
	 * @param file A file to include in the return value of
	 *            {@link #getFiles(File, String)}.
	 */
	protected void addFile(File file) {
		if (!files.contains(file)) {
			files.add(file);
		}
	}

	/**
	 * Add an Ant-style glob to the include patterns.
	 * 
	 * @param include Add an Ant-style glob
	 */
	public void setInclude(String include) {
		includes.add(AntGlob.toPattern(include));
	}

	/**
	 * Add an Ant-style glob to the exclude patterns.
	 * 
	 * @param exclude Add an Ant-style glob
	 */
	public void setExclude(String exclude) {
		excludes.add(AntGlob.toPattern(exclude));
	}

	/**
	 * Return a list of files using the specified baseDir and the configured
	 * include and exclude Ant-style glob expressions.
	 * 
	 * @param baseDir The base directory for locating files.
	 * @param defaultInclude The default include pattern to use of no include
	 *            patterns were configured.
	 * @return A list of files.
	 * @throws MojoExecutionException If an exception occurs.
	 */
	public List<File> getFiles(File baseDir, String defaultInclude) throws MojoExecutionException {
		List<Pattern> includePatterns = includes.isEmpty() && files.isEmpty() && (defaultInclude != null)
			? singletonList(AntGlob.toPattern(defaultInclude))
			: includes;
		if (includePatterns.isEmpty()) {
			return files;
		}
		List<Pattern> excludePatterns = excludes;

		Path basePath = baseDir.toPath();
		Stream<Path> walker;
		try {
			walker = Files.walk(basePath)
				.skip(1); // skip basePath itself
		} catch (IOException ioe) {
			throw new MojoExecutionException(ioe.getMessage(), ioe);
		}
		List<File> result = Stream.concat(files.stream(), //
			walker.filter(p -> {
				String path = basePath.relativize(p)
					.toString();
				return includePatterns.stream()
					.anyMatch(i -> i.matcher(path)
						.matches())
					&& !excludePatterns.stream()
						.anyMatch(e -> e.matcher(path)
							.matches());
			})
				.sorted()
				.map(Path::toFile))
			.distinct()
			.collect(toList());
		return result;
	}
}

@@ -493,17 +493,16 @@
 %3CFile%3E%09%09
-%09
 files%09%09=
@@ -543,17 +543,16 @@
 Pattern%3E
-%09
 %09include
@@ -596,17 +596,16 @@
 Pattern%3E
-%09
 %09exclude
@@ -2181,16 +2181,21 @@
 th();%0A%09%09
+try (
 Stream%3CP
@@ -2203,27 +2203,8 @@
 th%3E 
-walker;%0A%09%09try %7B%0A%09%09%09
 walk
@@ -2236,17 +2236,16 @@
 %0A%09%09%09
-%09
 .skip(1)
 ; //
@@ -2240,17 +2240,19 @@
 .skip(1)
-;
+) %7B
  // skip
@@ -2273,101 +2273,8 @@
 lf%0A%09
-%09%7D catch (IOException ioe) %7B%0A%09%09%09throw new MojoExecutionException(ioe.getMessage(), ioe);%0A%09%09%7D%0A
 %09%09Li
@@ -2327,16 +2327,17 @@
 , //%0A%09%09%09
+%09
 walker.f
@@ -2349,16 +2349,17 @@
 (p -%3E %7B%0A
+%09
 %09%09%09%09Stri
@@ -2396,16 +2396,17 @@
 p)%0A%09%09%09%09%09
+%09
 .toStrin
@@ -2410,16 +2410,17 @@
 ring();%0A
+%09
 %09%09%09%09retu
@@ -2448,24 +2448,25 @@
 ream()%0A%09%09%09%09%09
+%09
 .anyMatch(i 
@@ -2480,24 +2480,25 @@
 tcher(path)%0A
+%09
 %09%09%09%09%09%09.match
@@ -2508,16 +2508,17 @@
 ))%0A%09%09%09%09%09
+%09
 && !excl
@@ -2530,32 +2530,33 @@
 tterns.stream()%0A
+%09
 %09%09%09%09%09%09.anyMatch(
@@ -2568,32 +2568,33 @@
 e.matcher(path)%0A
+%09
 %09%09%09%09%09%09%09.matches(
@@ -2604,11 +2604,13 @@
 %0A%09%09%09
+%09
 %7D)%0A
+%09
 %09%09%09%09
@@ -2619,16 +2619,17 @@
 orted()%0A
+%09
 %09%09%09%09.map
@@ -2644,16 +2644,17 @@
 oFile))%0A
+%09
 %09%09%09.dist
@@ -2663,16 +2663,17 @@
 ct()%0A%09%09%09
+%09
 .collect
@@ -2686,16 +2686,17 @@
 t());%0A%09%09
+%09
 return r
@@ -2702,13 +2702,107 @@
 result;%0A
+%09%09%7D catch (IOException ioe) %7B%0A%09%09%09throw new MojoExecutionException(ioe.getMessage(), ioe);%0A%09%09%7D%0A
 %09%7D%0A%7D%0A

Make sure file walker is promptly closed