public static void showPopup(@NotNull Project project, boolean showChanged,
                               @NotNull @NlsContexts.PopupTitle String title1,
                               @NotNull @NlsContexts.PopupTitle String title2,
                               @NotNull @NlsContexts.StatusText String emptyText,
                               @Nullable Function<? super Boolean, ? extends List<IdeDocumentHistoryImpl.PlaceInfo>> supplier,
                               @Nullable Consumer<? super List<IdeDocumentHistoryImpl.PlaceInfo>> remover) {
    RecentLocationsDataModel model = new RecentLocationsDataModel(project, supplier, remover);
    JBList<RecentLocationItem> list = new JBList<>(JBList.createDefaultListModel(model.getPlaces(showChanged)));
    final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(list,
                                                                      ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                                                                      ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

    scrollPane.setBorder(BorderFactory.createEmptyBorder());

    ShortcutSet showChangedOnlyShortcutSet = KeymapUtil.getActiveKeymapShortcuts(RECENT_LOCATIONS_ACTION_ID);
    JBCheckBox checkBox = createCheckbox(showChangedOnlyShortcutSet, showChanged);
    RecentLocationsRenderer renderer = new RecentLocationsRenderer(project, model, checkBox);

    list.setCellRenderer(renderer);
    list.setEmptyText(emptyText);
    list.setBackground(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground());
    if (list.getModel().getSize() > 0) list.setSelectedIndex(0);
    ScrollingUtil.installActions(list);

    SimpleColoredComponent title = new SimpleColoredComponent();
    title.setOpaque(false);
    Runnable titleUpdater = () -> {
      title.clear();
      title.append(checkBox.isSelected() ? title2 : title1, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
      title.append("  (" + list.getModel().getSize() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
    };
    titleUpdater.run();

    JComponent listWithFilter = ListWithFilter.wrap(list, scrollPane, renderer::getSpeedSearchText, true);
    //noinspection unchecked
    ((ListWithFilter<Object>)listWithFilter).setAutoPackHeight(false);
    listWithFilter.setBorder(BorderFactory.createEmptyBorder());

    JPanel topPanel = createHeaderPanel(title, checkBox);
    JPanel mainPanel = createMainPanel(listWithFilter, topPanel);

    Color borderColor = SystemInfo.isMac && LafManager.getInstance().getCurrentUIThemeLookAndFeel().isDark()
                        ? topPanel.getBackground()
                        : null;

    JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(mainPanel, list)
      .setProject(project)
      .setCancelOnClickOutside(true)
      .setRequestFocus(true)
      .setResizable(true)
      .setMovable(true)
      .setBorderColor(borderColor)
      .setDimensionServiceKey(project, LOCATION_SETTINGS_KEY, true)
      .setMinSize(new Dimension(getMinimumWidth(), getMinimumHeight()))
      .setLocateWithinScreenBounds(false)
      .createPopup();
    Disposer.register(popup, renderer);

    LightEditActionFactory.create(event -> {
      checkBox.setSelected(!checkBox.isSelected());
      updateItems(model, list, checkBox, popup);
      titleUpdater.run();
    }).registerCustomShortcutSet(showChangedOnlyShortcutSet, list, popup);

    checkBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        updateItems(model, list, checkBox, popup);
        titleUpdater.run();
      }
    });

    if (DimensionService.getInstance().getSize(LOCATION_SETTINGS_KEY, project) == null) {
      popup.setSize(new Dimension(getDefaultWidth(), getDefaultHeight()));
    }

    list.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent event) {
        int clickCount = event.getClickCount();
        if (clickCount > 1 && clickCount % 2 == 0) {
          event.consume();
          final int i = list.locationToIndex(event.getPoint());
          if (i != -1) {
            list.setSelectedIndex(i);
            navigateToSelected(project, list, popup);
          }
        }
      }
    });

    list.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent event) {
        int clickCount = event.getClickCount();
        if (clickCount > 1 && clickCount % 2 == 0) {
          event.consume();
          navigateToSelected(project, list, popup);
        }
      }
    });

    LightEditActionFactory.create(e -> navigateToSelected(project, list, popup))
      .registerCustomShortcutSet(CustomShortcutSet.fromString("ENTER"), list, popup);

    LightEditActionFactory.create(e -> {
        removeItems(project, list, model, checkBox.isSelected());
        titleUpdater.run();
      })
      .registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE", "BACK_SPACE"), list, popup);

    IdeEventQueue.getInstance().getPopupManager().closeAllPopups(false);

    list.addFocusListener(new FocusAdapter() {
      @Override
      public void focusLost(FocusEvent e) {
        if (!(e.getOppositeComponent() instanceof JCheckBox)) {
          popup.cancel();
        }
      }
    });

    showPopup(project, popup);
  }
public static void showPopup(@NotNull Project project, boolean showChanged,
                               @NotNull @NlsContexts.PopupTitle String title1,
                               @NotNull @NlsContexts.PopupTitle String title2,
                               @NotNull @NlsContexts.StatusText String emptyText,
                               @Nullable Function<? super Boolean, ? extends List<IdeDocumentHistoryImpl.PlaceInfo>> supplier,
                               @Nullable Consumer<? super List<IdeDocumentHistoryImpl.PlaceInfo>> remover)