public static FileEntriesLayer extraDirectoryLayerConfiguration(
      Path sourceDirectory,
      AbsoluteUnixPath targetDirectory,
      List<String> includes,
      List<String> excludes,
      Map<String, FilePermissions> extraDirectoryPermissions,
      ModificationTimeProvider modificationTimeProvider)
      throws IOException {
    FileEntriesLayer.Builder builder =
        FileEntriesLayer.builder().setName(LayerType.EXTRA_FILES.getName());
    Map<PathMatcher, FilePermissions> permissionsPathMatchers = new LinkedHashMap<>();
    for (Map.Entry<String, FilePermissions> entry : extraDirectoryPermissions.entrySet()) {
      permissionsPathMatchers.put(
          FileSystems.getDefault().getPathMatcher(GLOB_PREFIX + entry.getKey()), entry.getValue());
    }

    DirectoryWalker walker = new DirectoryWalker(sourceDirectory).filterRoot();
    // add exclusion filters
    excludes.stream()
        .map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB_PREFIX + pattern))
        .forEach(
            pathMatcher ->
                walker.filter(path -> !pathMatcher.matches(sourceDirectory.relativize(path))));
    // add an inclusion filter
    includes.stream()
        .map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB_PREFIX + pattern))
        .map(
            pathMatcher ->
                (Predicate<Path>) path -> pathMatcher.matches(sourceDirectory.relativize(path)))
        .reduce((matches1, matches2) -> matches1.or(matches2))
        .ifPresent(walker::filter);
    // walk the source tree and add layer entries
    walker.walk(
        localPath -> {
          AbsoluteUnixPath pathOnContainer =
              targetDirectory.resolve(sourceDirectory.relativize(localPath));
          Instant modificationTime = modificationTimeProvider.get(localPath, pathOnContainer);
          Optional<FilePermissions> permissions =
              determinePermissions(
                  pathOnContainer, extraDirectoryPermissions, permissionsPathMatchers);
          if (permissions.isPresent()) {
            builder.addEntry(localPath, pathOnContainer, permissions.get(), modificationTime);
          } else {
            builder.addEntry(localPath, pathOnContainer, modificationTime);
          }
        });
    return builder.build();
  }
Returns a {@link FileEntriesLayer} for adding the extra directory to the container.

@param sourceDirectory the source extra directory path
@param targetDirectory the root directory on the container to place the files in
@param includes the list of glob patterns to include from the source directory
@param excludes the list of glob patterns to exclude from the source directory
@param extraDirectoryPermissions map from path on container to file permissions
@param modificationTimeProvider file modification time provider
@return a {@link FileEntriesLayer} for adding the extra directory to the container
@throws IOException if walking the extra directory fails
jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/JavaContainerBuilderHelper.java