static synchronized void initializeSwing() {
   if (swingInitialized) return;
   swingInitialized = true;
   /*
    * Feature in GTK.  The default X error handler
    * for GTK calls exit() after printing the X error.
    * Normally, this isn't that big a problem for SWT
    * applications because they don't cause X errors.
    * However, sometimes X errors are generated by AWT
    * that make SWT exit.  The fix is to hide all X
    * errors when AWT is running.
    */
   OS.gdk_error_trap_push();
   try {
     /* Initialize the default focus traversal policy */
     Class[] emptyClass = new Class[0];
     Object[] emptyObject = new Object[0];
     Class clazz = Class.forName("javax.swing.UIManager");
     Method method = clazz.getMethod("getDefaults", emptyClass);
     if (method != null) method.invoke(clazz, emptyObject);
   } catch (Throwable e) {
   }
 }
  /** Create tray icon and register frame listeners. */
  public void init() {
    // register error handler to avoid application crash on concurrent X access from SWT and AWT
    try {
      OS.gdk_error_trap_push();
    } catch (NoClassDefFoundError e) {
      // ignore
    }
    final String systemLookAndFeelClassName = UIManager.getSystemLookAndFeelClassName();
    try {
      // workaround for bug when SWT and AWT both try to access Gtk
      if (systemLookAndFeelClassName.indexOf("gtk") >= 0) {
        System.setProperty("swing.defaultlaf", UIManager.getCrossPlatformLookAndFeelClassName());
      } else {
        System.setProperty("swing.defaultlaf", systemLookAndFeelClassName);
      }
    } catch (Exception e) {
      DavGatewayTray.warn(new BundleMessage("LOG_UNABLE_TO_SET_LOOK_AND_FEEL"));
    }

    new Thread("SWT") {
      @Override
      public void run() {
        try {
          display = new Display();
          shell = new Shell(display);

          final Tray tray = display.getSystemTray();
          if (tray != null) {

            trayItem = new TrayItem(tray, SWT.NONE);
            trayItem.setToolTipText(BundleMessage.format("UI_DAVMAIL_GATEWAY"));

            awtImage = DavGatewayTray.loadImage(AwtGatewayTray.TRAY_PNG);
            image = loadSwtImage(AwtGatewayTray.TRAY_PNG);
            image2 = loadSwtImage(AwtGatewayTray.TRAY_ACTIVE_PNG);
            inactiveImage = loadSwtImage(AwtGatewayTray.TRAY_INACTIVE_PNG);

            trayItem.setImage(image);

            // create a popup menu
            final Menu popup = new Menu(shell, SWT.POP_UP);
            trayItem.addListener(
                SWT.MenuDetect,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            popup.setVisible(true);
                          }
                        });
                  }
                });

            MenuItem aboutItem = new MenuItem(popup, SWT.PUSH);
            aboutItem.setText(BundleMessage.format("UI_ABOUT"));
            aboutItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            if (aboutFrame == null) {
                              aboutFrame = new AboutFrame();
                            }
                            aboutFrame.update();
                            aboutFrame.setVisible(true);
                            aboutFrame.toFront();
                            aboutFrame.requestFocus();
                          }
                        });
                  }
                });

            trayItem.addListener(
                SWT.DefaultSelection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            // create frame on first call
                            if (settingsFrame == null) {
                              settingsFrame = new SettingsFrame();
                            }
                            settingsFrame.reload();
                            settingsFrame.setVisible(true);
                            settingsFrame.toFront();
                            settingsFrame.requestFocus();
                          }
                        });
                  }
                });

            // create menu item for the default action
            MenuItem defaultItem = new MenuItem(popup, SWT.PUSH);
            defaultItem.setText(BundleMessage.format("UI_SETTINGS"));
            defaultItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            // create frame on first call
                            if (settingsFrame == null) {
                              settingsFrame = new SettingsFrame();
                            }
                            settingsFrame.reload();
                            settingsFrame.setVisible(true);
                            settingsFrame.toFront();
                            settingsFrame.requestFocus();
                          }
                        });
                  }
                });

            MenuItem logItem = new MenuItem(popup, SWT.PUSH);
            logItem.setText(BundleMessage.format("UI_SHOW_LOGS"));
            logItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {

                            Logger rootLogger = Logger.getRootLogger();
                            LF5Appender lf5Appender =
                                (LF5Appender) rootLogger.getAppender("LF5Appender");
                            if (lf5Appender == null) {
                              logBrokerMonitor =
                                  new LogBrokerMonitor(LogLevel.getLog4JLevels()) {
                                    @Override
                                    protected void closeAfterConfirm() {
                                      hide();
                                    }
                                  };
                              lf5Appender = new LF5Appender(logBrokerMonitor);
                              lf5Appender.setName("LF5Appender");
                              rootLogger.addAppender(lf5Appender);
                            }
                            lf5Appender.getLogBrokerMonitor().show();
                          }
                        });
                  }
                });

            MenuItem exitItem = new MenuItem(popup, SWT.PUSH);
            exitItem.setText(BundleMessage.format("UI_EXIT"));
            exitItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    DavGateway.stop();
                  }
                });

            // display settings frame on first start
            if (Settings.isFirstStart()) {
              // create frame on first call
              if (settingsFrame == null) {
                settingsFrame = new SettingsFrame();
              }
              settingsFrame.setVisible(true);
              settingsFrame.toFront();
              settingsFrame.requestFocus();
            }

            synchronized (mainThread) {
              // ready
              isReady = true;
              mainThread.notifyAll();
            }

            while (!shell.isDisposed()) {
              if (!display.readAndDispatch()) {
                display.sleep();
              }
            }

            dispose();
          }
        } catch (Exception exc) {
          DavGatewayTray.error(exc);
        }
        // make sure we do exit
        System.exit(0);
      }
    }.start();
    while (true) {
      // wait for SWT init
      try {
        synchronized (mainThread) {
          if (isReady) {
            break;
          }
          mainThread.wait(1000);
        }
      } catch (InterruptedException e) {
        DavGatewayTray.error(new BundleMessage("LOG_ERROR_WAITING_FOR_SWT_INIT"), e);
      }
    }
  }