@Override
 public void addUpdate(final Map<String, Object> data) {
   LOG.info("Adding update data: {}", data);
   if (this.updateData != null && this.updateData.equals(data)) {
     LOG.info("Ignoring duplicate update data");
     return;
   }
   this.updateData = data;
   final String label =
       I18n.tr("Update to Lantern ") + data.get(LanternConstants.UPDATE_VERSION_KEY);
   updateItem = libgtk.gtk_menu_item_new_with_label(label);
   updateItemCallback =
       new Gobject.GCallback() {
         @Override
         public void callback(Pointer instance, Pointer pointer) {
           LOG.debug("updateItemCallback called");
           NativeUtils.openUri((String) data.get(LanternConstants.UPDATE_URL_KEY));
         }
       };
   libgobject.g_signal_connect_data(updateItem, "activate", updateItemCallback, null, null, 0);
   libgtk.gtk_menu_shell_append(menu, updateItem);
   libgtk.gtk_widget_show_all(updateItem);
 }
  @Override
  public void createTray() {

    /*uniqueApp = libunique.unique_app_new("org.lantern.lantern", null);
    if (libunique.unique_app_is_running(uniqueApp)) {
        LOG.error("Already running!");
        System.exit(0);
        // could signal to open dashboard
    }*/

    menu = libgtk.gtk_menu_new();

    connectionStatusItem = libgtk.gtk_menu_item_new_with_label(LABEL_DISCONNECTED);
    libgtk.gtk_widget_set_sensitive(connectionStatusItem, Gtk.FALSE);
    libgtk.gtk_menu_shell_append(menu, connectionStatusItem);
    libgtk.gtk_widget_show_all(connectionStatusItem);

    dashboardItem = libgtk.gtk_menu_item_new_with_label("Open Dashboard");
    dashboardItemCallback =
        new Gobject.GCallback() {
          @Override
          public void callback(Pointer instance, Pointer data) {
            LOG.debug("openDashboardItem callback called");
            openDashboard();
          }
        };
    libgobject.g_signal_connect_data(
        dashboardItem, "activate", dashboardItemCallback, null, null, 0);
    libgtk.gtk_menu_shell_append(menu, dashboardItem);
    libgtk.gtk_widget_show_all(dashboardItem);

    // updateItem = Gtk.gtk_menu_item_new_with_label();

    quitItem = libgtk.gtk_menu_item_new_with_label("Quit");
    quitItemCallback =
        new Gobject.GCallback() {
          @Override
          public void callback(Pointer instance, Pointer data) {
            LOG.debug("quitItemCallback called");
            quit();
          }
        };
    libgobject.g_signal_connect_data(quitItem, "activate", quitItemCallback, null, null, 0);
    libgtk.gtk_menu_shell_append(menu, quitItem);
    libgtk.gtk_widget_show_all(quitItem);

    appIndicator =
        libappindicator.app_indicator_new(
            "lantern", "indicator-messages-new", AppIndicator.CATEGORY_APPLICATION_STATUS);

    /* XXX basically a hack -- we should subclass the AppIndicator
       type and override the fallback entry in the 'vtable', instead we just
       hack the app indicator class itself. Not an issue unless we need other
       appindicators.
    */
    AppIndicator.AppIndicatorClassStruct aiclass =
        new AppIndicator.AppIndicatorClassStruct(appIndicator.parent.g_type_instance.g_class);

    AppIndicator.Fallback replacementFallback =
        new AppIndicator.Fallback() {
          @Override
          public Pointer callback(final AppIndicator.AppIndicatorInstanceStruct self) {
            fallback();
            return null;
          }
        };

    aiclass.fallback = replacementFallback;
    aiclass.write();

    libappindicator.app_indicator_set_menu(appIndicator, menu);

    changeIcon(ICON_DISCONNECTED, LABEL_DISCONNECTED);
    libappindicator.app_indicator_set_status(appIndicator, AppIndicator.STATUS_ACTIVE);

    Events.register(this);
    this.active = true;
  }