@Override
  public ExitCode build(final CompileContext context,
                        ModuleChunk chunk,
                        DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
                        OutputConsumer outputConsumer) throws ProjectBuildException {
    if (!useGreclipse(context)) return ModuleLevelBuilder.ExitCode.NOTHING_DONE;

    try {
      List<File> toCompile = myHelper.collectChangedFiles(context, dirtyFilesHolder, false, Ref.create(false));
      if (toCompile.isEmpty()) {
        return ExitCode.NOTHING_DONE;
      }

      Map<ModuleBuildTarget, String> outputDirs = GroovyBuilder.getCanonicalModuleOutputs(context, chunk, this);
      if (outputDirs == null) {
        return ExitCode.ABORT;
      }

      JpsProject project = context.getProjectDescriptor().getProject();
      GreclipseSettings greclipseSettings = GreclipseJpsCompilerSettings.getSettings(project);
      if (greclipseSettings == null) {
        String message = GroovyJpsBundle.message("greclipse.not.initialized.for.project.0", project);
        LOG.error(message);
        context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message));
        return ExitCode.ABORT;
      }

      ClassLoader loader = createGreclipseLoader(greclipseSettings.greclipsePath);
      if (loader == null) {
        context.processMessage(new CompilerMessage(
          getPresentableName(), BuildMessage.Kind.ERROR,
          GroovyJpsBundle.message("greclipse.invalid.jar.path.0", greclipseSettings.greclipsePath)
        ));
        return ExitCode.ABORT;
      }

      final Set<JpsModule> modules = chunk.getModules();
      ProcessorConfigProfile profile = null;
      if (modules.size() == 1) {
        final JpsJavaCompilerConfiguration compilerConfig = JpsJavaExtensionService.getInstance().getCompilerConfiguration(project);
        assert compilerConfig != null;
        profile = compilerConfig.getAnnotationProcessingProfile(modules.iterator().next());
      }
      else {
        final String message = JavaBuilder.validateCycle(context, chunk);
        if (message != null) {
          context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message));
          return ExitCode.ABORT;
        }
      }

      String mainOutputDir = outputDirs.get(chunk.representativeTarget());
      final List<String> args = createCommandLine(context, chunk, toCompile, mainOutputDir, profile, greclipseSettings);
      final List<String> vmOptions = discoverVmOptions(chunk, greclipseSettings.cmdLineParams, greclipseSettings.vmOptions);
      if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) {
        LOG.debug("Compiling with args: " + args);
      }

      Boolean notified = COMPILER_VERSION_INFO.get(context);
      if (notified != Boolean.TRUE) {
        context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, GroovyJpsBundle.message("greclipse.info")));
        COMPILER_VERSION_INFO.set(context, Boolean.TRUE);
      }

      context.processMessage(new ProgressMessage(GroovyJpsBundle.message("greclipse.compiling.chunk.0", chunk.getPresentableShortName())));

      StringWriter out = new StringWriter();
      StringWriter err = new StringWriter();
      HashMap<String, List<String>> outputMap = new HashMap<>();

      boolean success = performCompilation(vmOptions, args, out, err, outputMap, context, chunk);

      List<OutputItem> items = new ArrayList<>();
      for (String src : outputMap.keySet()) {
        for (String classFile : outputMap.get(src)) {
          items.add(new OutputItem(FileUtil.toSystemIndependentName(mainOutputDir + classFile),
                                   FileUtil.toSystemIndependentName(src)));
        }
      }
      MultiMap<ModuleBuildTarget, OutputItem> successfullyCompiled =
        myHelper.processCompiledFiles(context, chunk, outputDirs, mainOutputDir, items);

      EclipseOutputParser parser = new EclipseOutputParser(getPresentableName(), chunk);
      List<CompilerMessage> messages = ContainerUtil.concat(parser.parseMessages(out.toString()), parser.parseMessages(err.toString()));
      boolean hasError = false;
      for (CompilerMessage message : messages) {
        if (message.getKind() == BuildMessage.Kind.ERROR) {
          hasError = true;
        }
        context.processMessage(message);
      }

      if (!success && !hasError) {
        context.processMessage(new CompilerMessage(
          getPresentableName(), BuildMessage.Kind.ERROR,
          GroovyJpsBundle.message("greclipse.compilation.failed")
        ));
      }

      myHelper.updateDependencies(context, toCompile, successfullyCompiled, new DefaultOutputConsumer(outputConsumer), this);
      return ExitCode.OK;

    }
    catch (Exception e) {
      throw new ProjectBuildException(e);
    }
  }
@Override
  public ExitCode build(final CompileContext context,
                        ModuleChunk chunk,
                        DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
                        OutputConsumer outputConsumer)