@Override
  public void init(ResourceLoader rl, Object... params) throws Exception {
    this.rl = rl;
    core = (CoreSubsystem) params[0];
    initTray();
    core.addUICallback(
        new UICallback() {

          @Override
          public void firstDownloadEverFinished() {}

          @Override
          public void callbackRemoved() {}

          public void signalFileDatabaseFlushStarting() {}

          public void signalFileDatabaseFlushComplete() {}

          @Override
          public void nodeOrSubnodesUpdated(Node node) {}

          @Override
          public void noRouteToHost(Node node) {}

          @Override
          public void pluginCommunicationReceived(Friend source, String data) {}

          @Override
          public void searchHits(int srcGuid, int hops, List<SearchHit> hits) {}

          @Override
          public void trace(int level, String message, Exception stackTrace) {}

          @Override
          public void statusMessage(String s) {}

          @Override
          public void statusMessage(String s, boolean b) {}

          @Override
          public void toFront() {}

          @Override
          public void signalFriendAdded(Friend friend) {}

          @Override
          public boolean isUIVisible() {
            return false;
          }

          @Override
          public void logNetworkEvent(String event) {}

          @Override
          public void receivedShareBaseList(Friend friend, String[] shareBaseNames) {}

          @Override
          public void receivedDirectoryListing(
              Friend friend, int i, String s, TreeMap<String, Long> fileSize) {}

          @Override
          public void newUserInteractionQueued(NeedsUserInteraction ui) {
            if (ui instanceof PostMessageInteraction) {
              PostMessageInteraction pmi = (PostMessageInteraction) ui;
              String msg = pmi.getMessage().replaceAll("\\<.*?\\>", ""); // Strip html
              if (pmi instanceof PostMessageToAllInteraction) {
                if (core.getSettings().getInternal().getShowpublicchatmessagesintray() != 0) {
                  ti.displayMessage(
                      Language.getLocalizedString(getClass(), "chatnew"),
                      core.getFriendManager().nickname(pmi.getFromGuid()) + ": " + msg,
                      TrayIcon.MessageType.INFO);
                }
              } else {
                if (core.getSettings().getInternal().getShowprivatechatmessagesintray() != 0) {
                  ti.displayMessage(
                      Language.getLocalizedString(getClass(), "privatenew"),
                      core.getFriendManager().nickname(pmi.getFromGuid()) + ": " + msg,
                      TrayIcon.MessageType.INFO);
                }
              }
            } else {
              if (core.getSettings().getInternal().getShowsystemmessagesintray() != 0) {
                ti.displayMessage(
                    Language.getLocalizedString(getClass(), "attentionheader"),
                    Language.getLocalizedString(getClass(), "attention"),
                    TrayIcon.MessageType.INFO);
              }
            }
            balloonClickHandler =
                new Runnable() {

                  @Override
                  public void run() {
                    openUI();
                  }
                };
          }

          @Override
          public void handleError(final Throwable e, final Object source) {
            ti.displayMessage(
                e.getClass().getName(), e + "\n" + source, TrayIcon.MessageType.ERROR);
            e.printStackTrace();
            balloonClickHandler =
                new Runnable() {

                  @Override
                  public void run() {
                    try {
                      e.printStackTrace();
                      // report error. Use reflection to init dialogs because we want NO references
                      // to UI stuff in this
                      // class - we want this class to load fast (ie load minimal amount of classes)
                      Object errorDialog =
                          Class.forName("org.alliance.ui.dialogs.ErrorDialog").newInstance();
                      Method m =
                          errorDialog.getClass().getMethod("init", Throwable.class, boolean.class);
                      m.invoke(errorDialog, e, false);
                    } catch (Throwable t) {
                      t.printStackTrace();
                    }
                  }
                };
          }
        });
  }