@Override
    public UserProvider getUserProvider( String username )
    {
        for ( final Map.Entry<String, UserProvider> entry : providersByPrefix.entrySet() )
        {
            final String usersProperty = JiveGlobals.getProperty( entry.getKey() + ".members.propertyName" );
            if ( usersProperty != null )
            {
                final List<String> usersInSet = JiveGlobals.getListProperty( usersProperty, Collections.<String>emptyList() );
                if ( usersInSet.contains( username ) )
                {
                    return entry.getValue();
                }
            }
        }

        return fallbackProvider;
    }
A {@link UserProviderMapper} that can be used to draw some users from another source than the other users.

This implementation uses properties to define sets of usernames and a corresponding provider. When a user is not in
any set, a fallback provider is used.

Each set of usernames is defined by two properties. Use the following property to define the classname of an
{@link UserProvider} to be used for this set: {@code propertyBasedUserMapper.set.SET_NAME.provider.className}

Use the following property to identify a set of usernames: {@code propertyBasedUserMapper.set.SET_NAME.members}. The
value for this property must be the name of another property, which is a listing of usernames (such a property is
likely re-used in a corresponding {@link org.jivesoftware.openfire.auth.PropertyBasedAuthProviderMapper}
configuration).

There is no upper bound on the amount of sets that can be configured.

Users that are not in any set will use the fallback provider. This provider is defined by its class name in the
property {@code propertyBasedUserMapper.fallbackProvider.className}.

The following example defines two sets. Set "A" serves users john, jane and jack, and uses a DefaultUserProvider.
Set "B" serves users dave and doris, and uses A JDBCUserProvider. All other users are served by the fallback provider
that is a NativeUserProvider.

<ul>
<li>{@code members.set.A = List( "john", "jane", "jack" )}</li>
<li>{@code members.set.B = List( "dave", "doris" )}</li>
<li>{@code propertyBasedUserMapper.set.A.provider.className = org.jivesoftware.openfire.user.DefaultUserProvider}</li>
<li>{@code propertyBasedUserMapper.set.A.members.propertyName = members.set.A}</li>
<li>{@code propertyBasedUserMapper.set.B.provider.className = org.jivesoftware.openfire.user.JDBCUserProvider}</li>
<li>{@code propertyBasedUserMapper.set.B.members.propertyName = members.set.B}</li>
<li>{@code propertyBasedUserMapper.fallbackProvider.className = org.jivesoftware.openfire.auth.NativeUserProvider}</li>
</ul>

@author Guus der Kinderen, guus@goodbytes.nl
xmppserver/src/main/java/org/jivesoftware/openfire/user/PropertyBasedUserProviderMapper.java