@Override
  public void addMessage(CompilerMessage msg) {
    if (ApplicationManager.getApplication().isUnitTestMode()) {
      LOG.info("addMessage: " + msg + " this=" + this);
    }

    Collection<CompilerMessage> messages = myMessages.get(msg.getCategory());
    if (messages == null) {
      messages = new LinkedHashSet<CompilerMessage>();
      myMessages.put(msg.getCategory(), messages);
    }
    if (messages.add(msg)) {
      myTask.addMessage(msg);
    }

    if (ApplicationManager.getApplication().isCompilerServerMode()) {
      VirtualFile virtualFile = msg.getVirtualFile();
      CompilerClientConnector.getInstance(myProject)
          .addMessage(
              msg.getCategory(),
              msg.getMessage(),
              virtualFile == null ? null : virtualFile.getPath(),
              msg.getLine(),
              msg.getColumn());
    } else {
      ProblemsView.getInstance(myProject).addMessage(msg);
    }
  }
 @Override
 public CompilerMessage[] getMessages(CompilerMessageCategory category) {
   Collection<CompilerMessage> collection = myMessages.get(category);
   if (collection == null) {
     return CompilerMessage.EMPTY_ARRAY;
   }
   return collection.toArray(new CompilerMessage[collection.size()]);
 }
 @Override
 public int getMessageCount(CompilerMessageCategory category) {
   if (category != null) {
     Collection<CompilerMessage> collection = myMessages.get(category);
     return collection != null ? collection.size() : 0;
   }
   int count = 0;
   for (Collection<CompilerMessage> collection : myMessages.values()) {
     if (collection != null) {
       count += collection.size();
     }
   }
   return count;
 }
  private static void collectChildrenRecursively(
      @NotNull VirtualFile root,
      @NotNull VirtualFile anchor,
      @NotNull Collection<VirtualFile> result) {
    if (root == anchor) {
      return;
    }

    VirtualFile parent = anchor.getParent();
    if (parent == null) {
      return;
    }
    for (VirtualFile child : parent.getChildren()) {
      if (child != anchor) {
        result.add(child);
      }
    }
    if (parent != root) {
      collectChildrenRecursively(root, parent, result);
    }
  }
  private void updateOutputItemsList(
      final String outputDir,
      final VirtualFile srcFile,
      VirtualFile sourceRoot,
      final String packagePrefix,
      final List<File> filesToRefresh,
      Map<String, Collection<TranslatingCompiler.OutputItem>> results,
      final GlobalSearchScope srcRootScope)
      throws CacheCorruptedException {
    CompositeDependencyCache dependencyCache = myCompileContext.getDependencyCache();
    JavaDependencyCache child = dependencyCache.findChild(JavaDependencyCache.class);
    final Cache newCache = child.getNewClassesCache();
    final Set<CompiledClass> paths = myFileNameToSourceMap.get(srcFile.getName());
    if (paths == null || paths.isEmpty()) {
      return;
    }
    final String filePath = "/" + calcPackagePath(srcFile, sourceRoot, packagePrefix);
    for (final CompiledClass cc : paths) {
      myCompileContext.getProgressIndicator().checkCanceled();
      if (LOG.isDebugEnabled()) {
        LOG.debug("Checking [pathToClass; relPathToSource] = " + cc);
      }

      boolean pathsEquals = FileUtil.pathsEqual(filePath, cc.relativePathToSource);
      if (!pathsEquals) {
        final String qName = child.resolve(cc.qName);
        if (qName != null) {
          pathsEquals =
              ApplicationManager.getApplication()
                  .runReadAction(
                      new Computable<Boolean>() {
                        public Boolean compute() {
                          final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject);
                          PsiClass psiClass = facade.findClass(qName, srcRootScope);
                          if (psiClass == null) {
                            final int dollarIndex = qName.indexOf("$");
                            if (dollarIndex >= 0) {
                              final String topLevelClassName = qName.substring(0, dollarIndex);
                              psiClass = facade.findClass(topLevelClassName, srcRootScope);
                            }
                          }
                          if (psiClass != null) {
                            final VirtualFile vFile = psiClass.getContainingFile().getVirtualFile();
                            return vFile != null && vFile.equals(srcFile);
                          }
                          return false;
                        }
                      });
        }
      }

      if (pathsEquals) {
        final String outputPath = cc.pathToClass.replace(File.separatorChar, '/');
        final Pair<String, String> realLocation =
            moveToRealLocation(outputDir, outputPath, srcFile, filesToRefresh);
        if (realLocation != null) {
          Collection<TranslatingCompiler.OutputItem> outputs = results.get(realLocation.getFirst());
          if (outputs == null) {
            outputs = new ArrayList<TranslatingCompiler.OutputItem>();
            results.put(realLocation.getFirst(), outputs);
          }
          outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile));
          if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) {
            myProcessedPackageInfos.add(srcFile);
          }
          if (CompilerManager.MAKE_ENABLED) {
            newCache.setPath(cc.qName, realLocation.getSecond());
          }
          if (LOG.isDebugEnabled()) {
            LOG.debug(
                "Added output item: [outputDir; outputPath; sourceFile]  = ["
                    + realLocation.getFirst()
                    + "; "
                    + realLocation.getSecond()
                    + "; "
                    + srcFile.getPresentableUrl()
                    + "]");
          }
        } else {
          myCompileContext.addMessage(
              CompilerMessageCategory.ERROR,
              "Failed to copy from temporary location to output directory: "
                  + outputPath
                  + " (see idea.log for details)",
              null,
              -1,
              -1);
          if (LOG.isDebugEnabled()) {
            LOG.debug("Failed to move to real location: " + outputPath + "; from " + outputDir);
          }
        }
      }
    }
  }