@NotNull
  @Override
  public RelativePoint guessBestPopupLocation(@NotNull DataContext dataContext) {
    Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
    JComponent focusOwner = component instanceof JComponent ? (JComponent) component : null;

    if (focusOwner == null) {
      Project project = PlatformDataKeys.PROJECT.getData(dataContext);
      IdeFrameImpl frame =
          project == null
              ? null
              : ((WindowManagerEx) WindowManager.getInstance()).getFrame(project);
      focusOwner = frame == null ? null : frame.getRootPane();
      if (focusOwner == null) {
        throw new IllegalArgumentException("focusOwner cannot be null");
      }
    }

    final Point point = PlatformDataKeys.CONTEXT_MENU_POINT.getData(dataContext);
    if (point != null) {
      return new RelativePoint(focusOwner, point);
    }

    Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
    if (editor != null && focusOwner == editor.getContentComponent()) {
      return guessBestPopupLocation(editor);
    } else {
      return guessBestPopupLocation(focusOwner);
    }
  }
    private static ListPopupStep createStep(
        String title,
        @NotNull ActionGroup actionGroup,
        @NotNull DataContext dataContext,
        boolean showNumbers,
        boolean useAlphaAsNumbers,
        boolean showDisabledActions,
        boolean honorActionMnemonics,
        Condition<AnAction> preselectActionCondition,
        @Nullable String actionPlace) {
      final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
      LOG.assertTrue(component != null, "dataContext has no component for new ListPopupStep");

      final ActionStepBuilder builder =
          new ActionStepBuilder(
              dataContext,
              showNumbers,
              useAlphaAsNumbers,
              showDisabledActions,
              honorActionMnemonics);
      if (actionPlace != null) {
        builder.setActionPlace(actionPlace);
      }
      builder.buildGroup(actionGroup);
      final List<ActionItem> items = builder.getItems();

      return new ActionPopupStep(
          items,
          title,
          component,
          showNumbers || honorActionMnemonics && itemsHaveMnemonics(items),
          preselectActionCondition,
          false,
          showDisabledActions);
    }
  public boolean processAction(final InputEvent e, ActionProcessor processor) {
    ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
    final Project project = PlatformDataKeys.PROJECT.getData(myContext.getDataContext());
    final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
    List<AnActionEvent> nonDumbAwareAction = new ArrayList<AnActionEvent>();
    for (final AnAction action : myContext.getActions()) {
      final Presentation presentation = myPresentationFactory.getPresentation(action);

      // Mouse modifiers are 0 because they have no any sense when action is invoked via keyboard
      final AnActionEvent actionEvent =
          processor.createEvent(
              e,
              myContext.getDataContext(),
              ActionPlaces.MAIN_MENU,
              presentation,
              ActionManager.getInstance());

      ActionUtil.performDumbAwareUpdate(action, actionEvent, true);

      if (dumb && !action.isDumbAware()) {
        if (Boolean.FALSE.equals(
            presentation.getClientProperty(ActionUtil.WOULD_BE_ENABLED_IF_NOT_DUMB_MODE))) {
          continue;
        }

        nonDumbAwareAction.add(actionEvent);
        continue;
      }

      if (!presentation.isEnabled()) {
        continue;
      }

      processor.onUpdatePassed(e, action, actionEvent);

      ((DataManagerImpl.MyDataContext) myContext.getDataContext())
          .setEventCount(IdeEventQueue.getInstance().getEventCount(), this);
      actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext(), actionEvent);
      Component component =
          PlatformDataKeys.CONTEXT_COMPONENT.getData(actionEvent.getDataContext());
      if (component != null && !component.isShowing()) {
        return true;
      }

      processor.performAction(e, action, actionEvent);
      actionManager.fireAfterActionPerformed(action, actionEvent.getDataContext(), actionEvent);
      return true;
    }

    if (!nonDumbAwareAction.isEmpty()) {
      showDumbModeWarningLaterIfNobodyConsumesEvent(
          e, nonDumbAwareAction.toArray(new AnActionEvent[nonDumbAwareAction.size()]));
    }

    return false;
  }
    public ActionGroupPopup(
        final String title,
        @NotNull ActionGroup actionGroup,
        @NotNull DataContext dataContext,
        boolean showNumbers,
        boolean useAlphaAsNumbers,
        boolean showDisabledActions,
        boolean honorActionMnemonics,
        final Runnable disposeCallback,
        final int maxRowCount,
        final Condition<AnAction> preselectActionCondition,
        @Nullable final String actionPlace) {
      super(
          createStep(
              title,
              actionGroup,
              dataContext,
              showNumbers,
              useAlphaAsNumbers,
              showDisabledActions,
              honorActionMnemonics,
              preselectActionCondition,
              actionPlace),
          maxRowCount);
      myDisposeCallback = disposeCallback;
      myComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);

      addListSelectionListener(
          new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
              final JList list = (JList) e.getSource();
              final ActionItem actionItem = (ActionItem) list.getSelectedValue();
              if (actionItem == null) return;
              AnAction action = actionItem.getAction();
              Presentation presentation = new Presentation();
              presentation.setDescription(action.getTemplatePresentation().getDescription());
              final String actualActionPlace =
                  actionPlace == null ? ActionPlaces.UNKNOWN : actionPlace;
              action.update(
                  new AnActionEvent(
                      null,
                      DataManager.getInstance().getDataContext(myComponent),
                      actualActionPlace,
                      presentation,
                      ActionManager.getInstance(),
                      0));
              ActionMenu.showDescriptionInStatusBar(
                  true, myComponent, presentation.getDescription());
            }
          });
    }
  @Nullable
  private ToolWindow getWindow(AnActionEvent event) {
    if (myWindow != null) return myWindow;

    Project project = CommonDataKeys.PROJECT.getData(event.getDataContext());
    if (project == null) return null;

    ToolWindowManager manager = ToolWindowManager.getInstance(project);

    final ToolWindow window = manager.getToolWindow(manager.getActiveToolWindowId());
    if (window == null) return null;

    final Component context = PlatformDataKeys.CONTEXT_COMPONENT.getData(event.getDataContext());
    if (context == null) return null;

    return SwingUtilities.isDescendingFrom(window.getComponent(), context) ? window : null;
  }
  /**
   * @return <code>true</code> if and only if the passed event is already dispatched by the <code>
   *     IdeMouseEventDispatcher</code> and there is no need for any other processing of the event.
   *     If the method returns <code>false</code> then it means that the event should be delivered
   *     to normal event dispatching.
   */
  public boolean dispatchMouseEvent(MouseEvent e) {
    Component c = e.getComponent();

    // frame activation by mouse click
    if (e.getID() == MOUSE_PRESSED && c instanceof IdeFrame && !c.hasFocus()) {
      IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance();
      if (focusManager instanceof FocusManagerImpl) {
        Component at = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY());
        if (at != null && at.isFocusable()) {
          ((FocusManagerImpl) focusManager).setLastFocusedAtDeactivation((IdeFrame) c, at);
        }
      }
    }

    if (SystemInfo.isXWindow && e.isPopupTrigger() && e.getButton() != 3) {
      // we can do better than silly triggering popup on everything but left click
      resetPopupTrigger(e);
    }

    boolean ignore = false;
    if (!(e.getID() == MouseEvent.MOUSE_PRESSED
        || e.getID() == MouseEvent.MOUSE_RELEASED
        || e.getID() == MOUSE_CLICKED)) {
      ignore = true;
    }

    patchClickCount(e);

    if (e.isConsumed()
        || e.isPopupTrigger()
        || (e.getButton() > 3 ? e.getID() != MOUSE_PRESSED : e.getID() != MOUSE_RELEASED)
        || e.getClickCount() < 1
        || e.getButton() == MouseEvent.NOBUTTON) { // See #16995. It did happen
      ignore = true;
    }

    int modifiers = e.getModifiers();
    int modifiersEx = e.getModifiersEx();
    if (e.getID() == MOUSE_PRESSED) {
      myPressedModifiersStored = true;
      myModifiers = modifiers;
      myModifiersEx = modifiersEx;
    } else if (e.getID() == MOUSE_RELEASED) {
      if (myPressedModifiersStored) {
        myPressedModifiersStored = false;
        modifiers = myModifiers;
        modifiersEx = myModifiersEx;
      }
    }

    final JRootPane root = findRoot(e);
    if (root != null) {
      BlockState blockState = myRootPane2BlockedId.get(root);
      if (blockState != null) {
        if (SWING_EVENTS_PRIORITY.indexOf(blockState.currentEventId)
            < SWING_EVENTS_PRIORITY.indexOf(e.getID())) {
          blockState.currentEventId = e.getID();
          if (blockState.blockMode == IdeEventQueue.BlockMode.COMPLETE) {
            return true;
          } else {
            ignore = true;
          }
        } else {
          myRootPane2BlockedId.remove(root);
        }
      }
    }

    if (c == null) {
      throw new IllegalStateException("component cannot be null");
    }
    c = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY());

    if (c instanceof IdeGlassPaneImpl) {
      c = ((IdeGlassPaneImpl) c).getTargetComponentFor(e);
    }

    if (c == null) { // do nothing if component doesn't contains specified point
      return false;
    }

    if (isHorizontalScrolling(c, e)) {
      boolean done = doHorizontalScrolling(c, (MouseWheelEvent) e);
      if (done) return true;
    }

    if (ignore) return false;

    // avoid "cyclic component initialization error" in case of dialogs shown because of component
    // initialization failure
    if (!KeymapManagerImpl.ourKeymapManagerInitialized) {
      return false;
    }

    final MouseShortcut shortcut = new MouseShortcut(e.getButton(), modifiersEx, e.getClickCount());
    fillActionsList(c, shortcut, IdeKeyEventDispatcher.isModalContext(c));
    ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
    if (actionManager != null) {
      AnAction[] actions = myActions.toArray(new AnAction[myActions.size()]);
      for (AnAction action : actions) {
        DataContext dataContext = DataManager.getInstance().getDataContext(c);
        Presentation presentation = myPresentationFactory.getPresentation(action);
        AnActionEvent actionEvent =
            new AnActionEvent(
                e,
                dataContext,
                ActionPlaces.MAIN_MENU,
                presentation,
                ActionManager.getInstance(),
                modifiers);
        action.beforeActionPerformedUpdate(actionEvent);

        if (presentation.isEnabled()) {
          actionManager.fireBeforeActionPerformed(action, dataContext, actionEvent);
          final Component context = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);

          if (context != null && !context.isShowing()) continue;

          action.actionPerformed(actionEvent);
          e.consume();
        }
      }
      if (actions.length > 0 && e.isConsumed()) return true;
    }
    return e.getButton() > 3;
  }