public static void addRemoveEntriesWithUndo(@NotNull Project project, @Nullable Module module, @NotNull List<? extends VirtualFile> roots, boolean add) {
    List<VirtualFile> adjustedRoots = ContainerUtil.newArrayList(JBIterable.from(roots)
      .filter(o -> add == (ModuleUtilCore.findModuleForFile(o, project) == null))
      .filterMap(o -> o.isDirectory() ? o : o.getParent())
      .unique());
    adjustedRoots.removeIf(r -> ContainerUtil.exists(adjustedRoots, r2 -> VfsUtilCore.isAncestor(r2, r, true)));

    if (adjustedRoots.isEmpty()) return;

    final class MyUndoable extends GlobalUndoableAction {
      @Override
      public void undo() {
        addRemoveEntriesInner(project, module, adjustedRoots, !add);
      }

      @Override
      public void redo() {
        addRemoveEntriesInner(project, module, adjustedRoots, add);
      }
    }
    String title = IdeBundle.message("command.name.choice.attach.detach", add ? 0 : 1, getDisplayName(adjustedRoots));
    WriteCommandAction.writeCommandAction(project)
      .withName(title)
      .withUndoConfirmationPolicy(UndoConfirmationPolicy.REQUEST_CONFIRMATION).run(()-> {
        MyUndoable undoable = new MyUndoable();
        undoable.redo();
        UndoManager.getInstance(project).undoableActionPerformed(undoable);
    });
  }
public static void addRemoveEntriesWithUndo(@NotNull Project project, @Nullable Module module, @NotNull List<? extends VirtualFile> roots, boolean add)