private static Map<ModuleBuildTarget, String> getStubGenerationOutputs(
     ModuleChunk chunk, CompileContext context) throws IOException {
   Map<ModuleBuildTarget, String> generationOutputs = new HashMap<ModuleBuildTarget, String>();
   File commonRoot = getStubRoot(context);
   for (ModuleBuildTarget target : chunk.getTargets()) {
     File targetRoot =
         new File(
             commonRoot,
             target.getModule().getName() + File.separator + target.getTargetType().getTypeId());
     if (targetRoot.exists() && !FileUtil.deleteWithRenaming(targetRoot)) {
       throw new IOException("External make cannot clean " + targetRoot.getPath());
     }
     if (!targetRoot.mkdirs()) {
       throw new IOException("External make cannot create " + targetRoot.getPath());
     }
     generationOutputs.put(target, targetRoot.getPath());
   }
   return generationOutputs;
 }
 @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;
 }