private void hotSwapSessions(@NotNull List<DebuggerSession> sessions,
                               @Nullable Map<String, Collection<String>> generatedPaths,
                               @Nullable NotNullLazyValue<List<String>> outputPaths,
                               @Nullable HotSwapStatusListener callback) {
    boolean shouldAskBeforeHotswap = myAskBeforeHotswap;
    myAskBeforeHotswap = true;

    DebuggerSettings settings = DebuggerSettings.getInstance();
    String runHotswap = settings.RUN_HOTSWAP_AFTER_COMPILE;
    boolean shouldDisplayHangWarning = shouldDisplayHangWarning(settings, sessions);

    HotSwapStatusListener statusListener = makeNullSafe(callback);

    if (shouldAskBeforeHotswap && DebuggerSettings.RUN_HOTSWAP_NEVER.equals(runHotswap)) {
      statusListener.onCancel(sessions);
      return;
    }

    List<DebuggerSession> toScan = new ArrayList<>(sessions); // by default scan all sessions
    List<DebuggerSession> toUseGenerated = new ArrayList<>();

    if (generatedPaths != null) {
      toScan.clear();
      for (DebuggerSession session : sessions) {
        if (session.isModifiedClassesScanRequired()) {
          toScan.add(session);
        }
        else {
          toUseGenerated.add(session);
        }
        session.setModifiedClassesScanRequired(false);
      }
    }

    HotSwapProgressImpl findClassesProgress = !toScan.isEmpty() ? createHotSwapProgress(statusListener, sessions) : null;
    HotSwapProgressImpl outputPathsProgress =
      !toUseGenerated.isEmpty() && outputPaths != null ? createHotSwapProgress(statusListener, sessions) : null;

    ApplicationManager.getApplication().executeOnPooledThread(() -> {
      Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses = new HashMap<>();
      if (!toUseGenerated.isEmpty()) {
        modifiedClasses.putAll(HotSwapManager.findModifiedClasses(toUseGenerated, generatedPaths));
        if (outputPathsProgress != null) {
          scanForModifiedClassesWithProgress(toUseGenerated, outputPaths, outputPathsProgress)
            .forEach(
              (session, map) -> modifiedClasses.merge(session, map, (map1, map2) -> {
                map1.putAll(map2);
                return map1;
              })
            );
        }
      }
      if (findClassesProgress != null) {
        modifiedClasses.putAll(scanForModifiedClassesWithProgress(toScan, null, findClassesProgress));
      }

      if (modifiedClasses.isEmpty()) {
        String message = JavaDebuggerBundle.message("status.hotswap.uptodate");
        HotSwapProgressImpl.NOTIFICATION_GROUP.createNotification(message, NotificationType.INFORMATION).notify(myProject);
        statusListener.onSuccess(sessions);
        return;
      }

      ApplicationManager.getApplication().invokeLater(() -> {
        if (shouldAskBeforeHotswap && !DebuggerSettings.RUN_HOTSWAP_ALWAYS.equals(runHotswap)) {
          RunHotswapDialog dialog = new RunHotswapDialog(myProject, sessions, shouldDisplayHangWarning);
          if (!dialog.showAndGet()) {
            for (DebuggerSession session : modifiedClasses.keySet()) {
              session.setModifiedClassesScanRequired(true);
            }
            statusListener.onCancel(sessions);
            return;
          }
          Set<DebuggerSession> toReload = new HashSet<>(dialog.getSessionsToReload());
          for (DebuggerSession session : modifiedClasses.keySet()) {
            if (!toReload.contains(session)) {
              session.setModifiedClassesScanRequired(true);
            }
          }
          modifiedClasses.keySet().retainAll(toReload);
        }
        else if (shouldDisplayHangWarning && !confirmPossibleHang(settings)) {
          for (DebuggerSession session : modifiedClasses.keySet()) {
            session.setModifiedClassesScanRequired(true);
          }
          statusListener.onCancel(sessions);
          return;
        }

        if (modifiedClasses.isEmpty()) {
          return; // Without calling onCancel.
        }

        HotSwapProgressImpl progress = new HotSwapProgressImpl(myProject);
        if (modifiedClasses.keySet().size() == 1) {
          progress.setSessionForActions(ContainerUtil.getFirstItem(modifiedClasses.keySet()));
        }
        progress.addProgressListener(delegatingTo(statusListener, sessions, progress));

        ApplicationManager.getApplication().executeOnPooledThread(
          () -> reloadModifiedClasses(modifiedClasses, progress)
        );
      }, ModalityState.nonModal());
    });
  }
private void hotSwapSessions(@NotNull List<DebuggerSession> sessions,
                               @Nullable Map<String, Collection<String>> generatedPaths,
                               @Nullable NotNullLazyValue<List<String>> outputPaths,
                               @Nullable HotSwapStatusListener callback)