protected void fireInitComplete(PluginListener listener) {
    synchronized (init_complete_fired_set) {
      if (init_complete_fired_set.contains(listener)) {

        return;
      }

      init_complete_fired_set.add(listener);
    }

    try {
      listener.initializationComplete();
    } catch (Exception e) {
      Debug.out(e);
    }
  }
  protected void closedownComplete() {
    Iterator it = listeners.iterator();

    while (it.hasNext()) {

      try {
        ((PluginListener) it.next()).closedownComplete();

      } catch (Throwable e) {

        Debug.printStackTrace(e);
      }
    }

    for (int i = 0; i < children.size(); i++) {

      ((PluginInterfaceImpl) children.get(i)).closedownComplete();
    }
  }
  protected void initialisationComplete() {
    Iterator<PluginListener> it = listeners.iterator();

    while (it.hasNext()) {

      try {
        fireInitComplete(it.next());

      } catch (Throwable e) {

        Debug.printStackTrace(e);
      }
    }

    for (int i = 0; i < children.size(); i++) {

      ((PluginInterfaceImpl) children.get(i)).initialisationComplete();
    }
  }
  protected void firePluginEventSupport(PluginEvent event) {
    Iterator<PluginEventListener> it = event_listeners.iterator();

    while (it.hasNext()) {

      try {
        PluginEventListener listener = it.next();

        listener.handleEvent(event);

      } catch (Throwable e) {

        Debug.printStackTrace(e);
      }
    }

    for (int i = 0; i < children.size(); i++) {

      ((PluginInterfaceImpl) children.get(i)).firePluginEvent(event);
    }
  }
  protected void generateEvidence(IndentWriter writer) {
    writer.println(getPluginName());

    try {
      writer.indent();

      writer.println("id:" + getPluginID() + ",version:" + getPluginVersion());

      String user_dir = FileUtil.getUserFile("plugins").toString();
      String shared_dir = FileUtil.getApplicationFile("plugins").toString();

      String plugin_dir = getPluginDirectoryName();

      String type;
      boolean built_in = false;

      if (plugin_dir.startsWith(shared_dir)) {

        type = "shared";

      } else if (plugin_dir.startsWith(user_dir)) {

        type = "per-user";

      } else {

        built_in = true;

        type = "built-in";
      }

      PluginState ps = getPluginState();

      String info = getPluginconfig().getPluginStringParameter("plugin.info");

      writer.println(
          "type:"
              + type
              + ",enabled="
              + !ps.isDisabled()
              + ",load_at_start="
              + ps.isLoadedAtStartup()
              + ",operational="
              + ps.isOperational()
              + (info == null || info.length() == 0 ? "" : (",info=" + info)));

      if (ps.isOperational()) {

        Plugin plugin = getPlugin();

        if (plugin instanceof AEDiagnosticsEvidenceGenerator) {

          try {
            writer.indent();

            ((AEDiagnosticsEvidenceGenerator) plugin).generate(writer);

          } catch (Throwable e) {

            writer.println(
                "Failed to generate plugin-specific info: " + Debug.getNestedExceptionMessage(e));

          } finally {

            writer.exdent();
          }
        }
      } else {
        if (!built_in) {

          File dir = new File(plugin_dir);

          if (dir.exists()) {

            String[] files = dir.list();

            if (files != null) {

              String files_str = "";

              for (String f : files) {

                files_str += (files_str.length() == 0 ? "" : ", ") + f;
              }

              writer.println("    files: " + files_str);
            }
          }
        }
      }
    } finally {

      writer.exdent();
    }
  }