List<OrderRoot> (@NotNull final Collection<? extends VirtualFile> rootCandidates, @Nullable Component parentComponent, @Nullable Project project, @NotNull final LibraryRootsDetector detector, OrderRootType @NotNull [] rootTypesAllowedToBeSelectedByUserIfNothingIsDetected) { final List<OrderRoot> result = new ArrayList<>(); final List<SuggestedChildRootInfo> suggestedRoots = new ArrayList<>(); new Task.Modal(project, ProjectBundle.message("progress.title.scanning.for.roots"), true) { @Override public void run(@NotNull ProgressIndicator indicator) { try { for (VirtualFile rootCandidate : rootCandidates) { final Collection<DetectedLibraryRoot> roots = detector.detectRoots(rootCandidate, indicator); if (!roots.isEmpty() && allRootsHaveOneTypeAndEqualToOrAreDirectParentOf(roots, rootCandidate)) { for (DetectedLibraryRoot root : roots) { final LibraryRootType libraryRootType = root.getTypes().get(0); result.add(new OrderRoot(root.getFile(), libraryRootType.getType(), libraryRootType.isJarDirectory())); } } else { for (DetectedLibraryRoot root : roots) { final HashMap<LibraryRootType, String> names = new HashMap<>(); for (LibraryRootType type : root.getTypes()) { final String typeName = detector.getRootTypeName(type); LOG.assertTrue(typeName != null, "Unexpected root type " + type.getType().name() + (type.isJarDirectory() ? " (JAR directory)" : "") + ", detectors: " + detector); names.put(type, typeName); } suggestedRoots.add(new SuggestedChildRootInfo(rootCandidate, root, names)); } } } } catch (ProcessCanceledException ignored) { } } }.queue(); if (!suggestedRoots.isEmpty()) { final DetectedRootsChooserDialog dialog = parentComponent != null ? new DetectedRootsChooserDialog(parentComponent, suggestedRoots) : new DetectedRootsChooserDialog(project, suggestedRoots); if (!dialog.showAndGet()) { return Collections.emptyList(); } for (SuggestedChildRootInfo rootInfo : dialog.getChosenRoots()) { final LibraryRootType selectedRootType = rootInfo.getSelectedRootType(); result.add(new OrderRoot(rootInfo.getDetectedRoot().getFile(), selectedRootType.getType(), selectedRootType.isJarDirectory())); } } if (result.isEmpty() && rootTypesAllowedToBeSelectedByUserIfNothingIsDetected.length > 0) { Map<String, Pair<OrderRootType, Boolean>> types = new HashMap<>(); for (OrderRootType type : rootTypesAllowedToBeSelectedByUserIfNothingIsDetected) { for (boolean isJarDirectory : new boolean[]{false, true}) { final String typeName = detector.getRootTypeName(new LibraryRootType(type, isJarDirectory)); if (typeName != null) { types.put(StringUtil.capitalizeWords(typeName, true), Pair.create(type, isJarDirectory)); } } } LOG.assertTrue(!types.isEmpty(), "No allowed root types found for " + detector); List<String> names = new ArrayList<>(types.keySet()); if (names.size() == 1) { String title = LangBundle.message("dialog.title.attach.roots"); String typeName = names.get(0); String message = LangBundle.message("dialog.message.cannot.determine", ApplicationNamesInfo.getInstance().getProductName(), typeName); int answer = parentComponent != null ? Messages.showYesNoDialog(parentComponent, message, title, null) : Messages.showYesNoDialog(project, message, title, null); if (answer == Messages.YES) { Pair<OrderRootType, Boolean> pair = types.get(typeName); for (VirtualFile candidate : rootCandidates) { result.add(new OrderRoot(candidate, pair.getFirst(), pair.getSecond())); } } } else { String title = LangBundle.message("dialog.title.choose.categories.selected.files"); String description = XmlStringUtil.wrapInHtml( LangBundle.message("root.detector.cannot.determine.file.kind", ApplicationNamesInfo.getInstance().getProductName())); ChooseElementsDialog<String> dialog; if (parentComponent != null) { dialog = new ChooseRootTypeElementsDialog(parentComponent, names, title, description); } else { dialog = new ChooseRootTypeElementsDialog(project, names, title, description); } for (String rootType : dialog.showAndGetResult()) { final Pair<OrderRootType, Boolean> pair = types.get(rootType); for (VirtualFile candidate : rootCandidates) { result.add(new OrderRoot(candidate, pair.getFirst(), pair.getSecond())); } } } } return result; }