private @NotNull GroovyCompilerResult runGroovycOrContinuation(
    CompileContext context,
    ModuleChunk chunk,
    Map<T, String> finalOutputs,
    String compilerOutput, List<File> toCompile, boolean hasStubExcludes
  ) throws Exception {
    if (myForStubs) {
      clearContinuation(context, chunk);
    }

    GroovycContinuation continuation = takeContinuation(context, chunk);
    if (continuation != null) {
      if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) {
        LOG.debug("using continuation for " + chunk);
      }
      return continuation.continueCompilation();
    }

    final Set<String> toCompilePaths = getPathsToCompile(toCompile);

    JpsSdk<JpsDummyElement> jdk = GroovyBuilder.getJdk(chunk);
    int version = jdk != null ? JpsJavaSdkType.getJavaVersion(jdk) : JavaVersion.current().feature;
    boolean inProcess = shouldRunGroovycInProcess(version);
    boolean mayDependOnUtilJar = version >= 6;
    // Optimized classloader is in fact a UrlClassLoader that refers to jar archives in the SDK distribution
    // Starting from Java 9, JDK is no longer distributed as a set of jar archives, which invalidates assumptions for classloading optimization.
    boolean isJdkSuitableForOptimization = version < 9;
    boolean optimizeClassLoading =
      !inProcess &&
      mayDependOnUtilJar &&
      isJdkSuitableForOptimization &&
      ourOptimizeThreshold != 0 &&
      toCompilePaths.size() >= ourOptimizeThreshold;

    Map<String, String> class2Src = buildClassToSourceMap(chunk, context, toCompilePaths, finalOutputs);

    final String encoding = context.getProjectDescriptor().getEncodingConfiguration().getPreferredModuleChunkEncoding(chunk);
    List<String> patchers = new ArrayList<>();

    for (GroovyBuilderExtension extension : JpsServiceManager.getInstance().getExtensions(GroovyBuilderExtension.class)) {
      patchers.addAll(extension.getCompilationUnitPatchers(context, chunk));
    }

    Collection<String> classpath = generateClasspath(context, chunk);
    if (LOG.isDebugEnabled()) {
      LOG.debug("Optimized class loading: " + optimizeClassLoading + ", inProcess = " + inProcess);
      LOG.debug("Groovyc classpath: " + classpath);
    }

    final File tempFile = GroovycOutputParser.fillFileWithGroovycParameters(
      compilerOutput, toCompilePaths, finalOutputs.values(), class2Src, encoding, patchers,
      optimizeClassLoading ? StringUtil.join(classpath, File.pathSeparator) : ""
    );
    GroovycFlavor groovyc =
      inProcess ? new InProcessGroovyc(finalOutputs.values(), hasStubExcludes) : new ForkedGroovyc(optimizeClassLoading, chunk);

    GroovycOutputParser parser = new GroovycOutputParser(chunk, context);

    continuation = groovyc.runGroovyc(classpath, myForStubs, context, tempFile, parser, getBytecodeTarget(context, chunk));
    setContinuation(context, chunk, continuation);
    return parser.result();
  }
private @NotNull GroovyCompilerResult runGroovycOrContinuation(
    CompileContext context,
    ModuleChunk chunk,
    Map<T, String> finalOutputs,
    String compilerOutput, List<File> toCompile, boolean hasStubExcludes
  )