private static boolean compileBunchOfSources(
      K2JVMCompileEnvironmentConfiguration configuration,
      String jar,
      String outputDir,
      boolean includeRuntime) {
    FqName mainClass = null;
    for (JetFile file : configuration.getEnvironment().getSourceFiles()) {
      if (JetMainDetector.hasMain(file.getDeclarations())) {
        FqName fqName = JetPsiUtil.getFQName(file);
        mainClass = fqName.child(JvmAbi.PACKAGE_CLASS);
        break;
      }
    }

    GenerationState generationState = analyzeAndGenerate(configuration);
    if (generationState == null) {
      return false;
    }

    try {
      ClassFileFactory factory = generationState.getFactory();
      if (jar != null) {
        try {
          CompileEnvironmentUtil.writeToJar(
              factory, new FileOutputStream(jar), mainClass, includeRuntime);
        } catch (FileNotFoundException e) {
          throw new CompileEnvironmentException("Invalid jar path " + jar, e);
        }
      } else if (outputDir != null) {
        CompileEnvironmentUtil.writeToOutputDirectory(factory, outputDir);
      } else {
        throw new CompileEnvironmentException(
            "Output directory or jar file is not specified - no files will be saved to the disk");
      }
      return true;
    } finally {
      generationState.destroy();
    }
  }
  public static boolean compileModules(
      K2JVMCompileEnvironmentConfiguration configuration,
      @NotNull List<Module> modules,
      @NotNull File directory,
      @Nullable String jarPath,
      @Nullable String outputDir,
      boolean jarRuntime) {

    for (Module moduleBuilder : modules) {
      // TODO: this should be done only once for the environment
      if (configuration.getEnvironment().getCompilerDependencies().getRuntimeJar() != null) {
        CompileEnvironmentUtil.addToClasspath(
            configuration.getEnvironment(),
            configuration.getEnvironment().getCompilerDependencies().getRuntimeJar());
      }
      ClassFileFactory moduleFactory = compileModule(configuration, moduleBuilder, directory);
      if (moduleFactory == null) {
        return false;
      }
      if (outputDir != null) {
        CompileEnvironmentUtil.writeToOutputDirectory(moduleFactory, outputDir);
      } else {
        String path =
            jarPath != null
                ? jarPath
                : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
        try {
          CompileEnvironmentUtil.writeToJar(
              moduleFactory, new FileOutputStream(path), null, jarRuntime);
        } catch (FileNotFoundException e) {
          throw new CompileEnvironmentException("Invalid jar path " + path, e);
        }
      }
    }
    return true;
  }