class BundleImpl implements Bundle {

    @Override
    public Enumeration<URL> findEntries(final String path, final String filePattern, final boolean recurse) {
        final Filter filter = filePattern == null ?
                null : context.createFilter("(filename=" + filePattern + ")");
        final String prefix = path == null ? "" : (path.startsWith("/") ? path.substring(1) : path);

        if (includedResources != null) {
            if (!recurse) {
                return enumeration(includedResources.stream()
                        .filter(it -> doFilterEntry(filter, prefix, it))
                        .map(loader::getResource)
                        .collect(toList()));
            }
        }

        final File baseFile = new File(file, prefix);
        final Path base = baseFile.toPath();
        final Path filePath = this.file.toPath();
        if (file.isDirectory()) {
            if (!recurse) {
                return enumeration(ofNullable(baseFile.listFiles())
                        .map(Stream::of)
                        .orElseGet(Stream::empty)
                        .filter(file -> doFilterEntry(filter, prefix, filePath.relativize(file.toPath()).toString()))
                        .map(f -> {
                            try {
                                return f.getAbsoluteFile().toURI().toURL();
                            } catch (final MalformedURLException e) {
                                throw new IllegalStateException(e);
                            }
                        })
                        .collect(toList()));
            } else {
                final Collection<URL> files = new ArrayList<>();
                try {
                    Files.walkFileTree(base, new SimpleFileVisitor<Path>() {
                        @Override
                        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
                            if (doFilterEntry(filter, prefix, filePath.relativize(file).toString())) {
                                files.add(file.toAbsolutePath().toUri().toURL());
                            }
                            return super.visitFile(file, attrs);
                        }
                    });
                } catch (final IOException e) {
                    throw new IllegalStateException(e);
                }
                return enumeration(files);
            }
        } else {
            try (final JarFile jar = new JarFile(file)) {
                return enumeration(list(jar.entries()).stream().filter(it -> it.getName().startsWith(prefix))
                        .map(ZipEntry::getName).filter(name -> !name.endsWith("/")) // folders
                        .filter(name -> doFilterEntry(filter, prefix, name)).map(name -> {
                            try {
                                return new URL("jar", null, file.toURI().toURL().toExternalForm() + "!/" + name);
                            } catch (final MalformedURLException e) {
                                throw new IllegalArgumentException(e);
                            }
                        }).collect(toList()));
            } catch (final IOException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }

      BundleImpl(final Manifest manifest, final File file, final BundleContextImpl context,
               final Ripener.Configuration configuration, final long id,
               final Collection<String> includedResources, final BundleRegistry registry);

}