ProgressIndicator (@NotNull Map<? extends SearchEverywhereContributor<?>, Integer> contributorsAndLimits, @NotNull String pattern) { LOG.debug("Search started for pattern [", pattern, "]"); Collection<? extends SearchEverywhereContributor<?>> contributors = contributorsAndLimits.keySet(); if (pattern.isEmpty() && ApplicationManager.getApplication().isUnitTestMode()) { contributors = Collections.emptySet(); //empty search string is not allowed for tests } contributors = ContainerUtil.filter(contributors, contributor -> !contributor.filterControlSymbols(pattern).isEmpty() || contributor.isEmptyPatternSupported()); ProgressIndicator indicator; FullSearchResultsAccumulator accumulator; if (!contributors.isEmpty()) { CountDownLatch latch = new CountDownLatch(contributors.size()); ProgressIndicatorWithCancelListener indicatorWithCancelListener = new ProgressIndicatorWithCancelListener(); accumulator = new FullSearchResultsAccumulator(contributorsAndLimits, myEqualityProvider, myListener, myNotificationExecutor, indicatorWithCancelListener); accumulator.startSearch(pattern); for (SearchEverywhereContributor<?> contributor : contributors) { Runnable task = createSearchTask(pattern, accumulator, indicatorWithCancelListener, contributor, () -> latch.countDown()); ApplicationManager.getApplication().executeOnPooledThread(task); } Runnable finisherTask = createFinisherTask(latch, accumulator, indicatorWithCancelListener); Future<?> finisherFeature = ApplicationManager.getApplication().executeOnPooledThread(finisherTask); indicatorWithCancelListener.setCancelCallback(() -> { accumulator.stop(); finisherFeature.cancel(true); }); indicator = indicatorWithCancelListener; } else { indicator = new ProgressIndicatorBase(); accumulator = new FullSearchResultsAccumulator(contributorsAndLimits, myEqualityProvider, myListener, myNotificationExecutor, indicator); accumulator.startSearch(pattern); } indicator.start(); if (contributors.isEmpty()) { indicator.stop(); accumulator.searchFinished(); } return indicator; }