/**
   * Creates a new proximity node menu.
   *
   * @param parent Parent window used for dialogs.
   * @param graph Graph the proximity belong to.
   * @param node Clicked proximity node.
   */
  public CProximityNodeMenu(
      final JFrame parent, final ZyGraph graph, final ZyProximityNode<INaviViewNode> node) {
    Preconditions.checkNotNull(parent, "IE02150: Parent argument can not be null");

    Preconditions.checkNotNull(graph, "IE00972: Graph argument can't be null");

    Preconditions.checkNotNull(node, "IE00973: Node argument can't be null");

    add(CActionProxy.proxy(new CUnhideNodesAction(parent, graph, node)));

    addSeparator();

    final JMenuItem unhideParentItem =
        new JMenuItem(CActionProxy.proxy(new CUnhideParentsAction(parent, graph, node)));
    unhideParentItem.setEnabled(!node.isIncoming());
    add(unhideParentItem);

    final JMenuItem unhideChildrenItem =
        new JMenuItem(CActionProxy.proxy(new CUnhideChildrenAction(parent, graph, node)));
    unhideChildrenItem.setEnabled(node.isIncoming());
    add(unhideChildrenItem);

    addSeparator();

    add(CActionProxy.proxy(new CUnhideAndSelectAction(graph, node)));
    add(CActionProxy.proxy(new CUnhideAndAddToSelectionAction(graph, node)));
  }
  /**
   * Creates the BinNavi menu.
   *
   * @return The created menu.
   */
  private JMenu createBinNaviMenu() {
    // TODO: Rename to "File" for consistency with other applications?
    final JMenu menu = new JMenu("BinNavi");

    menu.setMnemonic('B');

    menu.add(CActionProxy.proxy(new CAddDatabaseAction(m_projectTree)));
    menu.addSeparator();
    menu.add(CActionProxy.proxy(new CActionExit(getParent())));

    return menu;
  }
  /**
   * Creates a new table menu object.
   *
   * @param parent Parent window used for dialogs.
   * @param debugger The debugger used to manipulate the thread.
   * @param thread The clicked thread.
   */
  public CThreadInformationTableMenu(
      final Window parent, final IDebugger debugger, final TargetProcessThread thread) {
    Preconditions.checkNotNull(parent, "IE00648: Parent argument can not be null");

    Preconditions.checkNotNull(thread, "IE00650: Thread argument can not be null");

    if (debugger != null) {
      if (thread.getState() == ThreadState.RUNNING) {
        add(CActionProxy.proxy(new CSuspendThreadAction(thread)));
      } else {
        add(CActionProxy.proxy(new CResumeThreadAction(thread)));
      }
    }
  }
  /**
   * Creates the plugin menu.
   *
   * @return The created menu.
   */
  private JMenu createPluginsMenu() {
    final List<IMainWindowMenuPlugin> plugins = new ArrayList<IMainWindowMenuPlugin>();

    for (@SuppressWarnings("rawtypes")
    final IPlugin plugin : PluginInterface.instance().getPluginRegistry()) {
      if (plugin instanceof IMainWindowMenuPlugin) {
        plugins.add((IMainWindowMenuPlugin) plugin);
      }
    }

    final JMenu menu = new JMenu("Plugins");
    menu.setMnemonic('U');

    menu.add(CActionProxy.proxy(new CActionOpenScriptingDialog(getParent())));
    menu.add(CActionProxy.proxy(new CActionOpenLogConsole()));
    menu.addSeparator();
    menu.add(CActionProxy.proxy(new CPluginManagementAction(getParent())));
    menu.add(CActionProxy.proxy(new CPluginsReloadAction()));
    menu.addSeparator();

    for (final IMainWindowMenuPlugin plugin : plugins) {
      // ESCA-JAVA0166: Catch Exception because we are calling a plugin function.
      try {
        final List<JMenuItem> menus = plugin.extendPluginMenu();

        for (final JMenuItem m : menus) {
          menu.add(m);
        }
      } catch (final Exception exception) {
        CUtilityFunctions.logException(exception);

        final String innerMessage = "E00092: " + "Plugin caused an unexpected exception";
        final String innerDescription =
            CUtilityFunctions.createDescription(
                String.format("The plugin %s caused an unexpected exception.", plugin.getName()),
                new String[] {"The plugin contains a bug."},
                new String[] {
                  "The plugin probably behaves erroneously from this point on but it remains active"
                });

        NaviErrorDialog.show(getParent(), innerMessage, innerDescription, exception);
      }
    }

    return menu;
  }
  @Override
  protected void createMenu(final JComponent menu) {
    menu.add(
        new JMenuItem(
            CActionProxy.proxy(
                new CCreateProjectAction(
                    getParent(),
                    database,
                    new CNodeSelectionUpdater(getProjectTree(), findNode())))));

    final List<IProjectFolderMenuPlugin> plugins = new ArrayList<IProjectFolderMenuPlugin>();

    for (final IPlugin<IPluginInterface> plugin : PluginInterface.instance().getPluginRegistry()) {
      if (plugin instanceof IProjectFolderMenuPlugin) {
        plugins.add((IProjectFolderMenuPlugin) plugin);
      }
    }

    if (!plugins.isEmpty()) {
      menu.add(new JSeparator());

      for (final IProjectFolderMenuPlugin plugin : plugins) {
        try {
          final List<JComponent> menuItems = plugin.extendProjectFolderMenu(getPluginDatabase());

          if (menuItems != null) {
            for (final JComponent menuItem : menuItems) {
              menu.add(menuItem);
            }
          }
        } catch (final Exception exception) {
          CUtilityFunctions.logException(exception);

          final String innerMessage = "E00089: " + "Plugin caused an unexpected exception";
          final String innerDescription =
              CUtilityFunctions.createDescription(
                  String.format("The plugin %s caused an unexpected exception.", plugin.getName()),
                  new String[] {"The plugin contains a bug."},
                  new String[] {
                    "The plugin probably behaves erroneously from this point on but it remains active"
                  });

          CNaviErrorDialog.show(getParent(), innerMessage, innerDescription, exception);
        }
      }
    }
  }