@ApiStatus.Internal
  public static boolean updateVersionAndPathsSynchronouslyAndScheduleRemaining(@NotNull Sdk sdk, @Nullable Project project) {
    Application application = ApplicationManager.getApplication();
    try {
      // This is not optimal but already happens in many contexts including possible external usages, e.g. during a new SDK generation.
      if (application.isDispatchThread()) {
        ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
          updateLocalSdkVersionAndPaths(sdk, project);
          return null;
        }, PyBundle.message("sdk.gen.updating.interpreter"), false, project);
      }
      else {
        LOG.assertTrue(!application.isReadAccessAllowed(), "Synchronous SDK update should not be run under read action");
        updateLocalSdkVersionAndPaths(sdk, project);
      }
    }
    catch (InvalidSdkException e) {
      LOG.warn("Error while evaluating path and version: ", e);
      return false;
    }
    if (project == null) {
      return true;
    }
    // Don't inline this variable, it needs to anchor the current stack.
    PyUpdateSdkRequestData request = new PyUpdateSdkRequestData();
    // When a new interpreter is still being generated, we need to wait until it finishes and SDK
    // is properly written in ProjectJdkTable. Otherwise, a concurrent background update might fail.
    boolean isSavedSdk = PythonSdkUtil.findSdkByKey(PythonSdkType.getSdkKey(sdk)) != null;
    if (application.isWriteIntentLockAcquired() && !isSavedSdk) {
      application.invokeLaterOnWriteThread(() -> scheduleUpdate(sdk, project, request));
    }
    else {
      scheduleUpdate(sdk, project, request);
    }
    return true;
  }
@ApiStatus.Internal
  public static boolean updateVersionAndPathsSynchronouslyAndScheduleRemaining(@NotNull Sdk sdk, @Nullable Project project)