@Override
  protected void init(final Properties parameters) throws BadRealmException, NoSuchRealmException {
    super.init(parameters);
    _logger.log(Level.FINE, "Initializing {0}", this.getClass().getSimpleName());

    // Among the other custom properties, there is a property jaas-context (which is explained later
    // in this post).
    // This property should be set using the call setProperty method implemented in the parent
    // class.
    /// From: https://blogs.oracle.com/nithya/entry/groups_in_custom_realms
    checkAndSetProperty(JAAS_CONTEXT_PARAM, parameters);

    for (Map.Entry<String, String> entry : OPTIONAL_PROPERTIES.entrySet()) {
      setOptionalProperty(entry.getKey(), parameters, entry.getValue());
    }

    String digestAlgorithm = getProperty(PARAM_DIGEST_ALGORITHM);
    switch (digestAlgorithm) {
      case "none":
        transformer = new NullTransformer();
        break;
      default:
        transformer =
            new MessageDigestTransformer(
                digestAlgorithm,
                getProperty(PARAM_DIGEST_ENCODING),
                Charset.forName(getProperty(PARAM_PASSWORD_CHARSET)));
    }
  }
  static {
    OPTIONAL_PROPERTIES.put(PARAM_DIGEST_ALGORITHM, DEFAULT_DIGEST_ALGORITHM);
    OPTIONAL_PROPERTIES.put(PARAM_DIGEST_ENCODING, DEFAULT_DIGEST_ENCODING);
    OPTIONAL_PROPERTIES.put(PARAM_PASSWORD_CHARSET, Charset.defaultCharset().name());

    OPTIONAL_PROPERTIES.put(PARAM_JNDI_DATASOURCE, DEFAULT_JNDI_DATASOURCE);

    OPTIONAL_PROPERTIES.put(PARAM_PRINCIPAL_QUERY, DEFAULT_PRINCIPAL_QUERY);
    OPTIONAL_PROPERTIES.put(PARAM_SECURITY_ROLES_QUERY, DEFAULT_SECURITY_ROLES_QUERY);
  }