public static void updateDependencies(
      CompileContext context,
      List<File> toCompile,
      Map<ModuleBuildTarget, Collection<GroovycOutputParser.OutputItem>> successfullyCompiled,
      OutputConsumer outputConsumer,
      Builder builder)
      throws IOException {
    JavaBuilderUtil.registerFilesToCompile(context, toCompile);
    if (!successfullyCompiled.isEmpty()) {

      final Callbacks.Backend callback = JavaBuilderUtil.getDependenciesRegistrar(context);

      for (Map.Entry<ModuleBuildTarget, Collection<GroovycOutputParser.OutputItem>> entry :
          successfullyCompiled.entrySet()) {
        final ModuleBuildTarget target = entry.getKey();
        final Collection<GroovycOutputParser.OutputItem> compiled = entry.getValue();
        for (GroovycOutputParser.OutputItem item : compiled) {
          final String sourcePath = FileUtil.toSystemIndependentName(item.sourcePath);
          final String outputPath = FileUtil.toSystemIndependentName(item.outputPath);
          final File outputFile = new File(outputPath);
          final File srcFile = new File(sourcePath);
          try {
            final byte[] bytes = FileUtil.loadFileBytes(outputFile);
            if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) {
              LOG.info("registerCompiledClass " + outputFile + " from " + srcFile);
            }
            outputConsumer.registerCompiledClass(
                target,
                new CompiledClass(
                    outputFile, srcFile, readClassName(bytes), new BinaryContent(bytes)));
            callback.associate(outputPath, sourcePath, new FailSafeClassReader(bytes));
          } catch (Throwable e) {
            // need this to make sure that unexpected errors in, for example, ASM will not ruin the
            // compilation
            final String message =
                "Class dependency information may be incomplete! Error parsing generated class "
                    + item.outputPath;
            LOG.info(message, e);
            context.processMessage(
                new CompilerMessage(
                    builder.getPresentableName(),
                    BuildMessage.Kind.WARNING,
                    message + "\n" + CompilerMessage.getTextFromThrowable(e),
                    sourcePath));
          }
          JavaBuilderUtil.registerSuccessfullyCompiled(context, srcFile);
        }
      }
    }
  }
 @Nullable
 public static Map<ModuleBuildTarget, String> getCanonicalModuleOutputs(
     CompileContext context, ModuleChunk chunk, Builder builder) {
   Map<ModuleBuildTarget, String> finalOutputs = new LinkedHashMap<ModuleBuildTarget, String>();
   for (ModuleBuildTarget target : chunk.getTargets()) {
     File moduleOutputDir = target.getOutputDir();
     if (moduleOutputDir == null) {
       context.processMessage(
           new CompilerMessage(
               builder.getPresentableName(),
               BuildMessage.Kind.ERROR,
               "Output directory not specified for module " + target.getModule().getName()));
       return null;
     }
     //noinspection ResultOfMethodCallIgnored
     moduleOutputDir.mkdirs();
     String moduleOutputPath = FileUtil.toCanonicalPath(moduleOutputDir.getPath());
     assert moduleOutputPath != null;
     finalOutputs.put(
         target, moduleOutputPath.endsWith("/") ? moduleOutputPath : moduleOutputPath + "/");
   }
   return finalOutputs;
 }