static void copyToForeignTarget(Path source,Path target,CopyOption... options) throws IOException {
  CopyOptions opts=CopyOptions.parse(options);
  LinkOption[] linkOptions=(opts.followLinks) ? new LinkOption[0] : new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
  BasicFileAttributes attrs=Files.readAttributes(source,BasicFileAttributes.class,linkOptions);
  if (attrs.isSymbolicLink())   throw new IOException("Copying of symbolic links not supported");
  if (opts.replaceExisting) {
    Files.deleteIfExists(target);
  }
 else   if (Files.exists(target))   throw new FileAlreadyExistsException(target.toString());
  if (attrs.isDirectory()) {
    Files.createDirectory(target);
  }
 else {
    try (InputStream in=Files.newInputStream(source)){
      Files.copy(in,target);
    }
   }
  if (opts.copyAttributes) {
    BasicFileAttributeView view=Files.getFileAttributeView(target,BasicFileAttributeView.class);
    try {
      view.setTimes(attrs.lastModifiedTime(),attrs.lastAccessTime(),attrs.creationTime());
    }
 catch (    Throwable x) {
      try {
        Files.delete(target);
      }
 catch (      Throwable suppressed) {
        x.addSuppressed(suppressed);
      }
      throw x;
    }
  }
}

static void copyToForeignTarget ( Path source , Path target , CopyOption ... options ) throws IOException { CopyOptions opts = CopyOptions . parse ( options ) ; LinkOption [ ] linkOptions = ( opts . followLinks ) ? new LinkOption [ 0 ] : new LinkOption [ ] { LinkOption . NOFOLLOW_LINKS } ; BasicFileAttributes attrs = Files . readAttributes ( source , BasicFileAttributes . class , linkOptions ) ; if ( attrs . isSymbolicLink ( ) ) throw new IOException ( "Copying of symbolic links not supported" ) ; if ( opts . replaceExisting ) { Files . deleteIfExists ( target ) ; } else if ( Files . exists ( target ) ) throw new FileAlreadyExistsException ( target . toString ( ) ) ; if ( attrs . isDirectory ( ) ) { Files . createDirectory ( target ) ; } else { try ( InputStream in = Files . newInputStream ( source ) ) { Files . copy ( in , target ) ; } } if ( opts . copyAttributes ) { BasicFileAttributeView view = Files . getFileAttributeView ( target , BasicFileAttributeView . class ) ; try { view . setTimes ( attrs . lastModifiedTime ( ) , attrs . lastAccessTime ( ) , attrs . creationTime ( ) ) ; } catch ( Throwable x ) { try { Files . delete ( target ) ; } catch ( Throwable suppressed ) { x . addSuppressed ( suppressed ) ; } throw x ; } } }
simple copy for use when source and target are associated with different providers
