@NotNull
  public ListPopup buildPopup() {
    List<String> ids = new ArrayList<>(restoreLRUItems());
    if (mySelection != null) {
      ids.add(getStorageId(mySelection));
    }
    List<T> topItems = myTopValues.toList();
    List<T> lru = new ArrayList<>(LRU_ITEMS);
    List<T> middleItems = myMiddleValues.toList();
    List<T> items = new ArrayList<>(MAX_VISIBLE_SIZE);
    List<T> bottomItems = myBottomValues.toList();
    for (T t : JBIterable.from(myValues)) {
      (ids.contains(getStorageId(t)) ? lru : items).add(t);
    }
    if (myComparator != null) {
      items.sort(myComparator);
    }
    if (!lru.isEmpty()) {
      lru.sort(Comparator.comparingInt(o -> ids.indexOf(getStorageId(o))));
    }
    List<T> combinedItems = ContainerUtil.concat(topItems, lru, middleItems, items, bottomItems);
    T sep1 = ContainerUtil.getOrElse(combinedItems, topItems.size() + lru.size() + middleItems.size(), null);
    T sep2 = ContainerUtil.getOrElse(combinedItems, topItems.size() + lru.size() + middleItems.size() + items.size(), null);

    BaseListPopupStep<T> step =
      new BaseListPopupStep<>(myTitle, combinedItems) {
        @NotNull
        @Override
        public String getTextFor(T t) {
          return t == null ? "" : getPresentation(t).first;
        }

        @Override
        public Icon getIconFor(T t) {
          return t == null ? null : getPresentation(t).second;
        }

        @Override
        public boolean isSpeedSearchEnabled() {
          return true;
        }

        @Override
        public String getIndexedString(T value) {
          String extra = myExtraSpeedSearchNamer != null ? StringUtil.nullize(myExtraSpeedSearchNamer.apply(value)) : null;
          if (extra == null) return super.getIndexedString(value);
          return super.getIndexedString(value) + SpeedSearchUtil.getDefaultHardSeparators() + extra;
        }

        @Override
        public PopupStep<?> onChosen(final T t, boolean finalChoice) {
          if (!bottomItems.contains(t) && !topItems.contains(t)) {
            storeLRUItems(t);
          }
          if (myOnChosen != null) {
            doFinalStep(() -> myOnChosen.consume(t));
          }
          return null;
        }

        @Nullable
        @Override
        public ListSeparator getSeparatorAbove(T value) {
          return value == sep1 || value == sep2 ? new ListSeparator() : null;
        }
      };
    int selection = Math.max(0, mySelection != null ? combinedItems.indexOf(mySelection) : 0);
    step.setDefaultOptionIndex(selection);

    return tweakSizeToPreferred(JBPopupFactory.getInstance().createListPopup(step));
  }
@NotNull
  public ListPopup buildPopup()