public static void copy(
      List<ResourceId> srcResourceIds, List<ResourceId> destResourceIds, MoveOptions... moveOptions)
      throws IOException {
    validateSrcDestLists(srcResourceIds, destResourceIds);
    if (srcResourceIds.isEmpty()) {
      return;
    }
    FileSystem fileSystem = getFileSystemInternal(srcResourceIds.iterator().next().getScheme());
    FilterResult filtered = filterFiles(fileSystem, srcResourceIds, destResourceIds, moveOptions);
    if (!filtered.resultSources.isEmpty()) {
      fileSystem.copy(filtered.resultSources, filtered.resultDestinations);
    }
  }
@Test
  public void testCopySkipIfItExists() throws Exception {
    Path srcPath1 = temporaryFolder.newFile().toPath();
    Path srcPath2 = temporaryFolder.newFile().toPath();

    Path destPath1 = srcPath1.resolveSibling("dest1");
    Path destPath2 = srcPath2.resolveSibling("dest2");

    createFileWithContent(srcPath1, "content1");
    createFileWithContent(srcPath2, "content3");
    createFileWithContent(destPath2, "content");

    FileSystems.copy(
        toResourceIds(ImmutableList.of(srcPath1, srcPath2), false /* isDirectory */),
        toResourceIds(ImmutableList.of(destPath1, destPath2), false /* isDirectory */),
        MoveOptions.StandardMoveOptions.SKIP_IF_DESTINATION_EXISTS);

    assertTrue(srcPath1.toFile().exists());
    assertTrue(srcPath2.toFile().exists());
    assertThat(
        Files.readLines(destPath1.toFile(), StandardCharsets.UTF_8),
        containsInAnyOrder("content1"));
    // The file is overwritten because the content does not match.
    assertThat(
        Files.readLines(destPath2.toFile(), StandardCharsets.UTF_8),
        containsInAnyOrder("content3"));
  }