private ExitCode generateRmiStubs(final CompileContext context,
                                    Map<ModuleBuildTarget, Collection<ClassItem>> remoteClasses,
                                    ModuleChunk chunk,
                                    OutputConsumer outputConsumer) {
    ExitCode exitCode = ExitCode.NOTHING_DONE;

    final Collection<File> classpath = ProjectPaths.getCompilationClasspath(chunk, false);
    final StringBuilder buf = new StringBuilder();
    for (File file : classpath) {
      if (buf.length() > 0) {
        buf.append(File.pathSeparator);
      }
      buf.append(file.getPath());
    }
    final String classpathString = buf.toString();
    final String rmicPath = getPathToRmic(chunk);
    final RmicCompilerOptions options = getOptions(context);
    final List<ModuleBuildTarget> targetsProcessed = new ArrayList<>(remoteClasses.size());

    for (Map.Entry<ModuleBuildTarget, Collection<ClassItem>> entry : remoteClasses.entrySet()) {
      try {
        final ModuleBuildTarget target = entry.getKey();
        final Collection<String> cmdLine = createStartupCommand(
          target, rmicPath, classpathString, options, entry.getValue()
        );
        final Process process = Runtime.getRuntime().exec(ArrayUtilRt.toStringArray(cmdLine));
        final BaseOSProcessHandler handler = new BaseOSProcessHandler(process, StringUtil.join(cmdLine, " "), null) {
          @Override
          public @NotNull Future<?> executeTask(@NotNull Runnable task) {
            return SharedThreadPool.getInstance().submit(task);
          }
        };

        final RmicOutputParser stdOutParser = new RmicOutputParser(context, getPresentableName());
        final RmicOutputParser stdErrParser = new RmicOutputParser(context, getPresentableName());
        handler.addProcessListener(new ProcessAdapter() {
          @Override
          public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) {
            if (outputType == ProcessOutputTypes.STDOUT) {
              stdOutParser.append(event.getText());
            }
            else if (outputType == ProcessOutputTypes.STDERR) {
              stdErrParser.append(event.getText());
            }
          }
        });
        handler.startNotify();
        handler.waitFor();
        targetsProcessed.add(target);
        if (stdErrParser.isErrorsReported() || stdOutParser.isErrorsReported()) {
          break;
        }
        else {
          final int exitValue = handler.getProcess().exitValue();
          if (exitValue != 0) {
            context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR,
                                                       JpsBuildBundle.message("build.message.rmi.stub.generation.failed")));
            break;
          }
        }
      }
      catch (IOException e) {
        context.processMessage(new CompilerMessage(getPresentableName(), e));
        break;
      }
    }

    // registering generated files
    final Map<File, File[]> fsCache = FileCollectionFactory.createCanonicalFileMap();
    for (ModuleBuildTarget target : targetsProcessed) {
      final Collection<ClassItem> items = remoteClasses.get(target);
      for (ClassItem item : items) {
        File[] children = fsCache.get(item.parentDir);
        if (children == null) {
          children = item.parentDir.listFiles();
          if (children == null) {
            children = EMPTY_FILE_ARRAY;
          }
          fsCache.put(item.parentDir, children);
        }
        final Collection<File> files = item.selectGeneratedFiles(children);
        if (!files.isEmpty()) {
          final Collection<String> sources = item.compiledClass.getSourceFilesPaths();
          for (File generated : files) {
            try {
              outputConsumer.registerOutputFile(target, generated, sources);
            }
            catch (IOException e) {
              context.processMessage(new CompilerMessage(getPresentableName(), e));
            }
          }
        }
      }
    }

    return exitCode;
  }
private ExitCode generateRmiStubs(final CompileContext context,
                                    Map<ModuleBuildTarget, Collection<ClassItem>> remoteClasses,
                                    ModuleChunk chunk,
                                    OutputConsumer outputConsumer)