protected URL writeConfig(ConfigData configuration, String fileName) throws Exception {
      File configFile = new File(configDirectory, fileName);
      File backupFile = new File(configDirectory, fileName + ".bak");
      ConfigLogImplementation.logMethods.info("Writing configuration file at " + configFile);
      checkConfigDirectoryWritable();
      checkConfigFileWritableIfExists(configFile);
      checkConfigFileWritableIfExists(backupFile);

      File tempConfigFile = null;
      FileOutputStream fos = null;
      try {
        ConfigLogImplementation.logMethods.debug("About to create temp file");
        tempConfigFile = File.createTempFile("tempConfig", "." + extension, configDirectory);
        tempConfigFile.deleteOnExit();

        ConfigLogImplementation.logMethods.debug("About to write: " + tempConfigFile);

        try {
          fos = new FileOutputStream(tempConfigFile);
          writeConfigToStream(fos, configuration.getSerializedConfig(), configuration.getVersion());
        } finally {
          if (fos != null) {
            try {
              fos.close();
            } catch (Exception e) {
              ConfigLogImplementation.logMethods.error(
                  "Failed to close out file stream to temp file " + tempConfigFile.getPath(), e);
            }
          }
        }
        ConfigLogImplementation.logMethods.debug("Written: " + tempConfigFile);

        if (backupFile.exists()) {
          ConfigLogImplementation.logMethods.debug("About to delete " + backupFile);
          boolean deleted = backupFile.delete();
          if (deleted) {
            ConfigLogImplementation.logMethods.debug("Deleted " + backupFile);
          } else {
            ConfigLogImplementation.logMethods.warn("Failed to delete " + backupFile);
          }
        }

        if (configFile.exists()) {
          ConfigLogImplementation.logMethods.debug(
              "About to rename old config: " + configFile + " to " + backupFile);
          if (!configFile.renameTo(backupFile)) {
            throw new IOException(
                "Unable to rename old config: " + configFile + " to " + backupFile);
          }
        }

        ConfigLogImplementation.logMethods.debug(
            "About to rename temp config: " + tempConfigFile + " to " + configFile);
        if (!tempConfigFile.renameTo(configFile)) {
          throw new IOException(
              "Unable to rename temp config: " + tempConfigFile + " to new config: " + configFile);
        }
      } catch (IOException e) {
        ConfigLogImplementation.logMethods.error("Unable to save config: " + configFile, e);
        throw new ConfigManagerException("Unable to save config", e);
      }
      return configFile.toURI().toURL();
    }