code: // Licensed to the Software Freedom Conservancy (SFC) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The SFC licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  
  package org.openqa.selenium.firefox;
  
  import static org.openqa.selenium.Platform.MAC;
  import static org.openqa.selenium.Platform.WINDOWS;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.IOException;
  import java.nio.charset.Charset;
  import java.nio.file.Files;
  import java.text.MessageFormat;
  import java.util.HashMap;
  import java.util.Map;
  import org.openqa.selenium.Platform;
  import org.openqa.selenium.WebDriverException;
  import org.openqa.selenium.io.FileHandler;
  import org.openqa.selenium.io.TemporaryFilesystem;
  
  public class ProfilesIni {
    private Map<String, File> profiles;
  
    public ProfilesIni() {
      File appData = locateAppDataDirectory(Platform.getCurrent());
      profiles = readProfiles(appData);
    }
  
    protected Map<String, File> readProfiles(File appData) {
      Map<String, File> toReturn = new HashMap<>();
  
      File profilesIni = new File(appData, "profiles.ini");
      if (!profilesIni.exists()) {
        // Fine. No profiles.ini file
        return toReturn;
      }
  
      boolean isRelative = true;
      String name = null;
      String path = null;
  
      BufferedReader reader = null;
      try {
        reader = Files.newBufferedReader(profilesIni.toPath(), Charset.defaultCharset());
  
        String line = reader.readLine();
  
        while (line != null) {
          if (line.startsWith("[Profile")) {
            File profile = newProfile(name, appData, path, isRelative);
            if (profile != null) toReturn.put(name, profile);
  
            name = null;
            path = null;
          } else if (line.startsWith("Name=")) {
            name = line.substring("Name=".length());
          } else if (line.startsWith("IsRelative=")) {
            isRelative = line.endsWith("1");
          } else if (line.startsWith("Path=")) {
            path = line.substring("Path=".length());
          }
  
          line = reader.readLine();
        }
      } catch (IOException e) {
        throw new WebDriverException(e);
      } finally {
        try {
          if (reader != null) {
            File profile = newProfile(name, appData, path, isRelative);
            if (profile != null) toReturn.put(name, profile);
  
            reader.close();
          }
        } catch (IOException e) {
          // Nothing that can be done sensibly. Swallowing.
        }
      }
  
      return toReturn;
    }
  
    protected File newProfile(String name, File appData, String path, boolean isRelative) {
      if (name != null && path != null) {
        return isRelative ? new File(appData, path) : new File(path);
      }
      return null;
    }
  
    public FirefoxProfile getProfile(String profileName) {
      File profileDir = profiles.get(profileName);
      if (profileDir == null) {
        return null;
      }
  
      // Make a copy of the profile to use
      File tempDir = TemporaryFilesystem.getDefaultTmpFS().createTempDir("userprofile", "copy");
      try {
        FileHandler.copy(profileDir, tempDir);
  
        // Delete the old compreg.dat file so that our new extension is registered
        File compreg = new File(tempDir, "compreg.dat");
        if (compreg.exists()) {
          if (!compreg.delete()) {
            throw new WebDriverException("Cannot delete file from copy of profile " + profileName);
          }
        }
      } catch (IOException e) {
        throw new WebDriverException(e);
      }
  
      return new FirefoxProfile(tempDir);
    }
  
    protected File locateAppDataDirectory(Platform os) {
      File appData;
      if (os.is(WINDOWS)) {
        appData = new File(MessageFormat.format("{0}\\Mozilla\\Firefox", System.getenv("APPDATA")));
  
      } else if (os.is(MAC)) {
        appData =
            new File(
                MessageFormat.format(
                    "{0}/Library/Application Support/Firefox", System.getenv("HOME")));
  
      } else {
        appData = new File(MessageFormat.format("{0}/.mozilla/firefox", System.getenv("HOME")));
      }
  
      if (!appData.exists()) {
        // It's possible we're being run as part of an automated build.
        // Assume the user knows what they're doing
        return null;
      }
  
      if (!appData.isDirectory()) {
        throw new WebDriverException(
            "The discovered user firefox data directory "
                + "(which normally contains the profiles) isn't a directory: "
                + appData.getAbsolutePath());
      }
  
      return appData;
    }
  }
  