private static void copyToDirectoryUnderProgress(PsiFileSystemItem elementToCopy,
                                                   @Nullable String newName,
                                                   @NotNull PsiDirectory targetDirectory,
                                                   @NotNull List<? super PsiFile> added,
                                                   List<? super PsiFile> originals,
                                                   MultiMap<PsiDirectory, PsiFile> existingFiles,
                                                   Ref<Integer> currentFileCount,
                                                   int totalFileCount,
                                                   @Nullable ProgressIndicator pi) throws IncorrectOperationException, IOException {

    if (pi != null) {
      pi.setFraction((double) currentFileCount.get() / totalFileCount);
      pi.setText2(InspectionsBundle.message("processing.progress.text", elementToCopy.getName()));
    }
    currentFileCount.set(currentFileCount.get() + 1);
    
    if (elementToCopy instanceof PsiFile file) {
      String name = newName == null ? file.getName() : newName;
      final PsiFile existing = targetDirectory.findFile(name);
      if (existing != null && !existing.equals(file)) {
        existingFiles.putValue(targetDirectory, file);
        return;
      }
      originals.add(file);
      ((PsiDirectoryImpl)targetDirectory).executeWithUpdatingAddedFilesDisabled(() -> ContainerUtil.addIfNotNull(added, targetDirectory.copyFileFrom(name, file)));
    }
    else if (elementToCopy instanceof PsiDirectory directory) {
      if (directory.equals(targetDirectory)) {
        return;
      }
      if (newName == null) newName = directory.getName();
      final PsiDirectory existing = targetDirectory.findSubdirectory(newName);
      final PsiDirectory subdirectory;
      if (existing == null) {
        subdirectory = targetDirectory.createSubdirectory(newName);
      }
      else {
        subdirectory = existing;
      }
      EncodingRegistry.doActionAndRestoreEncoding(directory.getVirtualFile(),
                                                  (ThrowableComputable<VirtualFile, IOException>)() -> subdirectory.getVirtualFile());

      VirtualFile[] children = directory.getVirtualFile().getChildren();
      Project project = subdirectory.getProject();
      PsiManager manager = PsiManager.getInstance(project);
      for (VirtualFile file : children) {
        PsiFileSystemItem item = file.isDirectory() ? manager.findDirectory(file) : manager.findFile(file);
        if (item == null) {
          LOG.info("invalid file: " + file.getExtension());
          continue;
        }
        copyToDirectoryUnderProgress(item, null, subdirectory, added, originals, existingFiles, currentFileCount, totalFileCount, pi);
      }
    }
    else {
      throw new IllegalArgumentException("unexpected elementToCopy: " + elementToCopy);
    }
  }
private static void copyToDirectoryUnderProgress(PsiFileSystemItem elementToCopy,
                                                   @Nullable String newName,
                                                   @NotNull PsiDirectory targetDirectory,
                                                   @NotNull List<? super PsiFile> added,
                                                   List<? super PsiFile> originals,
                                                   MultiMap<PsiDirectory, PsiFile> existingFiles,
                                                   Ref<Integer> currentFileCount,
                                                   int totalFileCount,
                                                   @Nullable ProgressIndicator pi)