code:     public static void copyRecursively(final Path source, final Path target, boolean overwrite) throws IOException {
          final CopyOption[] options;
          if (overwrite) {
              options = new CopyOption[]{StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING};
          } else {
              options = new CopyOption[]{StandardCopyOption.COPY_ATTRIBUTES};
          }
          Files.walkFileTree(source, new FileVisitor<Path>() {
              @Override
              public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                  Files.copy(dir, target.resolve(source.relativize(dir)), options);
                  return FileVisitResult.CONTINUE;
              }
  
              @Override
              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                  Files.copy(file, target.resolve(source.relativize(file)), options);
                  return FileVisitResult.CONTINUE;
              }
  
              @Override
              public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                  DeploymentRepositoryLogger.ROOT_LOGGER.cannotCopyFile(exc, file);
                  return FileVisitResult.CONTINUE;
              }
  
              @Override
              public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                  return FileVisitResult.CONTINUE;
              }
          });
      }
  
      /**
       * Delete a path recursively, not throwing Exception if it fails or if the path is null.
       * @param path a Path pointing to a file or a directory that may not exists anymore.
       */
  