private static void addClassesUsages(
      PsiPackage aPackage,
      final Processor<UsageInfo> results,
      final JavaPackageFindUsagesOptions options) {
    ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
    if (progress != null) {
      progress.pushState();
    }

    ArrayList<PsiClass> classes = new ArrayList<PsiClass>();
    addClassesInPackage(aPackage, options.isIncludeSubpackages, classes);
    for (final PsiClass aClass : classes) {
      if (progress != null) {
        progress.setText(
            FindBundle.message(
                "find.searching.for.references.to.class.progress",
                ApplicationManager.getApplication()
                    .runReadAction(
                        new Computable<String>() {
                          @Override
                          public String compute() {
                            return aClass.getName();
                          }
                        })));
        progress.checkCanceled();
      }
      ReferencesSearch.search(
              new ReferencesSearch.SearchParameters(
                  aClass, options.searchScope, false, options.fastTrack))
          .forEach(
              new ReadActionProcessor<PsiReference>() {
                @Override
                public boolean processInReadAction(final PsiReference psiReference) {
                  return addResult(results, psiReference, options);
                }
              });
    }

    if (progress != null) {
      progress.popState();
    }
  }
  @NotNull
  private File copyToMirror(@NotNull File original, @NotNull File mirror) {
    ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
    if (progress != null) {
      progress.pushState();
      progress.setText(VfsBundle.message("jar.copy.progress", original.getPath()));
      progress.setFraction(0);
    }

    try {
      FileUtil.copy(original, mirror);
    } catch (final IOException e) {
      reportIOErrorWithJars(original, mirror, e);
      return original;
    }

    if (progress != null) {
      progress.popState();
    }

    return mirror;
  }
  private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) {
    if (ApplicationManager.getApplication().isInternal()) LOG.info("schedule " + task);
    final Application application = ApplicationManager.getApplication();

    if (application.isUnitTestMode()
        || application.isHeadlessEnvironment()
        || !forceDumbMode && !myDumb && application.isReadAccessAllowed()) {
      final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
      if (indicator != null) {
        indicator.pushState();
      }
      try {
        HeavyProcessLatch.INSTANCE.processStarted();
        task.performInDumbMode(indicator != null ? indicator : new EmptyProgressIndicator());
      } finally {
        HeavyProcessLatch.INSTANCE.processFinished();
        if (indicator != null) {
          indicator.popState();
        }
        Disposer.dispose(task);
      }
      return;
    }

    UIUtil.invokeLaterIfNeeded(
        new DumbAwareRunnable() {
          @Override
          public void run() {
            if (myProject.isDisposed()) {
              return;
            }
            final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
            myProgresses.put(task, indicator);
            Disposer.register(
                task,
                new Disposable() {
                  @Override
                  public void dispose() {
                    application.assertIsDispatchThread();
                    myProgresses.remove(task);
                  }
                });
            // ok to test and set the flag like this, because the change is always done from
            // dispatch thread
            if (!myDumb) {
              // always change dumb status inside write action.
              // This will ensure all active read actions are completed before the app goes dumb
              boolean startSuccess =
                  application.runWriteAction(
                      new Computable<Boolean>() {
                        @Override
                        public Boolean compute() {
                          myDumb = true;
                          try {
                            myPublisher.enteredDumbMode();
                          } catch (Throwable e) {
                            LOG.error(e);
                          }

                          try {
                            startBackgroundProcess(task, indicator);
                          } catch (Throwable e) {
                            LOG.error("Failed to start background index update task", e);
                            return false;
                          }
                          return true;
                        }
                      });
              if (!startSuccess) {
                updateFinished();
              }
            } else {
              myUpdatesQueue.addLast(task);
            }
          }
        });
  }
 @Override
 public void pushState() {
   myIndicator.pushState();
 }