@Override
        public Argon2Hash generate(HashRequest hashRequest) {
            final String algorithmName = Optional.ofNullable(hashRequest.getParameters().get(Parameters.PARAMETER_ALGORITHM_NAME))
                    .map(algo -> (String) algo)
                    .orElse(Parameters.DEFAULT_ALGORITHM_NAME);

            final int version = Optional.ofNullable(hashRequest.getParameters().get(Parameters.PARAMETER_ALGORITHM_VERSION))
                    .flatMap(algoV -> intOrEmpty(algoV, Parameters.PARAMETER_ALGORITHM_VERSION))
                    .orElse(Parameters.DEFAULT_ALGORITHM_VERSION);

            final ByteSource salt = parseSalt(hashRequest);

            final int iterations = Optional.ofNullable(hashRequest.getParameters().get(Parameters.PARAMETER_ITERATIONS))
                    .flatMap(algoV -> intOrEmpty(algoV, Parameters.PARAMETER_ITERATIONS))
                    .orElse(Parameters.DEFAULT_ITERATIONS);

            final int memoryKib = Optional.ofNullable(hashRequest.getParameters().get(Parameters.PARAMETER_MEMORY_KIB))
                    .flatMap(algoV -> intOrEmpty(algoV, Parameters.PARAMETER_MEMORY_KIB))
                    .orElse(Parameters.DEFAULT_MEMORY_KIB);

            final int parallelism = Optional.ofNullable(hashRequest.getParameters().get(Parameters.PARAMETER_PARALLELISM))
                    .flatMap(algoV -> intOrEmpty(algoV, Parameters.PARAMETER_PARALLELISM))
                    .orElse(Parameters.DEFAULT_PARALLELISM);

            final int outputLengthBits = Optional.ofNullable(hashRequest.getParameters()
                            .get(Parameters.PARAMETER_OUTPUT_LENGTH_BITS))
                    .flatMap(algoV -> intOrEmpty(algoV, Parameters.PARAMETER_OUTPUT_LENGTH_BITS))
                    .orElse(Parameters.DEFAULT_OUTPUT_LENGTH_BITS);

            return Argon2Hash.generate(
                    algorithmName,
                    version,
                    hashRequest.getSource(),
                    salt,
                    iterations,
                    memoryKib,
                    parallelism,
                    outputLengthBits
            );
        }
A HashProvider for the Argon2 hash algorithm.

<p>This class is intended to be used by the {@code HashProvider} class from Shiro. However,
this class can also be used to created instances of the Argon2 hash manually.</p>

<p>Furthermore, there is a nested {@link Parameters} class which provides names for the
keys used in the parameters map of the {@link HashRequest} class.</p>

@since 2.0
crypto/support/hashes/argon2/src/main/java/org/apache/shiro/crypto/support/hashes/argon2/Argon2HashProvider.java