@Override
  public @NotNull VirtualFile copyFile(
    Object requestor,
    @NotNull VirtualFile file,
    @NotNull VirtualFile newParent,
    @NotNull String newName
  ) throws IOException {
    if (!isValidName(newName)) {
      throw new IOException(CoreBundle.message("file.invalid.name.error", newName));
    }
    if (!file.exists()) {
      throw new IOException(IdeCoreBundle.message("vfs.file.not.exist.error", file.getPath()));
    }
    if (!newParent.exists() || !newParent.isDirectory()) {
      throw new IOException(IdeCoreBundle.message("vfs.target.not.directory.error", newParent.getPath()));
    }
    if (newParent.findChild(newName) != null) {
      throw new IOException(IdeCoreBundle.message("vfs.target.already.exists.error", newParent.getPath() + "/" + newName));
    }

    if (!auxCopy(file, newParent, newName)) {
      var nioFile = convertToNioFileAndCheck(file, false);
      var nioTarget = convertToNioFileAndCheck(newParent, false).resolve(newName);
      NioFiles.copyRecursively(nioFile, nioTarget);
    }

    auxNotifyCompleted(handler -> handler.copy(file, newParent, newName));

    return new FakeVirtualFile(newParent, newName);
  }
@Override
  public @NotNull VirtualFile copyFile(
    Object requestor,
    @NotNull VirtualFile file,
    @NotNull VirtualFile newParent,
    @NotNull String newName
  )