public static GroupProvider instantiate(@Nonnull final SystemProperty<Class> implementationProperty, @Nullable final SystemProperty<String> configProperty)
    {
        final Class<? extends GroupProvider> implementationClass = implementationProperty.getValue();
        if (implementationClass == null) {
            Log.debug( "Property '{}' is undefined or has no value. Skipping.", implementationProperty.getKey() );
            return null;
        }
        Log.debug("About to to instantiate an GroupProvider '{}' based on the value of property '{}'.", implementationClass, implementationProperty.getKey());

        try {
            if (configProperty != null && configProperty.getValue() != null && !configProperty.getValue().isEmpty()) {
                try {
                    final Constructor<? extends GroupProvider> constructor = implementationClass.getConstructor(String.class);
                    final GroupProvider result = constructor.newInstance(configProperty.getValue());
                    Log.debug("Instantiated GroupProvider '{}' with configuration: '{}'", implementationClass.getName(), configProperty.getValue());
                    return result;
                } catch (NoSuchMethodException e) {
                    Log.warn("Custom configuration is defined for the a provider but the configured class ('{}') does not provide a constructor that takes a String argument. Custom configuration will be ignored. Ignored configuration: '{}'", implementationProperty.getValue().getName(), configProperty);
                }
            }

            final GroupProvider result = implementationClass.getDeclaredConstructor().newInstance();
            Log.debug("Instantiated GroupProvider '{}'", implementationClass.getName());
            return result;
        } catch (Exception e) {
            Log.error("Unable to load GroupProvider '{}'. Data from this provider will not be available.", implementationClass.getName(), e);
            return null;
        }
    }
Instantiates a GroupProvider based on Class-based system property. When the property is not set, this
method returns null. When the property is set, but an exception occurs while instantiating the class, this method
logs the error and returns null.

GroupProvider classes are required to have a public, no-argument constructor, but can have an optional additional
constructor that takes a single String argument. If such constructor is defined, then it is invoked with the
value of the second argument of this method. This is typically used to (but needs not) identify a property
(by name) that holds additional configuration for the to be instantiated GroupProvider. This
implementation will pass on any non-empty value to the constructor. When a configuration argument is provided,
but no constructor exists in the implementation that accepts a single String value, this method will log a
warning and attempt to return an instance based on the no-arg constructor of the class.

@param implementationProperty A property that defines the class of the instance to be returned.
@param configProperty an opaque string value passed to the constructor.
@return A group provider (can be null).
xmppserver/src/main/java/org/jivesoftware/openfire/group/GroupMultiProvider.java