/**
   * Creates a new scripting dialog.
   *
   * @param owner Parent window of the dialog.
   * @param defaultLanguage Scripting language selected by default when a new scripting panel is
   *     opened.
   * @param pluginInterface Plugin interface that makes the BinNavi API accessible for the scripts.
   * @param bindings Additional object bindings passed to the scripts.
   */
  public CScriptingDialog(
      final Frame owner,
      final String defaultLanguage,
      final PluginInterface pluginInterface,
      final Map<String, Object> bindings) {
    super(owner, "Scripting", false);

    this.defaultLanguage = defaultLanguage;
    scriptsDirectory = PluginInterface.instance().getProgramPath() + File.separator + "scripts";

    addBinding("navi", pluginInterface);
    addBinding("dbs", pluginInterface.getDatabaseManager());

    for (final Entry<String, Object> binding : bindings.entrySet()) {
      addBinding(binding.getKey(), binding.getValue());
    }

    setLayout(new BorderLayout());
    menuBar = new MenuBar();
    setJMenuBar(menuBar);
    scriptTab.addChangeListener(new InternalChangeListener());
    final ConsolePane initialPanel = new ConsolePane();
    initPanel(initialPanel);
    scriptTab.addTab("Console", initialPanel);
    add(scriptTab, BorderLayout.CENTER);
    setResizable(true);
    pack();
  }
  @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);
        }
      }
    }
  }
  /**
   * 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;
  }
 /**
  * Finds the API database object that represents a given database object.
  *
  * @return The API database object.
  */
 private Database getPluginDatabase() {
   return ObjectFinders.getObject(
       database, PluginInterface.instance().getDatabaseManager().getDatabases());
 }