private boolean checkUnderReadAction(
      final MyValidatorProcessingItem item,
      final CompileContext context,
      final Computable<Map<ProblemDescriptor, HighlightDisplayLevel>> runnable) {
    return DumbService.getInstance(context.getProject())
        .runReadActionInSmartMode(
            new Computable<Boolean>() {
              @Override
              public Boolean compute() {
                final PsiFile file = item.getPsiFile();
                if (file == null) return false;

                final Document document = myPsiDocumentManager.getCachedDocument(file);
                if (document != null && myPsiDocumentManager.isUncommited(document)) {
                  final String url = file.getViewProvider().getVirtualFile().getUrl();
                  context.addMessage(
                      CompilerMessageCategory.WARNING,
                      CompilerBundle.message("warning.text.file.has.been.changed"),
                      url,
                      -1,
                      -1);
                  return false;
                }

                if (reportProblems(context, runnable.compute())) return false;
                return true;
              }
            });
  }
  @Override
  @NotNull
  public ProcessingItem[] getProcessingItems(final CompileContext context) {
    final Project project = context.getProject();
    if (project.isDefault() || !ValidationConfiguration.shouldValidate(this, context)) {
      return ProcessingItem.EMPTY_ARRAY;
    }
    final ExcludesConfiguration excludesConfiguration =
        ValidationConfiguration.getExcludedEntriesConfiguration(project);
    final List<ProcessingItem> items =
        DumbService.getInstance(project)
            .runReadActionInSmartMode(
                new Computable<List<ProcessingItem>>() {
                  @Override
                  public List<ProcessingItem> compute() {
                    final CompileScope compileScope = context.getCompileScope();
                    if (!myValidator.isAvailableOnScope(compileScope)) return null;

                    final ArrayList<ProcessingItem> items = new ArrayList<ProcessingItem>();

                    final Processor<VirtualFile> processor =
                        new Processor<VirtualFile>() {
                          @Override
                          public boolean process(VirtualFile file) {
                            if (!file.isValid()) {
                              return true;
                            }

                            if (myCompilerManager.isExcludedFromCompilation(file)
                                || excludesConfiguration.isExcluded(file)) {
                              return true;
                            }

                            final Module module = context.getModuleByFile(file);
                            if (module != null) {
                              final PsiFile psiFile = myPsiManager.findFile(file);
                              if (psiFile != null) {
                                items.add(new MyValidatorProcessingItem(psiFile));
                              }
                            }
                            return true;
                          }
                        };
                    ContainerUtil.process(
                        myValidator.getFilesToProcess(myPsiManager.getProject(), context),
                        processor);
                    return items;
                  }
                });
    if (items == null) return ProcessingItem.EMPTY_ARRAY;

    return items.toArray(new ProcessingItem[items.size()]);
  }
  private static GenerationItem[] doGenerate(
      @NotNull final CompileContext context,
      @NotNull final GenerationItem[] items,
      VirtualFile outputRootDirectory) {
    if (context.getProject().isDisposed()) {
      return EMPTY_GENERATION_ITEM_ARRAY;
    }

    // we have one item per module there, so clear output directory
    final String genRootPath = FileUtil.toSystemDependentName(outputRootDirectory.getPath());
    final File genRootDir = new File(genRootPath);
    if (genRootDir.exists()) {
      if (!FileUtil.delete(genRootDir)) {
        context.addMessage(
            CompilerMessageCategory.ERROR, "Cannot delete directory " + genRootPath, null, -1, -1);
        return EMPTY_GENERATION_ITEM_ARRAY;
      }
      if (!genRootDir.mkdir()) {
        context.addMessage(
            CompilerMessageCategory.ERROR, "Cannot create directory " + genRootPath, null, -1, -1);
        return EMPTY_GENERATION_ITEM_ARRAY;
      }
    }

    final List<GenerationItem> results = new ArrayList<GenerationItem>(items.length);
    for (final GenerationItem item : items) {
      if (item instanceof MyGenerationItem) {
        final MyGenerationItem genItem = (MyGenerationItem) item;

        if (!AndroidCompileUtil.isModuleAffected(context, genItem.myModule)) {
          continue;
        }

        boolean success = true;

        for (final VirtualFile sourceFile : genItem.myFiles) {
          final String depFolderOsPath =
              getDependencyFolder(context.getProject(), sourceFile, outputRootDirectory);

          try {
            final Map<CompilerMessageCategory, List<String>> messages =
                AndroidCompileUtil.toCompilerMessageCategoryKeys(
                    AndroidRenderscript.execute(
                        genItem.mySdkLocation,
                        genItem.myAndroidTarget,
                        sourceFile.getPath(),
                        genRootPath,
                        depFolderOsPath,
                        genItem.myRawDirPath));

            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      public void run() {
                        if (context.getProject().isDisposed()) {
                          return;
                        }
                        addMessages(context, messages, sourceFile.getUrl());
                      }
                    });

            if (messages.get(CompilerMessageCategory.ERROR).size() > 0) {
              success = false;
            }
          } catch (final IOException e) {
            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      public void run() {
                        if (context.getProject().isDisposed()) return;
                        context.addMessage(
                            CompilerMessageCategory.ERROR,
                            e.getMessage(),
                            sourceFile.getUrl(),
                            -1,
                            -1);
                      }
                    });
            success = false;
          }
        }

        if (success) {
          results.add(genItem);
        }
      }
    }
    outputRootDirectory.refresh(false, true);
    return results.toArray(new GenerationItem[results.size()]);
  }