/**
  * 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 the windows arguments for launching a specified browser.
  *
  * <p>Depending on the forceNewWindow boolean, the args may also contain the args to force a new
  * window.
  *
  * @param protocol String
  * @param winbrowser WindowsBrowser
  * @param urlString String
  * @param forceNewWindow boolean
  * @return String[]
  */
 private String getCommandArgs(
     String protocol, WindowsBrowser winbrowser, String urlString, boolean forceNewWindow) {
   String commandArgs =
       LaunchingUtils.replaceArgs(
           commandsTargettedBrowser, winbrowser.getBrowserApplicationName(), urlString);
   String args = "";
   if (forceNewWindow) {
     args = winbrowser.getForceNewWindowArgs();
   }
   commandArgs = commandArgs.replaceAll("<args>", args);
   int pathLoc = commandArgs.indexOf("<path>");
   if (pathLoc > 0) {
     StringBuffer buf = new StringBuffer();
     buf.append(commandArgs.substring(0, pathLoc));
     buf.append(winbrowser.getPathToExe());
     buf.append(commandArgs.substring(pathLoc + 6));
     commandArgs = buf.toString();
   }
   return commandArgs; // .split("[ ]");
 }
 /**
  * Secondary method for browser discovery.
  *
  * <p>Uses IE to get the path to the Program Files directory; then gets a list of the sub dirs and
  * checks them against the remaining browsers.
  *
  * @param iePath String
  * @param browsersAvailable Map
  * @param tmpBrowsersToCheck List
  */
 private Map processFilePathsForBrowsers(List tmpBrowsersToCheck) {
   logger.debug("finding available browsers in program files path");
   logger.debug("browsers to check: " + tmpBrowsersToCheck);
   Map browsersAvailable = new HashMap();
   File progFilesPath = getProgramFilesPath();
   if (progFilesPath != null) {
     logger.debug("program files path: " + progFilesPath.getPath());
     File[] subDirs = progFilesPath.listFiles(new DirFileFilter());
     int subDirsCnt = subDirs != null ? subDirs.length : 0;
     // create and populate map of dir names to win browser objects
     Iterator iter = tmpBrowsersToCheck.iterator();
     Map dirNameToBrowser = new HashMap();
     while (iter.hasNext()) {
       WindowsBrowser wBrowser = (WindowsBrowser) iter.next();
       dirNameToBrowser.put(wBrowser.getSubDirName(), wBrowser);
     }
     // iterate over subdirs and compare to map entries
     for (int idx = 0; idx < subDirsCnt && !tmpBrowsersToCheck.isEmpty(); idx++) {
       if (dirNameToBrowser.containsKey(subDirs[idx].getName())) {
         WindowsBrowser wBrowser = (WindowsBrowser) dirNameToBrowser.get(subDirs[idx].getName());
         // need to search folder and sub-folders for exe to find
         // the full path
         String exeName = wBrowser.getBrowserApplicationName() + ".exe";
         File fullPathToExe = findExeFilePath(subDirs[idx], exeName);
         if (fullPathToExe != null) {
           logger.debug(
               "Adding browser " + wBrowser.getBrowserDisplayName() + " to available list.");
           wBrowser.setPathToExe(fullPathToExe.getPath());
           logger.debug(wBrowser.getPathToExe());
           // adding display and exe for backward compatibility and
           // ease of use if someone passes in the name of an exe
           browsersAvailable.put(wBrowser.getBrowserDisplayName(), wBrowser);
           browsersAvailable.put(wBrowser.getBrowserApplicationName(), wBrowser);
           tmpBrowsersToCheck.remove(wBrowser);
         }
       }
     }
   }
   return browsersAvailable;
 }