private static @NotNull AbstractPopup createUsagePopup(@NotNull UsageViewImpl usageView,
                                                         @NotNull ShowUsagesPopupData showUsagesPopupData,
                                                         @NotNull Runnable itemChoseCallback,
                                                         @NotNull Consumer<? super AbstractPopup> tableResizer) {
    ThreadingAssertions.assertEventDispatchThread();

    @NotNull JTable table = showUsagesPopupData.table;
    @NotNull AtomicReference<AbstractPopup> popupRef = showUsagesPopupData.popupRef;
    @NotNull ShowUsagesActionHandler actionHandler = showUsagesPopupData.actionHandler;
    @NotNull ShowUsagesParameters parameters = showUsagesPopupData.parameters;
    @NotNull Project project = parameters.project;
    @NotNull DialogPanel headerPanel = showUsagesPopupData.header.panel;

    SpeedSearchAdvertiser advertiser = new SpeedSearchAdvertiser();
    String hint = getSecondInvocationHint(actionHandler);

    JPanel advertiserComponent = null;
    boolean hintAdded = advertiser.addAdvertisement(hint);
    boolean speedSearchAdded = advertiser.addSpeedSearchAdvertisement() != null;
    if (hintAdded || speedSearchAdded) {
      advertiserComponent = advertiser.getComponent();
    }

    PopupChooserBuilder<?> builder = JBPopupFactory.getInstance().createPopupChooserBuilder(table).
      setTitle(showUsagesPopupData.header.getTitle()).
      setAdvertiser(advertiserComponent).
      setMovable(true).
      setResizable(true).
      setCancelKeyEnabled(true);

    PropertiesComponent properties = PropertiesComponent.getInstance(project);
    boolean addCodePreview = properties.isValueSet(PREVIEW_PROPERTY_KEY);
    OnePixelSplitter contentSplitter = null;
    if (addCodePreview) {
      contentSplitter = new OnePixelSplitter(true, .6f);
      contentSplitter.setSplitterProportionKey(SPLITTER_SERVICE_KEY);
      contentSplitter.setDividerPositionStrategy(Splitter.DividerPositionStrategy.KEEP_SECOND_SIZE);
      contentSplitter.getDivider().setBackground(OnePixelDivider.BACKGROUND);
      builder.setContentSplitter(contentSplitter);
    }

    Disposable contentDisposable = Disposer.newDisposable();

    KeyboardShortcut shortcut = UsageViewUtil.getShowUsagesWithSettingsShortcut();
    if (shortcut != null) {
      new DumbAwareAction() {
        @Override
        public void actionPerformed(@NotNull AnActionEvent e) {
          cancel(popupRef.get());
          showDialogAndRestart(parameters, actionHandler);
        }
      }.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table);
    }
    shortcut = getShowUsagesShortcut();
    if (shortcut != null) {
      new DumbAwareAction() {
        @Override
        public void actionPerformed(@NotNull AnActionEvent e) {
          showUsagesInMaximalScope(parameters, actionHandler, showUsagesPopupData);
        }
      }.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table);
    }

    DefaultActionGroup filteringGroup = new DefaultActionGroup();
    usageView.addFilteringActions(filteringGroup);
    ActionManager actionManager = ActionManager.getInstance();
    filteringGroup.add(actionManager.getAction("UsageGrouping.FileStructure"));
    filteringGroup.add(new ToggleAction(UsageViewBundle.message("preview.usages.action.text"), null, AllIcons.Actions.PreviewDetailsVertically) {
      @Override
      public boolean isSelected(@NotNull AnActionEvent e) {
        return properties.isValueSet(PREVIEW_PROPERTY_KEY);
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.BGT;
      }

      @Override
      public void setSelected(@NotNull AnActionEvent e, boolean state) {
        if (e.getDataContext() != DataContext.EMPTY_CONTEXT) { // Avoid fake events
          properties.setValue(PREVIEW_PROPERTY_KEY, state);
          cancel(popupRef.get(), actionHandler, CLOSE_REASON_PREVIEW);

          showElementUsages(parameters, actionHandler);
        }
      }
    });

    JPanel northPanel = new JPanel(new GridBagLayout());
    GridBag gc = new GridBag().nextLine();

    ActionToolbar actionToolbar = createActionToolbar(table, filteringGroup);
    JComponent toolbarComponent = actionToolbar.getComponent();
    toolbarComponent.setOpaque(false);
    northPanel.add(toolbarComponent, gc.next());

    SearchScope maximalScope;
    try (AccessToken ignore = SlowOperations.knownIssue("IDEA-349679, EA-891094")) {
      maximalScope = actionHandler.getMaximalScope();
    }
    if (!(maximalScope instanceof LocalSearchScope)) {
      DefaultActionGroup scopeChooserGroup = new DefaultActionGroup(createScopeChooser(project, contentDisposable, usageView, showUsagesPopupData));
      ActionToolbar scopeChooserToolbar =
        actionManager.createActionToolbar(ActionPlaces.SHOW_USAGES_POPUP_TOOLBAR, scopeChooserGroup, true);
      scopeChooserToolbar.setTargetComponent(table);
      scopeChooserToolbar.setLayoutStrategy(ToolbarLayoutStrategy.NOWRAP_STRATEGY);
      ((ActionToolbarImpl) scopeChooserToolbar).setForceMinimumSize(true);
      JComponent component = scopeChooserToolbar.getComponent();
      component.setBorder(JBUI.Borders.empty());
      component.setOpaque(false);
      northPanel.add(component, gc.next());
    }

    Dimension fillerSize = JBUI.size(8, 0);
    northPanel.add(new Box.Filler(fillerSize, fillerSize, fillerSize), gc.next().weightx(1.0));

    DefaultActionGroup settingsGroup = new DefaultActionGroup(
      new SettingsAction(project, () -> cancel(popupRef.get()), showDialogAndRestartRunnable(parameters, actionHandler)));
    actionToolbar = createActionToolbar(table, settingsGroup);
    ((ActionToolbarImpl) actionToolbar).setForceMinimumSize(true);
    JComponent settingsToolbarComponent = actionToolbar.getComponent();
    settingsToolbarComponent.setOpaque(false);

    if (Registry.is("ide.usages.popup.show.options.string")) {
      JLabel optionsLabel = new JLabel(actionHandler.getPresentation().getOptionsString());
      if (ExperimentalUI.isNewUI()) {
        optionsLabel.setForeground(JBUI.CurrentTheme.ContextHelp.FOREGROUND);
      }
      northPanel.add(optionsLabel, gc.next());
    }
    northPanel.add(settingsToolbarComponent, gc.next());

    builder.setNorthComponent(northPanel);

    PopupUpdateProcessor processor = new PopupUpdateProcessor(usageView.getProject()) {
      @Override
      public void updatePopup(Object lookupItemObject) {/*not used*/}
    };
    builder.addListener(processor);

    if (addCodePreview) {
      SimpleColoredComponent previewTitle = new SimpleColoredComponent();
      PopupUtil.applyPreviewTitleInsets(previewTitle);
      UsagePreviewPanel usagePreviewPanel = new UsagePreviewPanel(project, usageView.getPresentation(), false) {
        @Override
        public Dimension getPreferredSize() {
          return new Dimension(table.getWidth(), Math.max(getHeight(), getLineHeight() * 5));
        }

        @Override
        public Dimension getMinimumSize() {
          Dimension size = super.getMinimumSize();
          size.height = getLineHeight() * 5;
          return size;
        }
      };

      PropertyChangeListener lineHeightListener = e -> {
        if ((Integer)e.getNewValue() > 0) {
          tableResizer.accept(popupRef.get());
        }
      };

      usagePreviewPanel.addPropertyChangeListener(UsagePreviewPanel.LINE_HEIGHT_PROPERTY, lineHeightListener);

      Disposer.register(contentDisposable, () -> usagePreviewPanel.removePropertyChangeListener(lineHeightListener));
      Disposer.register(contentDisposable, usagePreviewPanel);

      JPanel previewPanel = new JPanel(new BorderLayout());
      previewPanel.add(previewTitle, BorderLayout.NORTH);
      previewPanel.add(usagePreviewPanel.createComponent(), BorderLayout.CENTER);
      contentSplitter.setSecondComponent(previewPanel);

      if (ExperimentalUI.isNewUI()) {
        previewPanel.setBackground(JBUI.CurrentTheme.Popup.BACKGROUND);
        previewTitle.setOpaque(false);
      }

      new DoubleClickListener() {
        @Override
        protected boolean onDoubleClick(@NotNull MouseEvent event) {
          if (event.getSource() != table) return false;
          itemChoseCallback.run();
          return true;
        }
      }.installOn(table);

      builder.setAutoselectOnMouseMove(false).setCloseOnEnter(false).
        registerKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), __ -> itemChoseCallback.run());

      Runnable updatePreviewRunnable = () -> {
        if (popupRef.get().isDisposed()) return;
        int[] selectedRows = table.getSelectedRows();
        String file = null;
        List<UsageInfoAdapter> adapters = new ArrayList<>();
        for (int row : selectedRows) {
          Object value = table.getModel().getValueAt(row, 0);

          if (value instanceof UsageNode) {
            Usage usage = ((UsageNode)value).getUsage();
            if (usage instanceof UsageInfoAdapter adapter) {
              file = adapter.getPath();
              adapters.add(adapter);
            }
          }
        }

        String selectedFile = file;

        UsageAdaptersKt.getUsageInfo(adapters, project).thenAccept(selectedUsages -> {
          ReadAction.nonBlocking(() -> UsagePreviewPanel.isOneAndOnlyOnePsiFileInUsages(selectedUsages))
              .finishOnUiThread(ModalityState.nonModal(), isOneAndOnlyOnePsiFileInUsages -> {
                usagePreviewPanel.updateLayout(project, selectedUsages);
                previewTitle.clear();

                if (isOneAndOnlyOnePsiFileInUsages && selectedFile != null) {
                  previewTitle.append(PathUtil.getFileName(selectedFile), SimpleTextAttributes.REGULAR_ATTRIBUTES);
                }
              })
            .expireWith(contentDisposable)
            .submit(AppExecutorUtil.getAppExecutorService());
        }).exceptionally(throwable -> {
          Logger.getInstance(ShowUsagesAction.class).error(throwable);
          return null;
        });
      };

      Alarm previewUpdater = new Alarm(contentDisposable);

      table.getSelectionModel().addListSelectionListener(e -> {
        if (!e.getValueIsAdjusting() && !previewUpdater.isDisposed()) {
          previewUpdater.addRequest(updatePreviewRunnable, 50);
        }
      });
    }
    else {
      builder.setAutoselectOnMouseMove(!ScreenReader.isActive()).setItemChosenCallback(itemChoseCallback).setCloseOnEnter(true);
    }

    AbstractPopup popup = (AbstractPopup)builder.createPopup();
    JComponent content = popup.getContent();
    Disposer.register(popup, contentDisposable);

    // Replace compound header by ShowUsagesHeader. A little hack because there is no suitable popup API
    // CWM: new API method in popup API should be introduced for setting headerPanel
    CaptionPanel captionPanel = popup.getTitle();
    Container parent = captionPanel.getParent();
    if (parent != null) {
      parent.remove(captionPanel);
      parent.add(headerPanel);
      new WindowMoveListener(headerPanel).installTo(headerPanel);
    }

    if (ExperimentalUI.isNewUI()) {
      headerPanel.setBorder(
        JBUI.Borders.compound(JBUI.Borders.customLineBottom(JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground()),
                              PopupUtil.getComplexPopupHorizontalHeaderBorder()));
      headerPanel.setBackground(JBUI.CurrentTheme.ComplexPopup.HEADER_BACKGROUND);

      Color background = JBUI.CurrentTheme.Popup.BACKGROUND;
      northPanel.setBackground(background);
      table.setBackground(background);
      northPanel.setBorder(createComplexPopupToolbarBorder());
      toolbarComponent.setBorder(JBUI.Borders.empty());
      settingsToolbarComponent.setBorder(JBUI.Borders.emptyLeft(8));
      if (contentSplitter != null) {
        contentSplitter.setBackground(background);
        contentSplitter.setOpaque(true);
        Insets textFieldBorderInsets = JBUI.CurrentTheme.ComplexPopup.textFieldBorderInsets();
        //noinspection UseDPIAwareInsets
        contentSplitter.setBlindZone(() -> new Insets(0, textFieldBorderInsets.left, 0, textFieldBorderInsets.right));
      }
    } else {
      headerPanel.setBorder(JBUI.Borders.empty(2, 15, 2, 2));
      headerPanel.setBackground(JBUI.CurrentTheme.Popup.headerBackground(true));
    }

    parameters.minWidth.set(-1);
    for (AnAction action : filteringGroup.getChildren(actionManager)) {
      action.unregisterCustomShortcutSet(usageView.getComponent());
      action.registerCustomShortcutSet(action.getShortcutSet(), content);
    }

    for (AnAction action : showUsagesPopupData.pinGroup.getChildren(actionManager)) {
      action.unregisterCustomShortcutSet(usageView.getComponent());
      action.registerCustomShortcutSet(action.getShortcutSet(), content);
    }
    /* save toolbar actions for using later, in automatic filter toggling in {@link #restartShowUsagesWithFiltersToggled(List} */
    popup.setUserData(addCodePreview ? Arrays.asList(filteringGroup, contentSplitter) : Collections.singletonList(filteringGroup));
    popup.setDataProvider(dataId -> {
      if (UsageView.USAGE_VIEW_SETTINGS_KEY.is(dataId)) {
        return usageView.getUsageViewSettings();
      }
      else {
        return null;
      }
    });
    popupRef.set(popup);
    return popup;
  }
private static @NotNull AbstractPopup createUsagePopup(@NotNull UsageViewImpl usageView,
                                                         @NotNull ShowUsagesPopupData showUsagesPopupData,
                                                         @NotNull Runnable itemChoseCallback,
                                                         @NotNull Consumer<? super AbstractPopup> tableResizer)