private static boolean hasNotNullAnnotations(
     final Cache cache, final SymbolTable symbolTable, final int className, Project project)
     throws CacheCorruptedException {
   final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
   final List<String> notNulls = manager.getNotNulls();
   for (MethodInfo methodId : cache.getMethods(className)) {
     for (AnnotationConstantValue annotation : methodId.getRuntimeInvisibleAnnotations()) {
       if (notNulls.contains(symbolTable.getSymbol(annotation.getAnnotationQName()))) {
         return true;
       }
     }
     final AnnotationConstantValue[][] paramAnnotations =
         methodId.getRuntimeInvisibleParameterAnnotations();
     for (AnnotationConstantValue[] _singleParamAnnotations : paramAnnotations) {
       for (AnnotationConstantValue annotation : _singleParamAnnotations) {
         if (notNulls.contains(symbolTable.getSymbol(annotation.getAnnotationQName()))) {
           return true;
         }
       }
     }
   }
   return false;
 }
  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);
          }
        }
      }
    }
  }
    private void processPath(FileObject fileObject, Project project)
        throws CacheCorruptedException {
      File file = fileObject.getFile();
      final String path = file.getPath();
      try {
        if (CompilerManager.MAKE_ENABLED) {
          byte[] fileContent = fileObject.getContent();
          // the file is assumed to exist!
          final JavaDependencyCache dependencyCache =
              myCompileContext.getDependencyCache().findChild(JavaDependencyCache.class);
          final int newClassQName = dependencyCache.reparseClassFile(file, fileContent);
          final Cache newClassesCache = dependencyCache.getNewClassesCache();
          final String sourceFileName = newClassesCache.getSourceFileName(newClassQName);
          final String qName = dependencyCache.resolve(newClassQName);
          String relativePathToSource =
              "/" + JavaMakeUtil.createRelativePathToSource(qName, sourceFileName);
          putName(sourceFileName, newClassQName, relativePathToSource, path);
          boolean haveToInstrument =
              myAddNotNullAssertions
                  && hasNotNullAnnotations(
                      newClassesCache, dependencyCache.getSymbolTable(), newClassQName, project);

          if (haveToInstrument) {
            try {
              ClassReader reader = new ClassReader(fileContent, 0, fileContent.length);
              ClassWriter writer = new PsiClassWriter(myProject, myIsJdk16);

              if (NotNullVerifyingInstrumenter.processClassFile(reader, writer)) {
                fileObject = new FileObject(file, writer.toByteArray());
              }
            } catch (Exception ignored) {
              LOG.info(ignored);
            }
          }

          fileObject.save();
        } else {
          final String _path = FileUtil.toSystemIndependentName(path);
          final int dollarIndex = _path.indexOf('$');
          final int tailIndex = dollarIndex >= 0 ? dollarIndex : _path.length() - ".class".length();
          final int slashIndex = _path.lastIndexOf('/');
          final String sourceFileName = _path.substring(slashIndex + 1, tailIndex) + ".java";
          String relativePathToSource = _path.substring(myOutputDir.length(), tailIndex) + ".java";
          putName(
              sourceFileName,
              0 /*doesn't matter here*/,
              relativePathToSource.startsWith("/")
                  ? relativePathToSource
                  : "/" + relativePathToSource,
              path);
        }
      } catch (ClsFormatException e) {
        final String m = e.getMessage();
        String message =
            CompilerBundle.message(
                "error.bad.class.file.format", StringUtil.isEmpty(m) ? path : m + "\n" + path);
        myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
        LOG.info(e);
      } catch (IOException e) {
        myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
        LOG.info(e);
      } finally {
        myStatistics.incClassesCount();
        updateStatistics();
      }
    }