protected static void start() throws Exception {
    agent = new SSHAgent();

    if (agent.isCreatedCorrectly()) {

      File settingsFile =
          new File(
              System.getProperty("user.home") + File.separator + AgentConstants.SETTINGS_FILE_NAME);

      if (!settingsFile.exists()) {
        try {
          settings = AgentUtils.initSettingsFile(settingsFile); // create default settings file
          Logger.getLogger(TrayProcess.class.getName())
              .log(
                  Level.INFO,
                  "New settings file created: {0}",
                  new Object[] {settingsFile.getPath()});
        } catch (Exception ex) {
          TrayProcess.createError(
              LocalizedLogger.getLocalizedMessage(
                  "INIT_SETTINGS_FILE_ERROR", ex.getLocalizedMessage()),
              false,
              ex);
          // Logger.getLogger(TrayProcess.class.getName()).log(Level.SEVERE, null, ex);
        }
      } else {
        settings = new Properties();
        try (FileInputStream fileIn = new FileInputStream(settingsFile)) {
          settings.load(fileIn);
        }
        Logger.getLogger(TrayProcess.class.getName())
            .log(
                Level.INFO,
                "Existing settings file loaded: {0}",
                new Object[] {settingsFile.getPath()});
      }

      // start device USB service depending on device type
      String deviceTypeProperty =
          AgentUtils.readSetting(
              settings, AgentConstants.SETTINGS_KEY_DEVICE, AgentConstants.TREZOR_LABEL);
      switch (deviceTypeProperty.toLowerCase()) {
        case (AgentConstants.SETTINGS_KEEPKEY_DEVICE):
          deviceType = AgentConstants.KEEPKEY_LABEL;
          deviceService = KeepKeyService.startKeepKeyService();
          break;
        default:
          deviceType = AgentConstants.TREZOR_LABEL;
          deviceService = TrezorService.startTrezorService();
      }

      initSessionTimer(); // start timer to control session (PIN+Passphrase) expiration

      SwingUtilities.invokeLater(
          new Runnable() { // start GUI
            @Override
            public void run() {
              TrayProcess.createAndShowGUI();
            }
          });

      agent.startMainLoop(); // start SSH Agent emulating Pageant and listening Windows requests
    }
  }
  private static void createAndShowGUI() {
    if (!SystemTray.isSupported()) {
      Logger.getLogger(StartAgentGUI.class.getName()).log(Level.SEVERE, "SYSTRAY_NOT_SUPPORTED");
      agent.exitProcess();
      return;
    }

    trayIcon =
        new TrayIcon(
            TrayProcess.createImage(AgentConstants.ICON16_PATH, AgentConstants.ICON_DESCRIPTION),
            AgentConstants.APP_PUBLIC_NAME);
    final SystemTray tray = SystemTray.getSystemTray();
    final AgentPopUpMenu popUpMenu = new AgentPopUpMenu(tray, trayIcon, agent, deviceService);

    MOUSE_HOOK = new JNIMouseHook(popUpMenu);
    trayIcon.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
              popUpMenu.setLocation(e.getX(), e.getY());
              popUpMenu.setInvoker(popUpMenu);
              popUpMenu.setVisible(true);
            }
          }
        });

    popUpMenu.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            if (e instanceof MouseClickOutsideComponentEvent) {
              popUpMenu.setVisible(false);
            }
          }
        });

    popUpMenu.addPropertyChangeListener(
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals(VISIBLE_PROPERTY)) {
              if (evt.getNewValue().equals(Boolean.TRUE)) {
                if (!MOUSE_HOOK.isIsHooked()) {
                  MOUSE_HOOK.setMouseHook();
                }
              } else if (MOUSE_HOOK.isIsHooked()) {
                MOUSE_HOOK.unsetMouseHook();
              }
            }
          }
        });

    try {
      tray.add(trayIcon);
    } catch (AWTException e) {
      Logger.getLogger(StartAgentGUI.class.getName()).log(Level.SEVERE, "TRAY_ICON_LOAD_ERROR", e);
      return;
    }
    trayIcon.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(
                null,
                LocalizedLogger.getLocalizedMessage("APPLICATION_INFO", AgentConstants.VERSION));
          }
        });
  }