loginmodules/password/pwcommon/src/main/java/org/beiter/michael/authn/jaas/loginmodules/password/common/PasswordValidatorFactory.java
@SuppressWarnings("PMD.NonThreadSafeSingleton")
    public static PasswordValidator getSingleton(final String className, final CommonProperties properties)
            throws FactoryException {

        Validate.notBlank(className, "The validated character sequence 'className' is null or empty");
        Validate.notNull(properties, "The validated object 'properties' is null");

        if (passwordValidatorInstance == null) {
            synchronized (PasswordValidatorFactory.class) {
                if (passwordValidatorInstance == null) {

                    passwordValidatorInstance = getInstance(className, properties);
                }
            }
        }

        return passwordValidatorInstance;
    }
@SuppressWarnings("PMD.NonThreadSafeSingleton")
    public static PasswordValidator getSingleton(final String className, final CommonProperties properties)
            throws FactoryException {

        Validate.notBlank(className, "The validated character sequence 'className' is null or empty");
        Validate.notNull(properties, "The validated object 'properties' is null");

        if (passwordValidatorInstance == null) {
            synchronized (PasswordValidatorFactory.class) {
                if (passwordValidatorInstance == null) {

                    passwordValidatorInstance = getInstance(className, properties);
                }
            }
        }

        return passwordValidatorInstance;
    }
Return a singleton, fully initialized instance of a {@link PasswordValidator} class to use for
JAAS authentication.
<p>
Retrieving a singleton by this method will cause the factory to keep state, and store a reference to the
singleton for later use. You may reset the factory state using the {@code reset()} method to retrieve a new
/ different singleton the next time this method is called..
<p>
Note that any properties of the singleton (e.g. configuration) cannot necessarily be changed easily. You may call
the singleton's {@code init()} method, but depending on the implementation provided by the respective class, this
may or may not have the expected effect.
<p>
If you need tight control over the singleton, including its lifecycle and configuration, or you require more than
one singleton that are different in their internal state (e.g. with different configurations), then you should
create such objects with the {@code getInstance()} method and maintain their state as "singletons" in your
application's business logic.
<p>
Classes implementing the {@link PasswordValidator} interface <b>must</b> be thread safe.

@param className  The name of a class that implements the PasswordValidator interface
@param properties The properties to initialize the instance with
@return An instance of a class implementing the {@code PasswordValidator} interface
@throws FactoryException         When the class cannot be instantiated
@throws NullPointerException     When the {@code className} or {@code properties} are {@code null}
@throws IllegalArgumentException When {@code className} is empty