@Nullable
 public static KeyStroke getKeyStroke(@NotNull final ShortcutSet shortcutSet) {
   final Shortcut[] shortcuts = shortcutSet.getShortcuts();
   if (shortcuts.length == 0 || !(shortcuts[0] instanceof KeyboardShortcut)) return null;
   final KeyboardShortcut shortcut = (KeyboardShortcut) shortcuts[0];
   if (shortcut.getSecondKeyStroke() != null) {
     return null;
   }
   return shortcut.getFirstKeyStroke();
 }
 private ArrayList<Pair<AnAction, KeyStroke>> getSecondKeystrokeActions() {
   ArrayList<Pair<AnAction, KeyStroke>> secondKeyStrokes =
       new ArrayList<Pair<AnAction, KeyStroke>>();
   for (AnAction action : myContext.getActions()) {
     Shortcut[] shortcuts = action.getShortcutSet().getShortcuts();
     for (Shortcut shortcut : shortcuts) {
       if (shortcut instanceof KeyboardShortcut) {
         KeyboardShortcut keyShortcut = (KeyboardShortcut) shortcut;
         if (keyShortcut.getFirstKeyStroke().equals(myFirstKeyStroke)) {
           secondKeyStrokes.add(
               new Pair<AnAction, KeyStroke>(action, keyShortcut.getSecondKeyStroke()));
         }
       }
     }
   }
   return secondKeyStrokes;
 }
  private int getMnemonicCharIndex(String text) {
    final int mnemonicIndex = myPresentation.getDisplayedMnemonicIndex();
    if (mnemonicIndex != -1) {
      return mnemonicIndex;
    }
    final ShortcutSet shortcutSet = myAction.getShortcutSet();
    final Shortcut[] shortcuts = shortcutSet.getShortcuts();
    for (Shortcut shortcut : shortcuts) {
      if (!(shortcut instanceof KeyboardShortcut)) continue;

      KeyboardShortcut keyboardShortcut = (KeyboardShortcut) shortcut;
      if (keyboardShortcut.getSecondKeyStroke()
          == null) { // we are interested only in "mnemonic-like" shortcuts
        final KeyStroke keyStroke = keyboardShortcut.getFirstKeyStroke();
        final int modifiers = keyStroke.getModifiers();
        if (BitUtil.isSet(modifiers, InputEvent.ALT_MASK)) {
          return (keyStroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED)
              ? text.indexOf(keyStroke.getKeyChar())
              : text.indexOf(KeyEvent.getKeyText(keyStroke.getKeyCode()));
        }
      }
    }
    return -1;
  }
  public static String getShortcutText(@NotNull Shortcut shortcut) {
    String s = "";

    if (shortcut instanceof KeyboardShortcut) {
      KeyboardShortcut keyboardShortcut = (KeyboardShortcut) shortcut;

      String acceleratorText = getKeystrokeText(keyboardShortcut.getFirstKeyStroke());
      if (!acceleratorText.isEmpty()) {
        s = acceleratorText;
      }

      acceleratorText = getKeystrokeText(keyboardShortcut.getSecondKeyStroke());
      if (!acceleratorText.isEmpty()) {
        s += ", " + acceleratorText;
      }
    } else if (shortcut instanceof MouseShortcut) {
      MouseShortcut mouseShortcut = (MouseShortcut) shortcut;
      s =
          getMouseShortcutText(
              mouseShortcut.getButton(),
              mouseShortcut.getModifiers(),
              mouseShortcut.getClickCount());
    } else if (shortcut instanceof KeyboardModifierGestureShortcut) {
      final KeyboardModifierGestureShortcut gestureShortcut =
          (KeyboardModifierGestureShortcut) shortcut;
      s =
          gestureShortcut.getType() == KeyboardGestureAction.ModifierType.dblClick
              ? "Press, release and hold "
              : "Hold ";
      s += getKeystrokeText(gestureShortcut.getStroke());
    } else {
      throw new IllegalArgumentException(
          "unknown shortcut class: " + shortcut.getClass().getCanonicalName());
    }
    return s;
  }
  /**
   * This method fills <code>myActions</code> list.
   *
   * @return true if there is a shortcut with second stroke found.
   */
  public KeyProcessorContext updateCurrentContext(
      Component component, Shortcut sc, boolean isModalContext) {
    myContext.setFoundComponent(null);
    myContext.getActions().clear();

    if (isControlEnterOnDialog(component, sc)) return myContext;

    boolean hasSecondStroke = false;

    // here we try to find "local" shortcuts

    for (; component != null; component = component.getParent()) {
      if (!(component instanceof JComponent)) {
        continue;
      }
      ArrayList listOfActions =
          (ArrayList) ((JComponent) component).getClientProperty(AnAction.ourClientProperty);
      if (listOfActions == null) {
        continue;
      }
      for (Object listOfAction : listOfActions) {
        if (!(listOfAction instanceof AnAction)) {
          continue;
        }
        AnAction action = (AnAction) listOfAction;
        hasSecondStroke |= addAction(action, sc);
      }
      // once we've found a proper local shortcut(s), we continue with non-local shortcuts
      if (!myContext.getActions().isEmpty()) {
        myContext.setFoundComponent((JComponent) component);
        break;
      }
    }

    // search in main keymap

    Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
    String[] actionIds = keymap.getActionIds(sc);

    ActionManager actionManager = ActionManager.getInstance();
    for (String actionId : actionIds) {
      AnAction action = actionManager.getAction(actionId);
      if (action != null) {
        if (isModalContext && !action.isEnabledInModalContext()) {
          continue;
        }
        hasSecondStroke |= addAction(action, sc);
      }
    }

    if (!hasSecondStroke && sc instanceof KeyboardShortcut) {
      // little trick to invoke action which second stroke is a key w/o modifiers, but user still
      // holds the modifier key(s) of the first stroke

      final KeyboardShortcut keyboardShortcut = (KeyboardShortcut) sc;
      final KeyStroke firstKeyStroke = keyboardShortcut.getFirstKeyStroke();
      final KeyStroke secondKeyStroke = keyboardShortcut.getSecondKeyStroke();

      if (secondKeyStroke != null
          && secondKeyStroke.getModifiers() != 0
          && firstKeyStroke.getModifiers() != 0) {
        final KeyboardShortcut altShortCut =
            new KeyboardShortcut(
                firstKeyStroke, KeyStroke.getKeyStroke(secondKeyStroke.getKeyCode(), 0));
        final String[] additionalActions = keymap.getActionIds(altShortCut);

        for (final String actionId : additionalActions) {
          AnAction action = actionManager.getAction(actionId);
          if (action != null) {
            if (isModalContext && !action.isEnabledInModalContext()) {
              continue;
            }
            hasSecondStroke |= addAction(action, altShortCut);
          }
        }
      }
    }

    myContext.setHasSecondStroke(hasSecondStroke);

    Comparator<? super AnAction> comparator =
        PlatformDataKeys.ACTIONS_SORTER.getData(myContext.getDataContext());
    if (comparator != null) {
      Collections.sort(myContext.getActions(), comparator);
    }

    return myContext;
  }