/**
  * Opens a url using the default browser.
  *
  * @param urlString String
  * @throws UnsupportedOperatingSystemException
  * @throws BrowserLaunchingExecutionException
  * @throws BrowserLaunchingInitializingException
  */
 public void openUrl(String urlString)
     throws UnsupportedOperatingSystemException, BrowserLaunchingExecutionException,
         BrowserLaunchingInitializingException {
   try {
     logger.info(urlString);
     String protocol = getProtocol(urlString);
     logger.info(protocol);
     // try the system prop first
     boolean successfullSystemPropLaunch = false;
     String browserName = System.getProperty(IBrowserLaunching.BROWSER_SYSTEM_PROPERTY, null);
     if (browserName != null) {
       Map browserMap = getBrowserMap();
       WindowsBrowser winBrowser = (WindowsBrowser) browserMap.get(browserName);
       if (winBrowser != null) {
         logger.debug("using browser from system property");
         successfullSystemPropLaunch = openUrlWithBrowser(winBrowser, protocol, urlString);
       }
     }
     if (!successfullSystemPropLaunch) {
       String[] args = getCommandArgs(protocol, urlString);
       if (logger.isDebugEnabled()) {
         logger.debug(getArrayAsString(args));
       }
       Process process = Runtime.getRuntime().exec(args);
       // This avoids a memory leak on some versions of Java on Windows.
       // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
       process.waitFor();
       process.exitValue();
     }
   } catch (Exception e) {
     logger.error("fatal exception", e);
     throw new BrowserLaunchingExecutionException(e);
   }
 }
 /**
  * Accesses the Windows registry to look for browser exes. The browsers search for are in the
  * browsersToCheck list. The returned map will use display names and exe names as keys to the
  * {@link WindowsBrowser WindowsBrowser} objects.
  *
  * @param browsersToCheck List
  * @return Map
  */
 private Map getAvailableBrowsers(List tempBrowsersToCheck) {
   logger.debug("finding available browsers using registry");
   logger.debug("browsers to check: " + tempBrowsersToCheck);
   Map browsersAvailable = new TreeMap(String.CASE_INSENSITIVE_ORDER);
   try {
     // create map of exe names to win browser objects
     Map exesToBrowserObjs = getExeNamesToBrowsers(tempBrowsersToCheck);
     // access and look in registry
     Regor regor = new Regor();
     String subKeyName = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths";
     int key = regor.openKey(Regor.HKEY_LOCAL_MACHINE, subKeyName);
     if (key > -1) {
       List keys = regor.listKeys(key);
       Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
       Iterator keysIter = exesToBrowserObjs.keySet().iterator();
       while (keysIter.hasNext()) {
         String exeKey = (String) keysIter.next();
         int index = Collections.binarySearch(keys, exeKey, String.CASE_INSENSITIVE_ORDER);
         if (index >= 0) {
           WindowsBrowser winBrowser =
               getBrowserFromRegistryEntry(
                   regor, key, (String) keys.get(index), exeKey, exesToBrowserObjs);
           if (winBrowser != null) {
             if (logger.isDebugEnabled()) {
               logger.debug(
                   "Adding browser " + winBrowser.getBrowserDisplayName() + " to available list.");
               logger.debug(winBrowser.getPathToExe());
             }
             // adding display and exe for backward compatibility and
             // ease of use if someone passes in the name of an exe
             browsersAvailable.put(winBrowser.getBrowserDisplayName(), winBrowser);
             browsersAvailable.put(winBrowser.getBrowserApplicationName(), winBrowser);
             tempBrowsersToCheck.remove(winBrowser);
           }
         }
       }
     }
   } catch (RegistryErrorException ex) {
     logger.error("problem accessing registry", ex);
   }
   return browsersAvailable;
 }
  /**
   * Returns true if the browser is available, ie mdfind command finds it.
   *
   * @param logger AbstractLogger
   * @return boolean
   */
  public boolean isBrowserAvailable(StandardUnixBrowser browser, AbstractLogger logger) {
    boolean isAvailable = false;
    try {
      Process process =
          Runtime.getRuntime().exec(new String[] {"mdfind", browser.getBrowserApplicationName()});
      InputStream errStream = process.getErrorStream();
      InputStream inStream = process.getInputStream();
      BufferedReader errIn = new BufferedReader(new InputStreamReader(errStream));
      BufferedReader in = new BufferedReader(new InputStreamReader(inStream));

      String temp;
      StringBuffer whichOutput = new StringBuffer();
      while ((temp = in.readLine()) != null) {
        // Searching with spotlight (mdfind) will find more than just the app sometimes
        if (temp.indexOf(browser.getBrowserApplicationName()) > -1) {
          whichOutput.append(temp);
        }
      }

      StringBuffer whichErrOutput = new StringBuffer();
      while ((temp = errIn.readLine()) != null) {
        whichErrOutput.append(temp);
      }

      in.close();
      errIn.close();
      if (whichOutput.length() > 0) {
        logger.debug(whichOutput.toString());
        // very weak test but should be enough since the Open -a applicationname works very well
        isAvailable = true;
      }
      if (whichErrOutput.length() > 0) {
        logger.debug(whichErrOutput.toString());
      }
    } catch (IOException ex) {
      logger.error("io error executing which command", ex);
    }
    return isAvailable;
  }