private void detectModuleStatementsUsed(@NotNull MultiMap<PsiJavaModule, PsiDirectory> sourceDirsByModuleDescriptor,
                                          @NotNull List<? super UsageInfo> usageInfos,
                                          @NotNull MultiMap<PsiElement, String> conflicts,
                                          @NotNull MultiMap<PsiJavaModule, PsiDirectory> absentDirsByModuleDescriptor) {
    PackageIndex packageIndex = PackageIndex.getInstance(myProject);
    JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
    PsiPackage targetPackage = psiFacade.findPackage(myMoveDestination.getTargetPackage().getQualifiedName());
    for (var entry : sourceDirsByModuleDescriptor.entrySet()) {
      PsiJavaModule sourceModuleDescriptor = entry.getKey();
      Collection<PsiDirectory> sourceDirs = entry.getValue();
      MultiMap<PsiPackage, PsiPackageAccessibilityStatement> sourceExports = collectModuleStatements(sourceModuleDescriptor.getExports());
      MultiMap<PsiPackage, PsiPackageAccessibilityStatement> sourceOpens = collectModuleStatements(sourceModuleDescriptor.getOpens());
      Map<PsiJavaModule, DirectoryWithModuleStatements> targetModuleStatementsByModuleDescriptor = new HashMap<>();
      for (PsiDirectory sourceDir : sourceDirs) {
        PsiDirectory targetDirectory = myMoveDestination.getTargetIfExists(sourceDir);
        if (targetDirectory == null) {
          absentDirsByModuleDescriptor.putValue(sourceModuleDescriptor, sourceDir);
          continue;
        }
        String sourcePkgName = packageIndex.getPackageNameByDirectory(sourceDir.getVirtualFile());
        if (sourcePkgName == null) continue;
        PsiPackage sourcePkg = psiFacade.findPackage(sourcePkgName);
        if (sourcePkg == null) continue;
        List<PsiPackageAccessibilityStatement> sourceStatements = findModuleStatementsForPkg(sourcePkg, sourceExports, sourceOpens);
        if (sourceStatements.isEmpty()) continue;
        // if a package doesn't contain any other classes except moved ones then we need to delete a corresponding export statement
        Collection<PsiClass> sourceClasses = mySourceClassesByDir.get(sourceDir);
        if (dirContainsOnlyClasses(sourceDir, sourceClasses)) {
          sourceStatements.forEach(statement -> usageInfos.add(ModifyModuleStatementUsageInfo.createLastDeletionInfo(statement, sourceModuleDescriptor)));
        }
        PsiJavaModule targetModuleDescriptor = JavaModuleGraphUtil.findDescriptorByElement(targetDirectory);
        // so far we don't take into account a motion between separate JPMS-modules
        if (sourceModuleDescriptor == targetModuleDescriptor) {
          DirectoryWithModuleStatements dirWithStatements = targetModuleStatementsByModuleDescriptor
            .computeIfAbsent(sourceModuleDescriptor, __ -> new DirectoryWithModuleStatements(targetDirectory, new SmartList<>()));
          dirWithStatements.myModuleStatements.addAll(sourceStatements);
        }
        else if (targetModuleDescriptor != null) {
          sourceClasses.forEach(c -> conflicts.put(c, List.of(
            JavaRefactoringBundle.message("move.classes.or.packages.different.modules.exports.conflict",
                                          RefactoringUIUtil.getDescription(c, false),
                                          StringUtil.htmlEmphasize(sourceModuleDescriptor.getName()),
                                          StringUtil.htmlEmphasize(targetModuleDescriptor.getName())))));
        }
      }
      for (var statementEntry : targetModuleStatementsByModuleDescriptor.entrySet()) {
        PsiJavaModule targetModuleDescriptor = statementEntry.getKey();
        List<PsiPackageAccessibilityStatement> sourceModuleStatements = statementEntry.getValue().myModuleStatements;
        assert targetPackage != null;
        List<PsiPackageAccessibilityStatement> targetPkgModuleStatements = findModuleStatementsForPkg(targetModuleDescriptor, targetPackage);
        List<PsiPackageAccessibilityStatement> statementsToCreate = new SmartList<>();
        List<PsiPackageAccessibilityStatement> statementsToDelete = new SmartList<>();
        mergeModuleStatements(sourceModuleStatements, targetPkgModuleStatements, targetPackage, statementsToCreate, statementsToDelete);
        if (statementsToCreate.isEmpty()) continue;
        if (!dirContainsOnlyClasses(statementEntry.getValue().myDir, Collections.emptyList())) {
          conflicts.put(targetModuleDescriptor.getNameIdentifier(), List.of(
            JavaRefactoringBundle.message("move.classes.or.packages.new.module.exports.conflict",
                                          StringUtil.htmlEmphasize(targetPackage.getQualifiedName()))));
        }
        statementsToDelete.stream().map(pkgStatement -> ModifyModuleStatementUsageInfo.createDeletionInfo(pkgStatement, targetModuleDescriptor))
          .forEach(usageInfos::add);
        statementsToCreate.stream().map(pkgStatement -> ModifyModuleStatementUsageInfo.createAdditionInfo(pkgStatement, targetModuleDescriptor))
          .forEach(usageInfos::add);
      }
    }
  }
private void detectModuleStatementsUsed(@NotNull MultiMap<PsiJavaModule, PsiDirectory> sourceDirsByModuleDescriptor,
                                          @NotNull List<? super UsageInfo> usageInfos,
                                          @NotNull MultiMap<PsiElement, String> conflicts,
                                          @NotNull MultiMap<PsiJavaModule, PsiDirectory> absentDirsByModuleDescriptor)