public AuthenticationType getType() {
        if (type != null) {
            // use the user provided type
            return type;
        }

        final boolean hasPassword = ObjectHelper.isNotEmpty(password);
        final boolean hasRefreshToken = ObjectHelper.isNotEmpty(refreshToken);
        final boolean hasKeystore = keystore != null && ObjectHelper.isNotEmpty(keystore.getResource());
        final boolean hasClientCredentials = ObjectHelper.isNotEmpty(clientId) && ObjectHelper.isNotEmpty(clientSecret);

        if (hasPassword && !hasRefreshToken && !hasKeystore) {
            return AuthenticationType.USERNAME_PASSWORD;
        }

        if (!hasPassword && hasRefreshToken && !hasKeystore) {
            return AuthenticationType.REFRESH_TOKEN;
        }

        if (!hasPassword && !hasRefreshToken && hasKeystore) {
            return AuthenticationType.JWT;
        }

        if (!hasPassword && !hasRefreshToken && !hasKeystore && hasClientCredentials) {
            return AuthenticationType.CLIENT_CREDENTIALS;
        }

        if (hasPassword && hasRefreshToken || hasPassword && hasKeystore || hasRefreshToken && hasKeystore) {
            throw new IllegalArgumentException(
                    "The provided authentication configuration can be used in multiple ways"
                                               + " for instance both with username/password and refresh_token. Either remove some of the configuration"
                                               + " options, so that authentication method can be auto-determined or explicitly set the authentication"
                                               + " type.");
        }

        throw new IllegalArgumentException(
                "You must specify parameters aligned with one of the supported authentication methods:"
                                           + " for username and password authentication: userName, password, clientSecret;"
                                           + " for refresh token authentication: refreshToken, clientSecret;"
                                           + " for JWT: userName, keystore. And for every one of those loginUrl and clientId must be specified also.");
    }
@Test
    public void shouldDetermineProperAuthenticationType() {
        assertEquals(AuthenticationType.USERNAME_PASSWORD, usernamePassword.getType());

        assertEquals(AuthenticationType.REFRESH_TOKEN, refreshToken.getType());

        assertEquals(AuthenticationType.JWT, jwt.getType());
    }