class XSUserInfoAdapter implements XSUserInfo {

	@Override
	public boolean isInForeignMode() {
		if (configuration == null) {
			LOGGER.info("No configuration provided -> falling back to foreignMode = true!");
			return true; // default provide OAuth2ServiceConfiguration via constructor argument
		}
		String tokenClientId, tokenIdentityZone;
		try {
			tokenClientId = getClientId();
			tokenIdentityZone = getIdentityZone();
		} catch (XSUserInfoException e) {
			LOGGER.warn("Tried to access missing attribute when checking for foreign mode", e);
			return true;
		}
		boolean clientIdsMatch = tokenClientId.equals(configuration.getClientId());
		boolean identityZonesMatch = tokenIdentityZone
				.equals(configuration.getProperty(CFConstants.XSUAA.IDENTITY_ZONE));
		boolean isApplicationPlan = tokenClientId.contains("!t");
		boolean isBrokerPlan = tokenClientId.contains("!b");

		if (clientIdsMatch && (identityZonesMatch || isApplicationPlan || isBrokerPlan)) {
			LOGGER.info(
					"Token not in foreign mode because because client ids match and identityZonesMatch={}, isApplicationPlan={} ",
					identityZonesMatch, isApplicationPlan);
			return false; // no foreign mode
		}
		// in case of broker master: check trustedclientidsuffix
		String bindingTrustedClientIdSuffix = configuration.getProperty(TRUSTED_CLIENT_ID_SUFFIX);
		if (bindingTrustedClientIdSuffix != null && tokenClientId.endsWith(bindingTrustedClientIdSuffix)) {
			LOGGER.info("Token not in foreign mode because token client id matches binding trusted client suffix");
			return false; // no foreign mode
		}
		LOGGER.info(
				"Token in foreign mode: clientIdsMatch={}, identityZonesMatch={}, isApplicationPlan={}, bindingTrustedClientIdSuffix={}",
				clientIdsMatch, identityZonesMatch, isApplicationPlan, bindingTrustedClientIdSuffix);
		return true;
	}

	public  XSUserInfoAdapter(Object accessToken);
	public  XSUserInfoAdapter(AccessToken accessToken);
	  XSUserInfoAdapter(Object accessToken, OAuth2ServiceConfiguration configuration);

}