ListPopup (@NotNull Project project, @NotNull RunManagerImpl runManager, @NotNull List<? extends RunConfiguration> configurations, @NotNull BiConsumer<? super List<RunConfiguration>, ? super ExecutionTarget> onSelected) { return JBPopupFactory.getInstance().createListPopup(new MultiSelectionListPopupStep<RunConfiguration>(null, configurations) { @Override public @Nullable ListSeparator getSeparatorAbove(RunConfiguration value) { int i = configurations.indexOf(value); if (i < 1) return null; RunConfiguration previous = configurations.get(i - 1); return value.getType() != previous.getType() ? new ListSeparator() : null; } @Override public Icon getIconFor(RunConfiguration value) { return value.getType().getIcon(); } @Override public boolean isSpeedSearchEnabled() { return true; } @Override public @NotNull String getTextFor(RunConfiguration value) { return value.getName(); } @Override public PopupStep<?> onChosen(List<RunConfiguration> selectedConfigs, boolean finalChoice) { if (finalChoice) { onSelected.accept(selectedConfigs, null); return FINAL_CHOICE; } else { return new BaseListPopupStep<>(null, getTargets(selectedConfigs)) { @Override public boolean isSpeedSearchEnabled() { return true; } @Override public Icon getIconFor(ExecutionTarget value) { return value.getIcon(); } @Override public @NotNull String getTextFor(ExecutionTarget value) { return value.getDisplayName(); } @Override public PopupStep onChosen(ExecutionTarget selectedTarget, boolean finalChoice) { onSelected.accept(selectedConfigs, selectedTarget); return FINAL_CHOICE; } }; } } @Override public boolean hasSubstep(List<? extends RunConfiguration> selectedValues) { return !getTargets(selectedValues).isEmpty(); } public @NotNull List<ExecutionTarget> getTargets(List<? extends RunConfiguration> selectedValues) { LinkedHashSet<ExecutionTarget> intersection = new LinkedHashSet<>(); for (int i = 0; i < selectedValues.size(); i++) { RunConfiguration config = selectedValues.get(i); RunnerAndConfigurationSettingsImpl settings = runManager.getSettings(config); List<ExecutionTarget> targets = settings == null ? Collections.emptyList() : ExecutionTargetManager.getTargetsToChooseFor(project, settings.getConfiguration()); if (i == 0) { intersection.addAll(targets); } else { intersection.retainAll(targets); } } return new ArrayList<>(intersection); } }); }