keycloak-aplcache

KEYCLOAK-1074 - Allow registration with email as username

3/10/2015 12:28:57 PM

Changes

Details

diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
index f1a35c9..a723490 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
@@ -93,6 +93,7 @@
 
         <addColumn tableName="REALM">
             <column name="LOGIN_LIFESPAN" type="INT"/>
+            <column name="REGISTRATION_EMAIL_AS_USERNAME" type="BOOLEAN" defaultValueBoolean="false"/>
         </addColumn>
     </changeSet>
 </databaseChangeLog>
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index dce6df6..aa55d71 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -11,497 +11,510 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class RealmRepresentation {
-    protected String id;
-    protected String realm;
-    protected Integer notBefore;
-    protected Integer accessTokenLifespan;
-    protected Integer ssoSessionIdleTimeout;
-    protected Integer ssoSessionMaxLifespan;
-    protected Integer accessCodeLifespan;
-    protected Integer accessCodeLifespanUserAction;
-    protected Integer accessCodeLifespanLogin;
-    protected Boolean enabled;
-    protected String sslRequired;
-    protected Boolean passwordCredentialGrantAllowed;
-    protected Boolean registrationAllowed;
-    protected Boolean rememberMe;
-    protected Boolean verifyEmail;
-    protected Boolean resetPasswordAllowed;
-
-    protected Boolean userCacheEnabled;
-    protected Boolean realmCacheEnabled;
-
-    //--- brute force settings
-    protected Boolean bruteForceProtected;
-    protected Integer maxFailureWaitSeconds;
-    protected Integer minimumQuickLoginWaitSeconds;
-    protected Integer waitIncrementSeconds;
-    protected Long quickLoginCheckMilliSeconds;
-    protected Integer maxDeltaTimeSeconds;
-    protected Integer failureFactor;
-    //--- end brute force settings
-
-    protected String privateKey;
-    protected String publicKey;
-    protected String certificate;
-    protected String codeSecret;
-    protected RolesRepresentation roles;
-    protected List<String> defaultRoles;
-    protected Set<String> requiredCredentials;
-    protected String passwordPolicy;
-    protected List<UserRepresentation> users;
-    protected List<ScopeMappingRepresentation> scopeMappings;
-    protected Map<String, List<ScopeMappingRepresentation>> applicationScopeMappings;
-    protected List<ApplicationRepresentation> applications;
-    protected List<OAuthClientRepresentation> oauthClients;
-    protected Map<String, String> browserSecurityHeaders;
-    protected Map<String, String> smtpServer;
-    protected List<UserFederationProviderRepresentation> userFederationProviders;
-    protected String loginTheme;
-    protected String accountTheme;
-    protected String adminTheme;
-    protected String emailTheme;
-    protected Boolean eventsEnabled;
-    protected Long eventsExpiration;
-    protected List<String> eventsListeners;
-    private List<IdentityProviderRepresentation> identityProviders;
-    private List<ProtocolMapperRepresentation> protocolMappers;
-    private Boolean identityFederationEnabled;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getRealm() {
-        return realm;
-    }
-
-    public void setRealm(String realm) {
-        this.realm = realm;
-    }
-
-    public List<UserRepresentation> getUsers() {
-        return users;
-    }
-
-    public List<ApplicationRepresentation> getApplications() {
-        return applications;
-    }
-
-    public ApplicationRepresentation resource(String name) {
-        ApplicationRepresentation resource = new ApplicationRepresentation();
-        if (applications == null) applications = new ArrayList<ApplicationRepresentation>();
-        applications.add(resource);
-        resource.setName(name);
-        return resource;
-    }
-
-    public void setUsers(List<UserRepresentation> users) {
-        this.users = users;
-    }
-
-    public UserRepresentation user(String username) {
-        UserRepresentation user = new UserRepresentation();
-        user.setUsername(username);
-        if (users == null) users = new ArrayList<UserRepresentation>();
-        users.add(user);
-        return user;
-    }
-
-    public void setApplications(List<ApplicationRepresentation> applications) {
-        this.applications = applications;
-    }
-
-    public Boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(Boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    public String getSslRequired() {
-        return sslRequired;
-    }
-
-    public void setSslRequired(String sslRequired) {
-        this.sslRequired = sslRequired;
-    }
-
-    public Integer getAccessTokenLifespan() {
-        return accessTokenLifespan;
-    }
-
-    public void setAccessTokenLifespan(Integer accessTokenLifespan) {
-        this.accessTokenLifespan = accessTokenLifespan;
-    }
-
-    public Integer getSsoSessionIdleTimeout() {
-        return ssoSessionIdleTimeout;
-    }
-
-    public void setSsoSessionIdleTimeout(Integer ssoSessionIdleTimeout) {
-        this.ssoSessionIdleTimeout = ssoSessionIdleTimeout;
-    }
-
-    public Integer getSsoSessionMaxLifespan() {
-        return ssoSessionMaxLifespan;
-    }
-
-    public void setSsoSessionMaxLifespan(Integer ssoSessionMaxLifespan) {
-        this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
-    }
-
-    public List<ScopeMappingRepresentation> getScopeMappings() {
-        return scopeMappings;
-    }
-
-    public ScopeMappingRepresentation scopeMapping(String username) {
-        ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
-        mapping.setClient(username);
-        if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
-        scopeMappings.add(mapping);
-        return mapping;
-    }
-
-    public Set<String> getRequiredCredentials() {
-        return requiredCredentials;
-    }
-
-    public void setRequiredCredentials(Set<String> requiredCredentials) {
-        this.requiredCredentials = requiredCredentials;
-    }
-
-    public String getPasswordPolicy() {
-        return passwordPolicy;
-    }
-
-    public void setPasswordPolicy(String passwordPolicy) {
-        this.passwordPolicy = passwordPolicy;
-    }
-
-    public Integer getAccessCodeLifespan() {
-        return accessCodeLifespan;
-    }
-
-    public void setAccessCodeLifespan(Integer accessCodeLifespan) {
-        this.accessCodeLifespan = accessCodeLifespan;
-    }
-
-    public Integer getAccessCodeLifespanUserAction() {
-        return accessCodeLifespanUserAction;
-    }
-
-    public void setAccessCodeLifespanUserAction(Integer accessCodeLifespanUserAction) {
-        this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
-    }
-
-    public Integer getAccessCodeLifespanLogin() {
-        return accessCodeLifespanLogin;
-    }
-
-    public void setAccessCodeLifespanLogin(Integer accessCodeLifespanLogin) {
-        this.accessCodeLifespanLogin = accessCodeLifespanLogin;
-    }
-
-    public List<String> getDefaultRoles() {
-        return defaultRoles;
-    }
+	protected String id;
+	protected String realm;
+	protected Integer notBefore;
+	protected Integer accessTokenLifespan;
+	protected Integer ssoSessionIdleTimeout;
+	protected Integer ssoSessionMaxLifespan;
+	protected Integer accessCodeLifespan;
+	protected Integer accessCodeLifespanUserAction;
+	protected Integer accessCodeLifespanLogin;
+	protected Boolean enabled;
+	protected String sslRequired;
+	protected Boolean passwordCredentialGrantAllowed;
+	protected Boolean registrationAllowed;
+	protected Boolean registrationEmailAsUsername;
+	protected Boolean rememberMe;
+	protected Boolean verifyEmail;
+	protected Boolean resetPasswordAllowed;
+
+	protected Boolean userCacheEnabled;
+	protected Boolean realmCacheEnabled;
+
+	// --- brute force settings
+	protected Boolean bruteForceProtected;
+	protected Integer maxFailureWaitSeconds;
+	protected Integer minimumQuickLoginWaitSeconds;
+	protected Integer waitIncrementSeconds;
+	protected Long quickLoginCheckMilliSeconds;
+	protected Integer maxDeltaTimeSeconds;
+	protected Integer failureFactor;
+	// --- end brute force settings
+
+	protected String privateKey;
+	protected String publicKey;
+	protected String certificate;
+	protected String codeSecret;
+	protected RolesRepresentation roles;
+	protected List<String> defaultRoles;
+	protected Set<String> requiredCredentials;
+	protected String passwordPolicy;
+	protected List<UserRepresentation> users;
+	protected List<ScopeMappingRepresentation> scopeMappings;
+	protected Map<String, List<ScopeMappingRepresentation>> applicationScopeMappings;
+	protected List<ApplicationRepresentation> applications;
+	protected List<OAuthClientRepresentation> oauthClients;
+	protected Map<String, String> browserSecurityHeaders;
+	protected Map<String, String> smtpServer;
+	protected List<UserFederationProviderRepresentation> userFederationProviders;
+	protected String loginTheme;
+	protected String accountTheme;
+	protected String adminTheme;
+	protected String emailTheme;
+	protected Boolean eventsEnabled;
+	protected Long eventsExpiration;
+	protected List<String> eventsListeners;
+	private List<IdentityProviderRepresentation> identityProviders;
+	private List<ProtocolMapperRepresentation> protocolMappers;
+	private Boolean identityFederationEnabled;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getRealm() {
+		return realm;
+	}
+
+	public void setRealm(String realm) {
+		this.realm = realm;
+	}
+
+	public List<UserRepresentation> getUsers() {
+		return users;
+	}
+
+	public List<ApplicationRepresentation> getApplications() {
+		return applications;
+	}
+
+	public ApplicationRepresentation resource(String name) {
+		ApplicationRepresentation resource = new ApplicationRepresentation();
+		if (applications == null)
+			applications = new ArrayList<ApplicationRepresentation>();
+		applications.add(resource);
+		resource.setName(name);
+		return resource;
+	}
+
+	public void setUsers(List<UserRepresentation> users) {
+		this.users = users;
+	}
+
+	public UserRepresentation user(String username) {
+		UserRepresentation user = new UserRepresentation();
+		user.setUsername(username);
+		if (users == null)
+			users = new ArrayList<UserRepresentation>();
+		users.add(user);
+		return user;
+	}
+
+	public void setApplications(List<ApplicationRepresentation> applications) {
+		this.applications = applications;
+	}
+
+	public Boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(Boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public String getSslRequired() {
+		return sslRequired;
+	}
+
+	public void setSslRequired(String sslRequired) {
+		this.sslRequired = sslRequired;
+	}
+
+	public Integer getAccessTokenLifespan() {
+		return accessTokenLifespan;
+	}
+
+	public void setAccessTokenLifespan(Integer accessTokenLifespan) {
+		this.accessTokenLifespan = accessTokenLifespan;
+	}
+
+	public Integer getSsoSessionIdleTimeout() {
+		return ssoSessionIdleTimeout;
+	}
+
+	public void setSsoSessionIdleTimeout(Integer ssoSessionIdleTimeout) {
+		this.ssoSessionIdleTimeout = ssoSessionIdleTimeout;
+	}
+
+	public Integer getSsoSessionMaxLifespan() {
+		return ssoSessionMaxLifespan;
+	}
+
+	public void setSsoSessionMaxLifespan(Integer ssoSessionMaxLifespan) {
+		this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
+	}
+
+	public List<ScopeMappingRepresentation> getScopeMappings() {
+		return scopeMappings;
+	}
+
+	public ScopeMappingRepresentation scopeMapping(String username) {
+		ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
+		mapping.setClient(username);
+		if (scopeMappings == null)
+			scopeMappings = new ArrayList<ScopeMappingRepresentation>();
+		scopeMappings.add(mapping);
+		return mapping;
+	}
+
+	public Set<String> getRequiredCredentials() {
+		return requiredCredentials;
+	}
+
+	public void setRequiredCredentials(Set<String> requiredCredentials) {
+		this.requiredCredentials = requiredCredentials;
+	}
+
+	public String getPasswordPolicy() {
+		return passwordPolicy;
+	}
+
+	public void setPasswordPolicy(String passwordPolicy) {
+		this.passwordPolicy = passwordPolicy;
+	}
+
+	public Integer getAccessCodeLifespan() {
+		return accessCodeLifespan;
+	}
+
+	public void setAccessCodeLifespan(Integer accessCodeLifespan) {
+		this.accessCodeLifespan = accessCodeLifespan;
+	}
+
+	public Integer getAccessCodeLifespanUserAction() {
+		return accessCodeLifespanUserAction;
+	}
+
+	public void setAccessCodeLifespanUserAction(Integer accessCodeLifespanUserAction) {
+		this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
+	}
+
+	public Integer getAccessCodeLifespanLogin() {
+		return accessCodeLifespanLogin;
+	}
+
+	public void setAccessCodeLifespanLogin(Integer accessCodeLifespanLogin) {
+		this.accessCodeLifespanLogin = accessCodeLifespanLogin;
+	}
+
+	public List<String> getDefaultRoles() {
+		return defaultRoles;
+	}
+
+	public void setDefaultRoles(List<String> defaultRoles) {
+		this.defaultRoles = defaultRoles;
+	}
+
+	public String getPrivateKey() {
+		return privateKey;
+	}
+
+	public void setPrivateKey(String privateKey) {
+		this.privateKey = privateKey;
+	}
+
+	public String getPublicKey() {
+		return publicKey;
+	}
+
+	public void setPublicKey(String publicKey) {
+		this.publicKey = publicKey;
+	}
+
+	public String getCertificate() {
+		return certificate;
+	}
+
+	public void setCertificate(String certificate) {
+		this.certificate = certificate;
+	}
+
+	public String getCodeSecret() {
+		return codeSecret;
+	}
+
+	public void setCodeSecret(String codeSecret) {
+		this.codeSecret = codeSecret;
+	}
+
+	public Boolean isPasswordCredentialGrantAllowed() {
+		return passwordCredentialGrantAllowed;
+	}
+
+	public void setPasswordCredentialGrantAllowed(Boolean passwordCredentialGrantAllowed) {
+		this.passwordCredentialGrantAllowed = passwordCredentialGrantAllowed;
+	}
+
+	public Boolean isRegistrationAllowed() {
+		return registrationAllowed;
+	}
+
+	public void setRegistrationAllowed(Boolean registrationAllowed) {
+		this.registrationAllowed = registrationAllowed;
+	}
 
-    public void setDefaultRoles(List<String> defaultRoles) {
-        this.defaultRoles = defaultRoles;
-    }
+	public Boolean isRegistrationEmailAsUsername() {
+		return registrationEmailAsUsername;
+	}
 
-    public String getPrivateKey() {
-        return privateKey;
-    }
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		this.registrationEmailAsUsername = registrationEmailAsUsername;
+	}
 
-    public void setPrivateKey(String privateKey) {
-        this.privateKey = privateKey;
-    }
+	public Boolean isRememberMe() {
+		return rememberMe;
+	}
 
-    public String getPublicKey() {
-        return publicKey;
-    }
+	public void setRememberMe(Boolean rememberMe) {
+		this.rememberMe = rememberMe;
+	}
 
-    public void setPublicKey(String publicKey) {
-        this.publicKey = publicKey;
-    }
+	public Boolean isRealmCacheEnabled() {
+		return realmCacheEnabled;
+	}
 
-    public String getCertificate() {
-        return certificate;
-    }
+	public void setRealmCacheEnabled(Boolean realmCacheEnabled) {
+		this.realmCacheEnabled = realmCacheEnabled;
+	}
 
-    public void setCertificate(String certificate) {
-        this.certificate = certificate;
-    }
+	public Boolean isUserCacheEnabled() {
+		return userCacheEnabled;
+	}
 
-    public String getCodeSecret() {
-        return codeSecret;
-    }
+	public void setUserCacheEnabled(Boolean userCacheEnabled) {
+		this.userCacheEnabled = userCacheEnabled;
+	}
 
-    public void setCodeSecret(String codeSecret) {
-        this.codeSecret = codeSecret;
-    }
+	public Boolean isVerifyEmail() {
+		return verifyEmail;
+	}
 
-    public Boolean isPasswordCredentialGrantAllowed() {
-        return passwordCredentialGrantAllowed;
-    }
+	public void setVerifyEmail(Boolean verifyEmail) {
+		this.verifyEmail = verifyEmail;
+	}
 
-    public void setPasswordCredentialGrantAllowed(Boolean passwordCredentialGrantAllowed) {
-        this.passwordCredentialGrantAllowed = passwordCredentialGrantAllowed;
-    }
+	public Boolean isResetPasswordAllowed() {
+		return resetPasswordAllowed;
+	}
 
-    public Boolean isRegistrationAllowed() {
-        return registrationAllowed;
-    }
+	public void setResetPasswordAllowed(Boolean resetPassword) {
+		this.resetPasswordAllowed = resetPassword;
+	}
 
-    public void setRegistrationAllowed(Boolean registrationAllowed) {
-        this.registrationAllowed = registrationAllowed;
-    }
+	public Map<String, String> getBrowserSecurityHeaders() {
+		return browserSecurityHeaders;
+	}
 
-    public Boolean isRememberMe() {
-        return rememberMe;
-    }
+	public void setBrowserSecurityHeaders(Map<String, String> browserSecurityHeaders) {
+		this.browserSecurityHeaders = browserSecurityHeaders;
+	}
 
-    public void setRememberMe(Boolean rememberMe) {
-        this.rememberMe = rememberMe;
-    }
+	public Map<String, String> getSmtpServer() {
+		return smtpServer;
+	}
 
-    public Boolean isRealmCacheEnabled() {
-        return realmCacheEnabled;
-    }
+	public void setSmtpServer(Map<String, String> smtpServer) {
+		this.smtpServer = smtpServer;
+	}
 
-    public void setRealmCacheEnabled(Boolean realmCacheEnabled) {
-        this.realmCacheEnabled = realmCacheEnabled;
-    }
+	public List<OAuthClientRepresentation> getOauthClients() {
+		return oauthClients;
+	}
 
-    public Boolean isUserCacheEnabled() {
-        return userCacheEnabled;
-    }
+	public void setOauthClients(List<OAuthClientRepresentation> oauthClients) {
+		this.oauthClients = oauthClients;
+	}
 
-    public void setUserCacheEnabled(Boolean userCacheEnabled) {
-        this.userCacheEnabled = userCacheEnabled;
-    }
+	public Map<String, List<ScopeMappingRepresentation>> getApplicationScopeMappings() {
+		return applicationScopeMappings;
+	}
 
-    public Boolean isVerifyEmail() {
-        return verifyEmail;
-    }
+	public void setApplicationScopeMappings(Map<String, List<ScopeMappingRepresentation>> applicationScopeMappings) {
+		this.applicationScopeMappings = applicationScopeMappings;
+	}
 
-    public void setVerifyEmail(Boolean verifyEmail) {
-        this.verifyEmail = verifyEmail;
-    }
+	public RolesRepresentation getRoles() {
+		return roles;
+	}
 
-    public Boolean isResetPasswordAllowed() {
-        return resetPasswordAllowed;
-    }
+	public void setRoles(RolesRepresentation roles) {
+		this.roles = roles;
+	}
 
-    public void setResetPasswordAllowed(Boolean resetPassword) {
-        this.resetPasswordAllowed = resetPassword;
-    }
+	public String getLoginTheme() {
+		return loginTheme;
+	}
 
-    public Map<String, String> getBrowserSecurityHeaders() {
-        return browserSecurityHeaders;
-    }
+	public void setLoginTheme(String loginTheme) {
+		this.loginTheme = loginTheme;
+	}
 
-    public void setBrowserSecurityHeaders(Map<String, String> browserSecurityHeaders) {
-        this.browserSecurityHeaders = browserSecurityHeaders;
-    }
+	public String getAccountTheme() {
+		return accountTheme;
+	}
 
-    public Map<String, String> getSmtpServer() {
-        return smtpServer;
-    }
+	public void setAccountTheme(String accountTheme) {
+		this.accountTheme = accountTheme;
+	}
 
-    public void setSmtpServer(Map<String, String> smtpServer) {
-        this.smtpServer = smtpServer;
-    }
+	public String getAdminTheme() {
+		return adminTheme;
+	}
 
-    public List<OAuthClientRepresentation> getOauthClients() {
-        return oauthClients;
-    }
+	public void setAdminTheme(String adminTheme) {
+		this.adminTheme = adminTheme;
+	}
 
-    public void setOauthClients(List<OAuthClientRepresentation> oauthClients) {
-        this.oauthClients = oauthClients;
-    }
+	public String getEmailTheme() {
+		return emailTheme;
+	}
 
-    public Map<String, List<ScopeMappingRepresentation>> getApplicationScopeMappings() {
-        return applicationScopeMappings;
-    }
+	public void setEmailTheme(String emailTheme) {
+		this.emailTheme = emailTheme;
+	}
 
-    public void setApplicationScopeMappings(Map<String, List<ScopeMappingRepresentation>> applicationScopeMappings) {
-        this.applicationScopeMappings = applicationScopeMappings;
-    }
+	public Integer getNotBefore() {
+		return notBefore;
+	}
 
-    public RolesRepresentation getRoles() {
-        return roles;
-    }
+	public void setNotBefore(Integer notBefore) {
+		this.notBefore = notBefore;
+	}
 
-    public void setRoles(RolesRepresentation roles) {
-        this.roles = roles;
-    }
+	public Boolean isBruteForceProtected() {
+		return bruteForceProtected;
+	}
 
-    public String getLoginTheme() {
-        return loginTheme;
-    }
+	public void setBruteForceProtected(Boolean bruteForceProtected) {
+		this.bruteForceProtected = bruteForceProtected;
+	}
 
-    public void setLoginTheme(String loginTheme) {
-        this.loginTheme = loginTheme;
-    }
+	public Integer getMaxFailureWaitSeconds() {
+		return maxFailureWaitSeconds;
+	}
 
-    public String getAccountTheme() {
-        return accountTheme;
-    }
+	public void setMaxFailureWaitSeconds(Integer maxFailureWaitSeconds) {
+		this.maxFailureWaitSeconds = maxFailureWaitSeconds;
+	}
 
-    public void setAccountTheme(String accountTheme) {
-        this.accountTheme = accountTheme;
-    }
+	public Integer getMinimumQuickLoginWaitSeconds() {
+		return minimumQuickLoginWaitSeconds;
+	}
 
-    public String getAdminTheme() {
-        return adminTheme;
-    }
+	public void setMinimumQuickLoginWaitSeconds(Integer minimumQuickLoginWaitSeconds) {
+		this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
+	}
 
-    public void setAdminTheme(String adminTheme) {
-        this.adminTheme = adminTheme;
-    }
+	public Integer getWaitIncrementSeconds() {
+		return waitIncrementSeconds;
+	}
 
-    public String getEmailTheme() {
-        return emailTheme;
-    }
+	public void setWaitIncrementSeconds(Integer waitIncrementSeconds) {
+		this.waitIncrementSeconds = waitIncrementSeconds;
+	}
 
-    public void setEmailTheme(String emailTheme) {
-        this.emailTheme = emailTheme;
-    }
+	public Long getQuickLoginCheckMilliSeconds() {
+		return quickLoginCheckMilliSeconds;
+	}
 
-    public Integer getNotBefore() {
-        return notBefore;
-    }
+	public void setQuickLoginCheckMilliSeconds(Long quickLoginCheckMilliSeconds) {
+		this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
+	}
 
-    public void setNotBefore(Integer notBefore) {
-        this.notBefore = notBefore;
-    }
+	public Integer getMaxDeltaTimeSeconds() {
+		return maxDeltaTimeSeconds;
+	}
 
-    public Boolean isBruteForceProtected() {
-        return bruteForceProtected;
-    }
+	public void setMaxDeltaTimeSeconds(Integer maxDeltaTimeSeconds) {
+		this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
+	}
 
-    public void setBruteForceProtected(Boolean bruteForceProtected) {
-        this.bruteForceProtected = bruteForceProtected;
-    }
+	public Integer getFailureFactor() {
+		return failureFactor;
+	}
 
-    public Integer getMaxFailureWaitSeconds() {
-        return maxFailureWaitSeconds;
-    }
+	public void setFailureFactor(Integer failureFactor) {
+		this.failureFactor = failureFactor;
+	}
 
-    public void setMaxFailureWaitSeconds(Integer maxFailureWaitSeconds) {
-        this.maxFailureWaitSeconds = maxFailureWaitSeconds;
-    }
+	public Boolean isEventsEnabled() {
+		return eventsEnabled;
+	}
 
-    public Integer getMinimumQuickLoginWaitSeconds() {
-        return minimumQuickLoginWaitSeconds;
-    }
+	public void setEventsEnabled(boolean eventsEnabled) {
+		this.eventsEnabled = eventsEnabled;
+	}
 
-    public void setMinimumQuickLoginWaitSeconds(Integer minimumQuickLoginWaitSeconds) {
-        this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
-    }
+	public Long getEventsExpiration() {
+		return eventsExpiration;
+	}
 
-    public Integer getWaitIncrementSeconds() {
-        return waitIncrementSeconds;
-    }
+	public void setEventsExpiration(long eventsExpiration) {
+		this.eventsExpiration = eventsExpiration;
+	}
 
-    public void setWaitIncrementSeconds(Integer waitIncrementSeconds) {
-        this.waitIncrementSeconds = waitIncrementSeconds;
-    }
+	public List<String> getEventsListeners() {
+		return eventsListeners;
+	}
 
-    public Long getQuickLoginCheckMilliSeconds() {
-        return quickLoginCheckMilliSeconds;
-    }
+	public void setEventsListeners(List<String> eventsListeners) {
+		this.eventsListeners = eventsListeners;
+	}
 
-    public void setQuickLoginCheckMilliSeconds(Long quickLoginCheckMilliSeconds) {
-        this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
-    }
+	public List<UserFederationProviderRepresentation> getUserFederationProviders() {
+		return userFederationProviders;
+	}
 
-    public Integer getMaxDeltaTimeSeconds() {
-        return maxDeltaTimeSeconds;
-    }
+	public void setUserFederationProviders(List<UserFederationProviderRepresentation> userFederationProviders) {
+		this.userFederationProviders = userFederationProviders;
+	}
 
-    public void setMaxDeltaTimeSeconds(Integer maxDeltaTimeSeconds) {
-        this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
-    }
+	public List<IdentityProviderRepresentation> getIdentityProviders() {
+		if (this.identityProviders == null) {
+			this.identityProviders = new ArrayList<IdentityProviderRepresentation>();
+		}
+
+		return identityProviders;
+	}
 
-    public Integer getFailureFactor() {
-        return failureFactor;
-    }
+	public void setIdentityProviders(List<IdentityProviderRepresentation> identityProviders) {
+		this.identityProviders = identityProviders;
+	}
 
-    public void setFailureFactor(Integer failureFactor) {
-        this.failureFactor = failureFactor;
-    }
+	public void addIdentityProvider(IdentityProviderRepresentation identityProviderRepresentation) {
+		getIdentityProviders().add(identityProviderRepresentation);
+	}
 
-    public Boolean isEventsEnabled() {
-        return eventsEnabled;
-    }
+	public boolean isIdentityFederationEnabled() {
+		return !getIdentityProviders().isEmpty();
+	}
 
-    public void setEventsEnabled(boolean eventsEnabled) {
-        this.eventsEnabled = eventsEnabled;
-    }
+	public List<ProtocolMapperRepresentation> getProtocolMappers() {
+		return protocolMappers;
+	}
 
-    public Long getEventsExpiration() {
-        return eventsExpiration;
-    }
-
-    public void setEventsExpiration(long eventsExpiration) {
-        this.eventsExpiration = eventsExpiration;
-    }
-
-    public List<String> getEventsListeners() {
-        return eventsListeners;
-    }
-
-    public void setEventsListeners(List<String> eventsListeners) {
-        this.eventsListeners = eventsListeners;
-    }
-
-    public List<UserFederationProviderRepresentation> getUserFederationProviders() {
-        return userFederationProviders;
-    }
-
-    public void setUserFederationProviders(List<UserFederationProviderRepresentation> userFederationProviders) {
-        this.userFederationProviders = userFederationProviders;
-    }
-
-    public List<IdentityProviderRepresentation> getIdentityProviders() {
-        if (this.identityProviders == null) {
-            this.identityProviders = new ArrayList<IdentityProviderRepresentation>();
-        }
-
-        return identityProviders;
-    }
-
-    public void setIdentityProviders(List<IdentityProviderRepresentation> identityProviders) {
-        this.identityProviders = identityProviders;
-    }
-
-    public void addIdentityProvider(IdentityProviderRepresentation identityProviderRepresentation) {
-        getIdentityProviders().add(identityProviderRepresentation);
-    }
-
-    public boolean isIdentityFederationEnabled() {
-        return !getIdentityProviders().isEmpty();
-    }
-
-    public List<ProtocolMapperRepresentation> getProtocolMappers() {
-        return protocolMappers;
-    }
-
-    public void addProtocolMapper(ProtocolMapperRepresentation rep) {
-        if (protocolMappers == null) protocolMappers = new LinkedList<ProtocolMapperRepresentation>();
-        protocolMappers.add(rep);
-    }
-
-    public void setProtocolMappers(List<ProtocolMapperRepresentation> protocolMappers) {
-        this.protocolMappers = protocolMappers;
-    }
+	public void addProtocolMapper(ProtocolMapperRepresentation rep) {
+		if (protocolMappers == null)
+			protocolMappers = new LinkedList<ProtocolMapperRepresentation>();
+		protocolMappers.add(rep);
+	}
+
+	public void setProtocolMappers(List<ProtocolMapperRepresentation> protocolMappers) {
+		this.protocolMappers = protocolMappers;
+	}
 }
diff --git a/events/api/src/main/java/org/keycloak/events/Errors.java b/events/api/src/main/java/org/keycloak/events/Errors.java
index 7a4404d..282b5e4 100755
--- a/events/api/src/main/java/org/keycloak/events/Errors.java
+++ b/events/api/src/main/java/org/keycloak/events/Errors.java
@@ -41,6 +41,7 @@ public interface Errors {
     String NOT_ALLOWED = "not_allowed";
 
     String FEDERATED_IDENTITY_EMAIL_EXISTS = "federated_identity_email_exists";
+    String FEDERATED_IDENTITY_REGISTRATION_EMAIL_MISSING = "federated_identity_registration_email_missing";
     String FEDERATED_IDENTITY_USERNAME_EXISTS = "federated_identity_username_exists";
     String SSL_REQUIRED = "ssl_required";
 
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-login-settings.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-login-settings.html
index bd1bab9..e491c21 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-login-settings.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-login-settings.html
@@ -12,7 +12,14 @@
                         <div class="col-sm-4">
                             <input ng-model="realm.registrationAllowed" name="registrationAllowed" id="registrationAllowed" onoffswitch />
                         </div>
-                        <span tooltip-placement="right" tooltip="Enable/disable the registration page.  A link for registration will show on login page too." class="fa fa-info-circle"></span>
+                        <span tooltip-placement="right" tooltip="Enable/disable the registration page. A link for registration will show on login page too." class="fa fa-info-circle"></span>
+                    </div>
+                    <div class="form-group" ng-show="registrationAllowed">
+                        <label for="registrationEmailAsUsername" class="col-sm-2 control-label">Email as username</label>
+                        <div class="col-sm-4">
+                            <input ng-model="realm.registrationEmailAsUsername" name="registrationEmailAsUsername" id="registrationEmailAsUsername" onoffswitch />
+                        </div>
+                        <span tooltip-placement="right" tooltip="If enabled then username field is hidden from registration form and email is used as username for new user." class="fa fa-info-circle"></span>
                     </div>
                     <div class="form-group">
                         <label for="resetPasswordAllowed" class="col-sm-2 control-label">Forget password</label>
diff --git a/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties b/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
index 2f43473..0a59a69 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
+++ b/forms/common-themes/src/main/resources/theme/login/base/messages/messages.properties
@@ -62,6 +62,7 @@ emailExists=Email already exists
 
 federatedIdentityEmailExists=User with email already exists. Please login to account management to link the account.
 federatedIdentityUsernameExists=User with username already exists. Please login to account management to link the account.
+federatedIdentityRegistrationEmailMissing=Email is not provided. Use another provider to create account please.  
 
 loginTitle=Log in to
 loginOauthTitle=Temporary access.
diff --git a/forms/common-themes/src/main/resources/theme/login/base/register.ftl b/forms/common-themes/src/main/resources/theme/login/base/register.ftl
index b827865..492fbab 100755
--- a/forms/common-themes/src/main/resources/theme/login/base/register.ftl
+++ b/forms/common-themes/src/main/resources/theme/login/base/register.ftl
@@ -6,6 +6,7 @@
         ${rb.registerWith} <strong>${realm.name}</strong>
     <#elseif section = "form">
         <form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.registrationAction}" method="post">
+          <#if !realm.registrationEmailAsUsername>
             <div class="${properties.kcFormGroupClass!}">
                 <div class="${properties.kcLabelWrapperClass!}">
                     <label for="username" class="${properties.kcLabelClass!}">${rb.username}</label>
@@ -14,7 +15,7 @@
                     <input type="text" id="username" class="${properties.kcInputClass!}" name="username" value="${(register.formData.username!'')?html}" />
                 </div>
             </div>
-
+          </#if>
             <div class="${properties.kcFormGroupClass!}">
                 <div class="${properties.kcLabelWrapperClass!}">
                     <label for="firstName" class="${properties.kcLabelClass!}">${rb.firstName}</label>
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/RealmBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/RealmBean.java
index f751cf9..499474d 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/RealmBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/RealmBean.java
@@ -30,39 +30,43 @@ import org.keycloak.representations.idm.CredentialRepresentation;
  */
 public class RealmBean {
 
-    private RealmModel realm;
+	private RealmModel realm;
 
-    public RealmBean(RealmModel realmModel) {
-        realm = realmModel;
-    }
+	public RealmBean(RealmModel realmModel) {
+		realm = realmModel;
+	}
 
-    public String getName() {
-        return realm.getName();
-    }
+	public String getName() {
+		return realm.getName();
+	}
 
-    public boolean isIdentityFederationEnabled() {
-        return realm.isIdentityFederationEnabled();
-    }
+	public boolean isIdentityFederationEnabled() {
+		return realm.isIdentityFederationEnabled();
+	}
 
-    public boolean isRegistrationAllowed() {
-        return realm.isRegistrationAllowed();
-    }
+	public boolean isRegistrationAllowed() {
+		return realm.isRegistrationAllowed();
+	}
 
-    public boolean isResetPasswordAllowed() {
-        return realm.isResetPasswordAllowed();
-    }
+	public boolean isRegistrationEmailAsUsername() {
+		return realm.isRegistrationEmailAsUsername();
+	}
 
-    public boolean isRememberMe() {
-        return realm.isRememberMe();
-    }
+	public boolean isResetPasswordAllowed() {
+		return realm.isResetPasswordAllowed();
+	}
 
-    public boolean isPassword() {
-        for (RequiredCredentialModel r : realm.getRequiredCredentials()) {
-            if (r.getType().equals(CredentialRepresentation.PASSWORD)) {
-                return true;
-            }
-        }
-        return false;
-    }
+	public boolean isRememberMe() {
+		return realm.isRememberMe();
+	}
+
+	public boolean isPassword() {
+		for (RequiredCredentialModel r : realm.getRequiredCredentials()) {
+			if (r.getType().equals(CredentialRepresentation.PASSWORD)) {
+				return true;
+			}
+		}
+		return false;
+	}
 
 }
diff --git a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
index 17792e5..203c0b9 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
@@ -10,394 +10,402 @@ import java.util.Map;
  */
 public class RealmEntity extends AbstractIdentifiableEntity {
 
-    private String name;
-    private boolean enabled;
-    private String sslRequired;
-    private boolean registrationAllowed;
-    private boolean rememberMe;
-    private boolean verifyEmail;
-    private boolean passwordCredentialGrantAllowed;
-    private boolean resetPasswordAllowed;
-    private String passwordPolicy;
-    //--- brute force settings
-    private boolean bruteForceProtected;
-    private int maxFailureWaitSeconds;
-    private int minimumQuickLoginWaitSeconds;
-    private int waitIncrementSeconds;
-    private long quickLoginCheckMilliSeconds;
-    private int maxDeltaTimeSeconds;
-    private int failureFactor;
-    //--- end brute force settings
-
-    private int ssoSessionIdleTimeout;
-    private int ssoSessionMaxLifespan;
-    private int accessTokenLifespan;
-    private int accessCodeLifespan;
-    private int accessCodeLifespanUserAction;
-    private int accessCodeLifespanLogin;
-    private int notBefore;
-
-    private String publicKeyPem;
-    private String privateKeyPem;
-    private String certificatePem;
-    private String codeSecret;
-
-    private String loginTheme;
-    private String accountTheme;
-    private String adminTheme;
-    private String emailTheme;
-
-    // We are using names of defaultRoles (not ids)
-    private List<String> defaultRoles = new ArrayList<String>();
-
-    private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
-    private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
-    private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
-
-    private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
-    private Map<String, String> smtpConfig = new HashMap<String, String>();
-    private Map<String, String> socialConfig = new HashMap<String, String>();
-
-    private boolean eventsEnabled;
-    private long eventsExpiration;
-    private List<String> eventsListeners = new ArrayList<String>();
-
-    private String adminAppId;
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    public String getSslRequired() {
-        return sslRequired;
-    }
-
-    public void setSslRequired(String sslRequired) {
-        this.sslRequired = sslRequired;
-    }
-
-    public boolean isPasswordCredentialGrantAllowed() {
-        return passwordCredentialGrantAllowed;
-    }
-
-    public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
-        this.passwordCredentialGrantAllowed = passwordCredentialGrantAllowed;
-    }
-
-    public boolean isRegistrationAllowed() {
-        return registrationAllowed;
-    }
-
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        this.registrationAllowed = registrationAllowed;
-    }
-
-    public boolean isRememberMe() {
-        return rememberMe;
-    }
-
-    public void setRememberMe(boolean rememberMe) {
-        this.rememberMe = rememberMe;
-    }
-
-    public boolean isVerifyEmail() {
-        return verifyEmail;
-    }
-
-    public void setVerifyEmail(boolean verifyEmail) {
-        this.verifyEmail = verifyEmail;
-    }
-
-    public boolean isResetPasswordAllowed() {
-        return resetPasswordAllowed;
-    }
-
-    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
-        this.resetPasswordAllowed = resetPasswordAllowed;
-    }
+	private String name;
+	private boolean enabled;
+	private String sslRequired;
+	private boolean registrationAllowed;
+	protected boolean registrationEmailAsUsername;
+	private boolean rememberMe;
+	private boolean verifyEmail;
+	private boolean passwordCredentialGrantAllowed;
+	private boolean resetPasswordAllowed;
+	private String passwordPolicy;
+	// --- brute force settings
+	private boolean bruteForceProtected;
+	private int maxFailureWaitSeconds;
+	private int minimumQuickLoginWaitSeconds;
+	private int waitIncrementSeconds;
+	private long quickLoginCheckMilliSeconds;
+	private int maxDeltaTimeSeconds;
+	private int failureFactor;
+	// --- end brute force settings
+
+	private int ssoSessionIdleTimeout;
+	private int ssoSessionMaxLifespan;
+	private int accessTokenLifespan;
+	private int accessCodeLifespan;
+	private int accessCodeLifespanUserAction;
+	private int accessCodeLifespanLogin;
+	private int notBefore;
+
+	private String publicKeyPem;
+	private String privateKeyPem;
+	private String certificatePem;
+	private String codeSecret;
+
+	private String loginTheme;
+	private String accountTheme;
+	private String adminTheme;
+	private String emailTheme;
+
+	// We are using names of defaultRoles (not ids)
+	private List<String> defaultRoles = new ArrayList<String>();
+
+	private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
+	private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
+	private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
+
+	private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
+	private Map<String, String> smtpConfig = new HashMap<String, String>();
+	private Map<String, String> socialConfig = new HashMap<String, String>();
+
+	private boolean eventsEnabled;
+	private long eventsExpiration;
+	private List<String> eventsListeners = new ArrayList<String>();
+
+	private String adminAppId;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public String getSslRequired() {
+		return sslRequired;
+	}
+
+	public void setSslRequired(String sslRequired) {
+		this.sslRequired = sslRequired;
+	}
+
+	public boolean isPasswordCredentialGrantAllowed() {
+		return passwordCredentialGrantAllowed;
+	}
+
+	public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
+		this.passwordCredentialGrantAllowed = passwordCredentialGrantAllowed;
+	}
+
+	public boolean isRegistrationAllowed() {
+		return registrationAllowed;
+	}
+
+	public void setRegistrationAllowed(boolean registrationAllowed) {
+		this.registrationAllowed = registrationAllowed;
+	}
+
+	public boolean isRegistrationEmailAsUsername() {
+		return registrationEmailAsUsername;
+	}
+
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		this.registrationEmailAsUsername = registrationEmailAsUsername;
+	}
+
+	public boolean isRememberMe() {
+		return rememberMe;
+	}
+
+	public void setRememberMe(boolean rememberMe) {
+		this.rememberMe = rememberMe;
+	}
+
+	public boolean isVerifyEmail() {
+		return verifyEmail;
+	}
+
+	public void setVerifyEmail(boolean verifyEmail) {
+		this.verifyEmail = verifyEmail;
+	}
 
-    public String getPasswordPolicy() {
-        return passwordPolicy;
-    }
-
-    public void setPasswordPolicy(String passwordPolicy) {
-        this.passwordPolicy = passwordPolicy;
-    }
+	public boolean isResetPasswordAllowed() {
+		return resetPasswordAllowed;
+	}
 
-    public boolean isBruteForceProtected() {
-        return bruteForceProtected;
-    }
+	public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+		this.resetPasswordAllowed = resetPasswordAllowed;
+	}
 
-    public void setBruteForceProtected(boolean bruteForceProtected) {
-        this.bruteForceProtected = bruteForceProtected;
-    }
+	public String getPasswordPolicy() {
+		return passwordPolicy;
+	}
 
-    public int getMaxFailureWaitSeconds() {
-        return maxFailureWaitSeconds;
-    }
+	public void setPasswordPolicy(String passwordPolicy) {
+		this.passwordPolicy = passwordPolicy;
+	}
 
-    public void setMaxFailureWaitSeconds(int maxFailureWaitSeconds) {
-        this.maxFailureWaitSeconds = maxFailureWaitSeconds;
-    }
+	public boolean isBruteForceProtected() {
+		return bruteForceProtected;
+	}
 
-    public int getMinimumQuickLoginWaitSeconds() {
-        return minimumQuickLoginWaitSeconds;
-    }
+	public void setBruteForceProtected(boolean bruteForceProtected) {
+		this.bruteForceProtected = bruteForceProtected;
+	}
 
-    public void setMinimumQuickLoginWaitSeconds(int minimumQuickLoginWaitSeconds) {
-        this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
-    }
+	public int getMaxFailureWaitSeconds() {
+		return maxFailureWaitSeconds;
+	}
 
-    public int getWaitIncrementSeconds() {
-        return waitIncrementSeconds;
-    }
+	public void setMaxFailureWaitSeconds(int maxFailureWaitSeconds) {
+		this.maxFailureWaitSeconds = maxFailureWaitSeconds;
+	}
 
-    public void setWaitIncrementSeconds(int waitIncrementSeconds) {
-        this.waitIncrementSeconds = waitIncrementSeconds;
-    }
+	public int getMinimumQuickLoginWaitSeconds() {
+		return minimumQuickLoginWaitSeconds;
+	}
 
-    public long getQuickLoginCheckMilliSeconds() {
-        return quickLoginCheckMilliSeconds;
-    }
+	public void setMinimumQuickLoginWaitSeconds(int minimumQuickLoginWaitSeconds) {
+		this.minimumQuickLoginWaitSeconds = minimumQuickLoginWaitSeconds;
+	}
 
-    public void setQuickLoginCheckMilliSeconds(long quickLoginCheckMilliSeconds) {
-        this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
-    }
+	public int getWaitIncrementSeconds() {
+		return waitIncrementSeconds;
+	}
 
-    public int getMaxDeltaTimeSeconds() {
-        return maxDeltaTimeSeconds;
-    }
+	public void setWaitIncrementSeconds(int waitIncrementSeconds) {
+		this.waitIncrementSeconds = waitIncrementSeconds;
+	}
 
-    public void setMaxDeltaTimeSeconds(int maxDeltaTimeSeconds) {
-        this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
-    }
+	public long getQuickLoginCheckMilliSeconds() {
+		return quickLoginCheckMilliSeconds;
+	}
 
-    public int getFailureFactor() {
-        return failureFactor;
-    }
+	public void setQuickLoginCheckMilliSeconds(long quickLoginCheckMilliSeconds) {
+		this.quickLoginCheckMilliSeconds = quickLoginCheckMilliSeconds;
+	}
 
-    public void setFailureFactor(int failureFactor) {
-        this.failureFactor = failureFactor;
-    }
+	public int getMaxDeltaTimeSeconds() {
+		return maxDeltaTimeSeconds;
+	}
 
-    public int getSsoSessionIdleTimeout() {
-        return ssoSessionIdleTimeout;
-    }
+	public void setMaxDeltaTimeSeconds(int maxDeltaTimeSeconds) {
+		this.maxDeltaTimeSeconds = maxDeltaTimeSeconds;
+	}
 
-    public void setSsoSessionIdleTimeout(int ssoSessionIdleTimeout) {
-        this.ssoSessionIdleTimeout = ssoSessionIdleTimeout;
-    }
+	public int getFailureFactor() {
+		return failureFactor;
+	}
 
-    public int getSsoSessionMaxLifespan() {
-        return ssoSessionMaxLifespan;
-    }
+	public void setFailureFactor(int failureFactor) {
+		this.failureFactor = failureFactor;
+	}
 
-    public void setSsoSessionMaxLifespan(int ssoSessionMaxLifespan) {
-        this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
-    }
+	public int getSsoSessionIdleTimeout() {
+		return ssoSessionIdleTimeout;
+	}
 
-    public int getAccessTokenLifespan() {
-        return accessTokenLifespan;
-    }
+	public void setSsoSessionIdleTimeout(int ssoSessionIdleTimeout) {
+		this.ssoSessionIdleTimeout = ssoSessionIdleTimeout;
+	}
 
-    public void setAccessTokenLifespan(int accessTokenLifespan) {
-        this.accessTokenLifespan = accessTokenLifespan;
-    }
+	public int getSsoSessionMaxLifespan() {
+		return ssoSessionMaxLifespan;
+	}
 
-    public int getAccessCodeLifespan() {
-        return accessCodeLifespan;
-    }
+	public void setSsoSessionMaxLifespan(int ssoSessionMaxLifespan) {
+		this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
+	}
 
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        this.accessCodeLifespan = accessCodeLifespan;
-    }
+	public int getAccessTokenLifespan() {
+		return accessTokenLifespan;
+	}
 
-    public int getAccessCodeLifespanUserAction() {
-        return accessCodeLifespanUserAction;
-    }
+	public void setAccessTokenLifespan(int accessTokenLifespan) {
+		this.accessTokenLifespan = accessTokenLifespan;
+	}
 
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
-    }
-    public int getAccessCodeLifespanLogin() {
-        return accessCodeLifespanLogin;
-    }
+	public int getAccessCodeLifespan() {
+		return accessCodeLifespan;
+	}
 
-    public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
-        this.accessCodeLifespanLogin = accessCodeLifespanLogin;
-    }
+	public void setAccessCodeLifespan(int accessCodeLifespan) {
+		this.accessCodeLifespan = accessCodeLifespan;
+	}
 
-    public int getNotBefore() {
-        return notBefore;
-    }
+	public int getAccessCodeLifespanUserAction() {
+		return accessCodeLifespanUserAction;
+	}
 
-    public void setNotBefore(int notBefore) {
-        this.notBefore = notBefore;
-    }
+	public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+		this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
+	}
 
-    public String getPublicKeyPem() {
-        return publicKeyPem;
-    }
+	public int getAccessCodeLifespanLogin() {
+		return accessCodeLifespanLogin;
+	}
 
-    public void setPublicKeyPem(String publicKeyPem) {
-        this.publicKeyPem = publicKeyPem;
-    }
+	public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
+		this.accessCodeLifespanLogin = accessCodeLifespanLogin;
+	}
 
-    public String getPrivateKeyPem() {
-        return privateKeyPem;
-    }
+	public int getNotBefore() {
+		return notBefore;
+	}
 
-    public void setPrivateKeyPem(String privateKeyPem) {
-        this.privateKeyPem = privateKeyPem;
-    }
+	public void setNotBefore(int notBefore) {
+		this.notBefore = notBefore;
+	}
 
-    public String getCodeSecret() {
-        return codeSecret;
-    }
+	public String getPublicKeyPem() {
+		return publicKeyPem;
+	}
 
-    public void setCodeSecret(String codeSecret) {
-        this.codeSecret = codeSecret;
-    }
+	public void setPublicKeyPem(String publicKeyPem) {
+		this.publicKeyPem = publicKeyPem;
+	}
 
-    public String getLoginTheme() {
-        return loginTheme;
-    }
+	public String getPrivateKeyPem() {
+		return privateKeyPem;
+	}
 
-    public void setLoginTheme(String loginTheme) {
-        this.loginTheme = loginTheme;
-    }
+	public void setPrivateKeyPem(String privateKeyPem) {
+		this.privateKeyPem = privateKeyPem;
+	}
 
-    public String getAccountTheme() {
-        return accountTheme;
-    }
+	public String getCodeSecret() {
+		return codeSecret;
+	}
 
-    public void setAccountTheme(String accountTheme) {
-        this.accountTheme = accountTheme;
-    }
+	public void setCodeSecret(String codeSecret) {
+		this.codeSecret = codeSecret;
+	}
 
-    public String getAdminTheme() {
-        return adminTheme;
-    }
+	public String getLoginTheme() {
+		return loginTheme;
+	}
 
-    public void setAdminTheme(String adminTheme) {
-        this.adminTheme = adminTheme;
-    }
+	public void setLoginTheme(String loginTheme) {
+		this.loginTheme = loginTheme;
+	}
 
-    public String getEmailTheme() {
-        return emailTheme;
-    }
-
-    public void setEmailTheme(String emailTheme) {
-        this.emailTheme = emailTheme;
-    }
-
-    public List<String> getDefaultRoles() {
-        return defaultRoles;
-    }
-
-    public void setDefaultRoles(List<String> defaultRoles) {
-        this.defaultRoles = defaultRoles;
-    }
-
-    public List<RequiredCredentialEntity> getRequiredCredentials() {
-        return requiredCredentials;
-    }
-
-    public void setRequiredCredentials(List<RequiredCredentialEntity> requiredCredentials) {
-        this.requiredCredentials = requiredCredentials;
-    }
-
-    public Map<String, String> getBrowserSecurityHeaders() {
-        return browserSecurityHeaders;
-    }
-
-    public void setBrowserSecurityHeaders(Map<String, String> browserSecurityHeaders) {
-        this.browserSecurityHeaders = browserSecurityHeaders;
-    }
-
-    public Map<String, String> getSmtpConfig() {
-        return smtpConfig;
-    }
-
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        this.smtpConfig = smtpConfig;
-    }
+	public String getAccountTheme() {
+		return accountTheme;
+	}
 
-    public Map<String, String> getSocialConfig() {
-        return socialConfig;
-    }
+	public void setAccountTheme(String accountTheme) {
+		this.accountTheme = accountTheme;
+	}
 
-    public void setSocialConfig(Map<String, String> socialConfig) {
-        this.socialConfig = socialConfig;
-    }
+	public String getAdminTheme() {
+		return adminTheme;
+	}
 
-    public boolean isEventsEnabled() {
-        return eventsEnabled;
-    }
+	public void setAdminTheme(String adminTheme) {
+		this.adminTheme = adminTheme;
+	}
 
-    public void setEventsEnabled(boolean eventsEnabled) {
-        this.eventsEnabled = eventsEnabled;
-    }
+	public String getEmailTheme() {
+		return emailTheme;
+	}
 
-    public long getEventsExpiration() {
-        return eventsExpiration;
-    }
+	public void setEmailTheme(String emailTheme) {
+		this.emailTheme = emailTheme;
+	}
 
-    public void setEventsExpiration(long eventsExpiration) {
-        this.eventsExpiration = eventsExpiration;
-    }
+	public List<String> getDefaultRoles() {
+		return defaultRoles;
+	}
 
-    public List<String> getEventsListeners() {
-        return eventsListeners;
-    }
+	public void setDefaultRoles(List<String> defaultRoles) {
+		this.defaultRoles = defaultRoles;
+	}
 
-    public void setEventsListeners(List<String> eventsListeners) {
-        this.eventsListeners = eventsListeners;
-    }
+	public List<RequiredCredentialEntity> getRequiredCredentials() {
+		return requiredCredentials;
+	}
 
-    public String getAdminAppId() {
-        return adminAppId;
-    }
+	public void setRequiredCredentials(List<RequiredCredentialEntity> requiredCredentials) {
+		this.requiredCredentials = requiredCredentials;
+	}
 
-    public void setAdminAppId(String adminAppId) {
-        this.adminAppId = adminAppId;
-    }
+	public Map<String, String> getBrowserSecurityHeaders() {
+		return browserSecurityHeaders;
+	}
 
-    public List<UserFederationProviderEntity> getUserFederationProviders() {
-        return userFederationProviders;
-    }
+	public void setBrowserSecurityHeaders(Map<String, String> browserSecurityHeaders) {
+		this.browserSecurityHeaders = browserSecurityHeaders;
+	}
 
-    public void setUserFederationProviders(List<UserFederationProviderEntity> userFederationProviders) {
-        this.userFederationProviders = userFederationProviders;
-    }
+	public Map<String, String> getSmtpConfig() {
+		return smtpConfig;
+	}
 
-    public List<IdentityProviderEntity> getIdentityProviders() {
-        return identityProviders;
-    }
+	public void setSmtpConfig(Map<String, String> smtpConfig) {
+		this.smtpConfig = smtpConfig;
+	}
 
-    public void setIdentityProviders(List<IdentityProviderEntity> identityProviders) {
-        this.identityProviders = identityProviders;
-    }
+	public Map<String, String> getSocialConfig() {
+		return socialConfig;
+	}
 
-    public String getCertificatePem() {
-        return certificatePem;
-    }
+	public void setSocialConfig(Map<String, String> socialConfig) {
+		this.socialConfig = socialConfig;
+	}
 
-    public void setCertificatePem(String certificatePem) {
-        this.certificatePem = certificatePem;
-    }
-}
+	public boolean isEventsEnabled() {
+		return eventsEnabled;
+	}
+
+	public void setEventsEnabled(boolean eventsEnabled) {
+		this.eventsEnabled = eventsEnabled;
+	}
+
+	public long getEventsExpiration() {
+		return eventsExpiration;
+	}
+
+	public void setEventsExpiration(long eventsExpiration) {
+		this.eventsExpiration = eventsExpiration;
+	}
+
+	public List<String> getEventsListeners() {
+		return eventsListeners;
+	}
+
+	public void setEventsListeners(List<String> eventsListeners) {
+		this.eventsListeners = eventsListeners;
+	}
+
+	public String getAdminAppId() {
+		return adminAppId;
+	}
 
+	public void setAdminAppId(String adminAppId) {
+		this.adminAppId = adminAppId;
+	}
 
+	public List<UserFederationProviderEntity> getUserFederationProviders() {
+		return userFederationProviders;
+	}
+
+	public void setUserFederationProviders(List<UserFederationProviderEntity> userFederationProviders) {
+		this.userFederationProviders = userFederationProviders;
+	}
+
+	public List<IdentityProviderEntity> getIdentityProviders() {
+		return identityProviders;
+	}
+
+	public void setIdentityProviders(List<IdentityProviderEntity> identityProviders) {
+		this.identityProviders = identityProviders;
+	}
+
+	public String getCertificatePem() {
+		return certificatePem;
+	}
+
+	public void setCertificatePem(String certificatePem) {
+		this.certificatePem = certificatePem;
+	}
+}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 4212e3b..b1781bd 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -1,8 +1,5 @@
 package org.keycloak.models;
 
-import org.keycloak.enums.SslRequired;
-import org.keycloak.provider.ProviderEvent;
-
 import java.security.Key;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -11,233 +8,272 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.keycloak.enums.SslRequired;
+import org.keycloak.provider.ProviderEvent;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public interface RealmModel extends RoleContainerModel {
-    interface RealmCreationEvent extends ProviderEvent {
-        RealmModel getCreatedRealm();
-    }
-    interface ClientCreationEvent extends ProviderEvent {
-        ClientModel getCreatedClient();
-    }
-    interface ApplicationCreationEvent extends ClientCreationEvent {
-        ApplicationModel getCreatedApplication();
-    }
-    interface OAuthClientCreationEvent extends ClientCreationEvent {
-        OAuthClientModel getCreatedOAuthClient();
-    }
+	interface RealmCreationEvent extends ProviderEvent {
+		RealmModel getCreatedRealm();
+	}
+
+	interface ClientCreationEvent extends ProviderEvent {
+		ClientModel getCreatedClient();
+	}
+
+	interface ApplicationCreationEvent extends ClientCreationEvent {
+		ApplicationModel getCreatedApplication();
+	}
+
+	interface OAuthClientCreationEvent extends ClientCreationEvent {
+		OAuthClientModel getCreatedOAuthClient();
+	}
+
+	String getId();
+
+	String getName();
+
+	void setName(String name);
+
+	boolean isEnabled();
+
+	void setEnabled(boolean enabled);
+
+	SslRequired getSslRequired();
+
+	void setSslRequired(SslRequired sslRequired);
+
+	boolean isRegistrationAllowed();
+
+	void setRegistrationAllowed(boolean registrationAllowed);
+
+	public boolean isRegistrationEmailAsUsername();
+
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername);
+
+	boolean isPasswordCredentialGrantAllowed();
+
+	void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed);
+
+	boolean isRememberMe();
+
+	void setRememberMe(boolean rememberMe);
+
+	// --- brute force settings
+	boolean isBruteForceProtected();
+
+	void setBruteForceProtected(boolean value);
+
+	int getMaxFailureWaitSeconds();
+
+	void setMaxFailureWaitSeconds(int val);
+
+	int getWaitIncrementSeconds();
+
+	void setWaitIncrementSeconds(int val);
+
+	int getMinimumQuickLoginWaitSeconds();
+
+	void setMinimumQuickLoginWaitSeconds(int val);
+
+	long getQuickLoginCheckMilliSeconds();
+
+	void setQuickLoginCheckMilliSeconds(long val);
+
+	int getMaxDeltaTimeSeconds();
+
+	void setMaxDeltaTimeSeconds(int val);
+
+	int getFailureFactor();
+
+	void setFailureFactor(int failureFactor);
+
+	// --- end brute force settings
 
-    String getId();
+	boolean isVerifyEmail();
 
-    String getName();
+	void setVerifyEmail(boolean verifyEmail);
 
-    void setName(String name);
+	boolean isResetPasswordAllowed();
 
-    boolean isEnabled();
+	void setResetPasswordAllowed(boolean resetPasswordAllowed);
 
-    void setEnabled(boolean enabled);
+	int getSsoSessionIdleTimeout();
 
-    SslRequired getSslRequired();
+	void setSsoSessionIdleTimeout(int seconds);
 
-    void setSslRequired(SslRequired sslRequired);
+	int getSsoSessionMaxLifespan();
 
-    boolean isRegistrationAllowed();
+	void setSsoSessionMaxLifespan(int seconds);
 
-    void setRegistrationAllowed(boolean registrationAllowed);
+	int getAccessTokenLifespan();
 
-    boolean isPasswordCredentialGrantAllowed();
+	void setAccessTokenLifespan(int seconds);
 
-    void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed);
+	int getAccessCodeLifespan();
 
-    boolean isRememberMe();
+	void setAccessCodeLifespan(int seconds);
 
-    void setRememberMe(boolean rememberMe);
+	int getAccessCodeLifespanUserAction();
 
-    //--- brute force settings
-    boolean isBruteForceProtected();
-    void setBruteForceProtected(boolean value);
-    int getMaxFailureWaitSeconds();
-    void setMaxFailureWaitSeconds(int val);
-    int getWaitIncrementSeconds();
-    void setWaitIncrementSeconds(int val);
-    int getMinimumQuickLoginWaitSeconds();
-    void setMinimumQuickLoginWaitSeconds(int val);
-    long getQuickLoginCheckMilliSeconds();
-    void setQuickLoginCheckMilliSeconds(long val);
-    int getMaxDeltaTimeSeconds();
-    void setMaxDeltaTimeSeconds(int val);
-    int getFailureFactor();
-    void setFailureFactor(int failureFactor);
-    //--- end brute force settings
+	void setAccessCodeLifespanUserAction(int seconds);
 
+	int getAccessCodeLifespanLogin();
 
-    boolean isVerifyEmail();
+	void setAccessCodeLifespanLogin(int seconds);
 
-    void setVerifyEmail(boolean verifyEmail);
+	String getPublicKeyPem();
 
-    boolean isResetPasswordAllowed();
+	void setPublicKeyPem(String publicKeyPem);
 
-    void setResetPasswordAllowed(boolean resetPasswordAllowed);
+	String getPrivateKeyPem();
 
-    int getSsoSessionIdleTimeout();
-    void setSsoSessionIdleTimeout(int seconds);
+	void setPrivateKeyPem(String privateKeyPem);
 
-    int getSsoSessionMaxLifespan();
-    void setSsoSessionMaxLifespan(int seconds);
+	PublicKey getPublicKey();
 
-    int getAccessTokenLifespan();
+	void setPublicKey(PublicKey publicKey);
 
-    void setAccessTokenLifespan(int seconds);
+	String getCodeSecret();
 
-    int getAccessCodeLifespan();
+	Key getCodeSecretKey();
 
-    void setAccessCodeLifespan(int seconds);
+	void setCodeSecret(String codeSecret);
 
-    int getAccessCodeLifespanUserAction();
+	X509Certificate getCertificate();
 
-    void setAccessCodeLifespanUserAction(int seconds);
+	void setCertificate(X509Certificate certificate);
 
-    int getAccessCodeLifespanLogin();
+	String getCertificatePem();
 
-    void setAccessCodeLifespanLogin(int seconds);
+	void setCertificatePem(String certificate);
 
-    String getPublicKeyPem();
+	PrivateKey getPrivateKey();
 
-    void setPublicKeyPem(String publicKeyPem);
+	void setPrivateKey(PrivateKey privateKey);
 
-    String getPrivateKeyPem();
+	List<RequiredCredentialModel> getRequiredCredentials();
 
-    void setPrivateKeyPem(String privateKeyPem);
+	void addRequiredCredential(String cred);
 
-    PublicKey getPublicKey();
+	PasswordPolicy getPasswordPolicy();
 
-    void setPublicKey(PublicKey publicKey);
+	void setPasswordPolicy(PasswordPolicy policy);
 
-    String getCodeSecret();
+	RoleModel getRoleById(String id);
 
-    Key getCodeSecretKey();
+	List<String> getDefaultRoles();
 
-    void setCodeSecret(String codeSecret);
+	void addDefaultRole(String name);
 
-    X509Certificate getCertificate();
-    void setCertificate(X509Certificate certificate);
-    String getCertificatePem();
-    void setCertificatePem(String certificate);
+	void updateDefaultRoles(String[] defaultRoles);
 
-    PrivateKey getPrivateKey();
+	ClientModel findClient(String clientId);
 
-    void setPrivateKey(PrivateKey privateKey);
+	Map<String, ApplicationModel> getApplicationNameMap();
 
-    List<RequiredCredentialModel> getRequiredCredentials();
+	List<ApplicationModel> getApplications();
 
-    void addRequiredCredential(String cred);
+	ApplicationModel addApplication(String name);
 
-    PasswordPolicy getPasswordPolicy();
+	ApplicationModel addApplication(String id, String name);
 
-    void setPasswordPolicy(PasswordPolicy policy);
+	boolean removeApplication(String id);
 
-    RoleModel getRoleById(String id);
+	ApplicationModel getApplicationById(String id);
 
-    List<String> getDefaultRoles();
+	ApplicationModel getApplicationByName(String name);
 
-    void addDefaultRole(String name);
+	void updateRequiredCredentials(Set<String> creds);
 
-    void updateDefaultRoles(String[] defaultRoles);
+	OAuthClientModel addOAuthClient(String name);
 
-    ClientModel findClient(String clientId);
+	OAuthClientModel addOAuthClient(String id, String name);
 
-    Map<String, ApplicationModel> getApplicationNameMap();
+	OAuthClientModel getOAuthClient(String name);
 
-    List<ApplicationModel> getApplications();
+	OAuthClientModel getOAuthClientById(String id);
 
-    ApplicationModel addApplication(String name);
+	boolean removeOAuthClient(String id);
 
-    ApplicationModel addApplication(String id, String name);
+	List<OAuthClientModel> getOAuthClients();
 
-    boolean removeApplication(String id);
+	Map<String, String> getBrowserSecurityHeaders();
 
-    ApplicationModel getApplicationById(String id);
-    ApplicationModel getApplicationByName(String name);
+	void setBrowserSecurityHeaders(Map<String, String> headers);
 
-    void updateRequiredCredentials(Set<String> creds);
+	Map<String, String> getSmtpConfig();
 
-    OAuthClientModel addOAuthClient(String name);
+	void setSmtpConfig(Map<String, String> smtpConfig);
 
-    OAuthClientModel addOAuthClient(String id, String name);
+	List<IdentityProviderModel> getIdentityProviders();
 
-    OAuthClientModel getOAuthClient(String name);
-    OAuthClientModel getOAuthClientById(String id);
-    boolean removeOAuthClient(String id);
+	IdentityProviderModel getIdentityProviderById(String identityProviderId);
 
-    List<OAuthClientModel> getOAuthClients();
+	void addIdentityProvider(IdentityProviderModel identityProvider);
 
-    Map<String, String> getBrowserSecurityHeaders();
-    void setBrowserSecurityHeaders(Map<String, String> headers);
+	void removeIdentityProviderById(String providerId);
 
-    Map<String, String> getSmtpConfig();
+	void updateIdentityProvider(IdentityProviderModel identityProvider);
 
-    void setSmtpConfig(Map<String, String> smtpConfig);
+	List<UserFederationProviderModel> getUserFederationProviders();
 
-    List<IdentityProviderModel> getIdentityProviders();
-    IdentityProviderModel getIdentityProviderById(String identityProviderId);
-    void addIdentityProvider(IdentityProviderModel identityProvider);
-    void removeIdentityProviderById(String providerId);
-    void updateIdentityProvider(IdentityProviderModel identityProvider);
+	UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority,
+			String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync);
 
-    List<UserFederationProviderModel> getUserFederationProviders();
+	void updateUserFederationProvider(UserFederationProviderModel provider);
 
-    UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync);
-    void updateUserFederationProvider(UserFederationProviderModel provider);
-    void removeUserFederationProvider(UserFederationProviderModel provider);
-    void setUserFederationProviders(List<UserFederationProviderModel> providers);
+	void removeUserFederationProvider(UserFederationProviderModel provider);
 
-    String getLoginTheme();
+	void setUserFederationProviders(List<UserFederationProviderModel> providers);
 
-    void setLoginTheme(String name);
+	String getLoginTheme();
 
-    String getAccountTheme();
+	void setLoginTheme(String name);
 
-    void setAccountTheme(String name);
+	String getAccountTheme();
 
-    String getAdminTheme();
+	void setAccountTheme(String name);
 
-    void setAdminTheme(String name);
+	String getAdminTheme();
 
-    String getEmailTheme();
+	void setAdminTheme(String name);
 
-    void setEmailTheme(String name);
+	String getEmailTheme();
 
+	void setEmailTheme(String name);
 
-    /**
-     * Time in seconds since epoc
-     *
-     * @return
-     */
-    int getNotBefore();
+	/**
+	 * Time in seconds since epoc
+	 * 
+	 * @return
+	 */
+	int getNotBefore();
 
-    void setNotBefore(int notBefore);
+	void setNotBefore(int notBefore);
 
-    boolean removeRoleById(String id);
+	boolean removeRoleById(String id);
 
-    boolean isEventsEnabled();
+	boolean isEventsEnabled();
 
-    void setEventsEnabled(boolean enabled);
+	void setEventsEnabled(boolean enabled);
 
-    long getEventsExpiration();
+	long getEventsExpiration();
 
-    void setEventsExpiration(long expiration);
+	void setEventsExpiration(long expiration);
 
-    Set<String> getEventsListeners();
+	Set<String> getEventsListeners();
 
-    void setEventsListeners(Set<String> listeners);
+	void setEventsListeners(Set<String> listeners);
 
-    ApplicationModel getMasterAdminApp();
+	ApplicationModel getMasterAdminApp();
 
-    void setMasterAdminApp(ApplicationModel app);
+	void setMasterAdminApp(ApplicationModel app);
 
-    ClientModel findClientById(String id);
+	ClientModel findClientById(String id);
 
-    boolean isIdentityFederationEnabled();
+	boolean isIdentityFederationEnabled();
 }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index d0963df..834475e 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -1,5 +1,13 @@
 package org.keycloak.models.utils;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClaimMask;
 import org.keycloak.models.ClientIdentityProviderMappingModel;
@@ -31,337 +39,331 @@ import org.keycloak.representations.idm.UserFederationProviderRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class ModelToRepresentation {
-    public static UserRepresentation toRepresentation(UserModel user) {
-        UserRepresentation rep = new UserRepresentation();
-        rep.setId(user.getId());
-        rep.setUsername(user.getUsername());
-        rep.setLastName(user.getLastName());
-        rep.setFirstName(user.getFirstName());
-        rep.setEmail(user.getEmail());
-        rep.setEnabled(user.isEnabled());
-        rep.setEmailVerified(user.isEmailVerified());
-        rep.setTotp(user.isTotp());
-        rep.setFederationLink(user.getFederationLink());
-
-        List<String> reqActions = new ArrayList<String>();
-        for (UserModel.RequiredAction ra : user.getRequiredActions()){
-            reqActions.add(ra.name());
-        }
-
-        rep.setRequiredActions(reqActions);
-
-        if (user.getAttributes() != null && !user.getAttributes().isEmpty()) {
-            Map<String, String> attrs = new HashMap<String, String>();
-            attrs.putAll(user.getAttributes());
-            rep.setAttributes(attrs);
-        }
-        return rep;
-    }
-
-    public static RoleRepresentation toRepresentation(RoleModel role) {
-        RoleRepresentation rep = new RoleRepresentation();
-        rep.setId(role.getId());
-        rep.setName(role.getName());
-        rep.setDescription(role.getDescription());
-        rep.setComposite(role.isComposite());
-        return rep;
-    }
-
-    public static RealmRepresentation toRepresentation(RealmModel realm, boolean internal) {
-        RealmRepresentation rep = new RealmRepresentation();
-        rep.setId(realm.getId());
-        rep.setRealm(realm.getName());
-        rep.setEnabled(realm.isEnabled());
-        rep.setNotBefore(realm.getNotBefore());
-        rep.setSslRequired(realm.getSslRequired().name().toLowerCase());
-        rep.setPublicKey(realm.getPublicKeyPem());
-        if (internal) {
-            rep.setPrivateKey(realm.getPrivateKeyPem());
-            String privateKeyPem = realm.getPrivateKeyPem();
-            if (realm.getCertificatePem() == null && privateKeyPem != null) {
-                KeycloakModelUtils.generateRealmCertificate(realm);
-            }
-            rep.setCodeSecret(realm.getCodeSecret());
-        }
-        rep.setCertificate(realm.getCertificatePem());
-        rep.setPasswordCredentialGrantAllowed(realm.isPasswordCredentialGrantAllowed());
-        rep.setRegistrationAllowed(realm.isRegistrationAllowed());
-        rep.setRememberMe(realm.isRememberMe());
-        rep.setBruteForceProtected(realm.isBruteForceProtected());
-        rep.setMaxFailureWaitSeconds(realm.getMaxFailureWaitSeconds());
-        rep.setMinimumQuickLoginWaitSeconds(realm.getMinimumQuickLoginWaitSeconds());
-        rep.setWaitIncrementSeconds(realm.getWaitIncrementSeconds());
-        rep.setQuickLoginCheckMilliSeconds(realm.getQuickLoginCheckMilliSeconds());
-        rep.setMaxDeltaTimeSeconds(realm.getMaxDeltaTimeSeconds());
-        rep.setFailureFactor(realm.getFailureFactor());
-        rep.setVerifyEmail(realm.isVerifyEmail());
-        rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
-        rep.setAccessTokenLifespan(realm.getAccessTokenLifespan());
-        rep.setSsoSessionIdleTimeout(realm.getSsoSessionIdleTimeout());
-        rep.setSsoSessionMaxLifespan(realm.getSsoSessionMaxLifespan());
-        rep.setAccessCodeLifespan(realm.getAccessCodeLifespan());
-        rep.setAccessCodeLifespanUserAction(realm.getAccessCodeLifespanUserAction());
-        rep.setAccessCodeLifespanLogin(realm.getAccessCodeLifespanLogin());
-        rep.setSmtpServer(realm.getSmtpConfig());
-        rep.setBrowserSecurityHeaders(realm.getBrowserSecurityHeaders());
-        rep.setAccountTheme(realm.getAccountTheme());
-        rep.setLoginTheme(realm.getLoginTheme());
-        rep.setAdminTheme(realm.getAdminTheme());
-        rep.setEmailTheme(realm.getEmailTheme());
-        if (realm.getPasswordPolicy() != null) {
-            rep.setPasswordPolicy(realm.getPasswordPolicy().toString());
-        }
-
-        List<String> defaultRoles = realm.getDefaultRoles();
-        if (!defaultRoles.isEmpty()) {
-            List<String> roleStrings = new ArrayList<String>();
-            roleStrings.addAll(defaultRoles);
-            rep.setDefaultRoles(roleStrings);
-        }
-
-        List<RequiredCredentialModel> requiredCredentialModels = realm.getRequiredCredentials();
-        if (requiredCredentialModels.size() > 0) {
-            rep.setRequiredCredentials(new HashSet<String>());
-            for (RequiredCredentialModel cred : requiredCredentialModels) {
-                rep.getRequiredCredentials().add(cred.getType());
-            }
-        }
-
-        List<UserFederationProviderModel> fedProviderModels = realm.getUserFederationProviders();
-        if (fedProviderModels.size() > 0) {
-            List<UserFederationProviderRepresentation> fedProviderReps = new ArrayList<UserFederationProviderRepresentation>();
-            for (UserFederationProviderModel model : fedProviderModels) {
-                UserFederationProviderRepresentation fedProvRep = toRepresentation(model);
-                fedProviderReps.add(fedProvRep);
-            }
-            rep.setUserFederationProviders(fedProviderReps);
-        }
-
-        for (IdentityProviderModel provider : realm.getIdentityProviders()) {
-            rep.addIdentityProvider(toRepresentation(provider));
-        }
-
-        return rep;
-    }
-
-    public static RealmEventsConfigRepresentation toEventsConfigReprensetation(RealmModel realm) {
-        RealmEventsConfigRepresentation rep = new RealmEventsConfigRepresentation();
-        rep.setEventsEnabled(realm.isEventsEnabled());
-
-        if (realm.getEventsExpiration() != 0) {
-            rep.setEventsExpiration(realm.getEventsExpiration());
-        }
-
-        if (realm.getEventsListeners() != null) {
-            rep.setEventsListeners(new LinkedList<String>(realm.getEventsListeners()));
-        }
-        return rep;
-    }
-
-    public static CredentialRepresentation toRepresentation(UserCredentialModel cred) {
-        CredentialRepresentation rep = new CredentialRepresentation();
-        rep.setType(CredentialRepresentation.SECRET);
-        rep.setValue(cred.getValue());
-        return rep;
-    }
-
-    public static ClaimRepresentation toRepresentation(ClientModel model) {
-        ClaimRepresentation rep = new ClaimRepresentation();
-        rep.setAddress(ClaimMask.hasAddress(model.getAllowedClaimsMask()));
-        rep.setEmail(ClaimMask.hasEmail(model.getAllowedClaimsMask()));
-        rep.setGender(ClaimMask.hasGender(model.getAllowedClaimsMask()));
-        rep.setLocale(ClaimMask.hasLocale(model.getAllowedClaimsMask()));
-        rep.setName(ClaimMask.hasName(model.getAllowedClaimsMask()));
-        rep.setPhone(ClaimMask.hasPhone(model.getAllowedClaimsMask()));
-        rep.setPicture(ClaimMask.hasPicture(model.getAllowedClaimsMask()));
-        rep.setProfile(ClaimMask.hasProfile(model.getAllowedClaimsMask()));
-        rep.setWebsite(ClaimMask.hasWebsite(model.getAllowedClaimsMask()));
-        rep.setUsername(ClaimMask.hasUsername(model.getAllowedClaimsMask()));
-        return rep;
-    }
-
-    public static FederatedIdentityRepresentation toRepresentation(FederatedIdentityModel socialLink) {
-        FederatedIdentityRepresentation rep = new FederatedIdentityRepresentation();
-        rep.setUserName(socialLink.getUserName());
-        rep.setIdentityProvider(socialLink.getIdentityProvider());
-        rep.setUserId(socialLink.getUserId());
-        return rep;
-    }
-
-    public static UserSessionRepresentation toRepresentation(UserSessionModel session) {
-        UserSessionRepresentation rep = new UserSessionRepresentation();
-        rep.setId(session.getId());
-        rep.setStart(((long)session.getStarted()) * 1000L);
-        rep.setLastAccess(((long)session.getLastSessionRefresh())* 1000L);
-        rep.setUser(session.getUser().getUsername());
-        rep.setIpAddress(session.getIpAddress());
-        for (ClientSessionModel clientSession : session.getClientSessions()) {
-            ClientModel client = clientSession.getClient();
-            if (client instanceof ApplicationModel) {
-                rep.getApplications().put(client.getId(), client.getClientId());
-            } else if (client instanceof OAuthClientModel) {
-                rep.getClients().put(client.getId(), client.getClientId());
-            }
-        }
-        return rep;
-    }
-
-    public static ApplicationRepresentation toRepresentation(ApplicationModel applicationModel) {
-        ApplicationRepresentation rep = new ApplicationRepresentation();
-        rep.setId(applicationModel.getId());
-        rep.setName(applicationModel.getName());
-        rep.setEnabled(applicationModel.isEnabled());
-        rep.setAdminUrl(applicationModel.getManagementUrl());
-        rep.setPublicClient(applicationModel.isPublicClient());
-        rep.setFrontchannelLogout(applicationModel.isFrontchannelLogout());
-        rep.setProtocol(applicationModel.getProtocol());
-        rep.setAttributes(applicationModel.getAttributes());
-        rep.setFullScopeAllowed(applicationModel.isFullScopeAllowed());
-        rep.setBearerOnly(applicationModel.isBearerOnly());
-        rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
-        rep.setBaseUrl(applicationModel.getBaseUrl());
-        rep.setNotBefore(applicationModel.getNotBefore());
-        rep.setNodeReRegistrationTimeout(applicationModel.getNodeReRegistrationTimeout());
-
-        Set<String> redirectUris = applicationModel.getRedirectUris();
-        if (redirectUris != null) {
-            rep.setRedirectUris(new LinkedList<String>(redirectUris));
-        }
-
-        Set<String> webOrigins = applicationModel.getWebOrigins();
-        if (webOrigins != null) {
-            rep.setWebOrigins(new LinkedList<String>(webOrigins));
-        }
-
-        if (!applicationModel.getDefaultRoles().isEmpty()) {
-            rep.setDefaultRoles(applicationModel.getDefaultRoles().toArray(new String[0]));
-        }
-
-        if (!applicationModel.getRegisteredNodes().isEmpty()) {
-            rep.setRegisteredNodes(new HashMap<String, Integer>(applicationModel.getRegisteredNodes()));
-        }
-
-        if (!applicationModel.getIdentityProviders().isEmpty()) {
-            rep.setIdentityProviders(toRepresentation(applicationModel.getIdentityProviders()));
-        }
-
-        if (!applicationModel.getProtocolMappers().isEmpty()) {
-            List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
-            for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) {
-                mappings.add(toRepresentation(model));
-            }
-            rep.setProtocolMappers(mappings);
-        }
-
-        return rep;
-    }
-
-    private static List<ClientIdentityProviderMappingRepresentation> toRepresentation(List<ClientIdentityProviderMappingModel> identityProviders) {
-        ArrayList<ClientIdentityProviderMappingRepresentation> representations = new ArrayList<ClientIdentityProviderMappingRepresentation>();
-
-        for (ClientIdentityProviderMappingModel model : identityProviders) {
-            ClientIdentityProviderMappingRepresentation representation = new ClientIdentityProviderMappingRepresentation();
-
-            representation.setId(model.getIdentityProvider());
-            representation.setRetrieveToken(model.isRetrieveToken());
-
-            representations.add(representation);
-        }
-
-        return representations;
-    }
-
-    public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
-        OAuthClientRepresentation rep = new OAuthClientRepresentation();
-        rep.setId(model.getId());
-        rep.setName(model.getClientId());
-        rep.setEnabled(model.isEnabled());
-        rep.setPublicClient(model.isPublicClient());
-        rep.setFrontchannelLogout(model.isFrontchannelLogout());
-        rep.setProtocol(model.getProtocol());
-        rep.setAttributes(model.getAttributes());
-        rep.setFullScopeAllowed(model.isFullScopeAllowed());
-        rep.setDirectGrantsOnly(model.isDirectGrantsOnly());
-        Set<String> redirectUris = model.getRedirectUris();
-        if (redirectUris != null) {
-            rep.setRedirectUris(new LinkedList<String>(redirectUris));
-        }
-
-        Set<String> webOrigins = model.getWebOrigins();
-        if (webOrigins != null) {
-            rep.setWebOrigins(new LinkedList<String>(webOrigins));
-        }
-        rep.setNotBefore(model.getNotBefore());
-
-        if (!model.getIdentityProviders().isEmpty()) {
-            rep.setIdentityProviders(toRepresentation(model.getIdentityProviders()));
-        }
-
-        if (!model.getProtocolMappers().isEmpty()) {
-                List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
-                for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
-                    mappings.add(toRepresentation(mapper));
-                }
-                rep.setProtocolMappers(mappings);
-        }
-
-        return rep;
-    }
-
-    public static UserFederationProviderRepresentation toRepresentation(UserFederationProviderModel model) {
-        UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation();
-        rep.setId(model.getId());
-        rep.setConfig(model.getConfig());
-        rep.setProviderName(model.getProviderName());
-        rep.setPriority(model.getPriority());
-        rep.setDisplayName(model.getDisplayName());
-        rep.setFullSyncPeriod(model.getFullSyncPeriod());
-        rep.setChangedSyncPeriod(model.getChangedSyncPeriod());
-        rep.setLastSync(model.getLastSync());
-        return rep;
-    }
-
-    public static IdentityProviderRepresentation toRepresentation(IdentityProviderModel identityProviderModel) {
-        IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation();
-
-        providerRep.setInternalId(identityProviderModel.getInternalId());
-        providerRep.setProviderId(identityProviderModel.getProviderId());
-        providerRep.setId(identityProviderModel.getId());
-        providerRep.setName(identityProviderModel.getName());
-        providerRep.setEnabled(identityProviderModel.isEnabled());
-        providerRep.setStoreToken(identityProviderModel.isStoreToken());
-        providerRep.setUpdateProfileFirstLogin(identityProviderModel.isUpdateProfileFirstLogin());
-        providerRep.setAuthenticateByDefault(identityProviderModel.isAuthenticateByDefault());
-        providerRep.setConfig(identityProviderModel.getConfig());
-
-        return providerRep;
-    }
-
-    public static ProtocolMapperRepresentation toRepresentation(ProtocolMapperModel model) {
-        ProtocolMapperRepresentation rep = new ProtocolMapperRepresentation();
-        rep.setId(model.getId());
-        rep.setProtocol(model.getProtocol());
-        Map<String, String> config = new HashMap<String, String>();
-        config.putAll(model.getConfig());
-        rep.setConfig(config);
-        rep.setName(model.getName());
-        rep.setProtocolMapper(model.getProtocolMapper());
-        rep.setConsentText(model.getConsentText());
-        rep.setConsentRequired(model.isConsentRequired());
-        return rep;
-    }
+	public static UserRepresentation toRepresentation(UserModel user) {
+		UserRepresentation rep = new UserRepresentation();
+		rep.setId(user.getId());
+		rep.setUsername(user.getUsername());
+		rep.setLastName(user.getLastName());
+		rep.setFirstName(user.getFirstName());
+		rep.setEmail(user.getEmail());
+		rep.setEnabled(user.isEnabled());
+		rep.setEmailVerified(user.isEmailVerified());
+		rep.setTotp(user.isTotp());
+		rep.setFederationLink(user.getFederationLink());
+
+		List<String> reqActions = new ArrayList<String>();
+		for (UserModel.RequiredAction ra : user.getRequiredActions()) {
+			reqActions.add(ra.name());
+		}
+
+		rep.setRequiredActions(reqActions);
+
+		if (user.getAttributes() != null && !user.getAttributes().isEmpty()) {
+			Map<String, String> attrs = new HashMap<String, String>();
+			attrs.putAll(user.getAttributes());
+			rep.setAttributes(attrs);
+		}
+		return rep;
+	}
+
+	public static RoleRepresentation toRepresentation(RoleModel role) {
+		RoleRepresentation rep = new RoleRepresentation();
+		rep.setId(role.getId());
+		rep.setName(role.getName());
+		rep.setDescription(role.getDescription());
+		rep.setComposite(role.isComposite());
+		return rep;
+	}
+
+	public static RealmRepresentation toRepresentation(RealmModel realm, boolean internal) {
+		RealmRepresentation rep = new RealmRepresentation();
+		rep.setId(realm.getId());
+		rep.setRealm(realm.getName());
+		rep.setEnabled(realm.isEnabled());
+		rep.setNotBefore(realm.getNotBefore());
+		rep.setSslRequired(realm.getSslRequired().name().toLowerCase());
+		rep.setPublicKey(realm.getPublicKeyPem());
+		if (internal) {
+			rep.setPrivateKey(realm.getPrivateKeyPem());
+			String privateKeyPem = realm.getPrivateKeyPem();
+			if (realm.getCertificatePem() == null && privateKeyPem != null) {
+				KeycloakModelUtils.generateRealmCertificate(realm);
+			}
+			rep.setCodeSecret(realm.getCodeSecret());
+		}
+		rep.setCertificate(realm.getCertificatePem());
+		rep.setPasswordCredentialGrantAllowed(realm.isPasswordCredentialGrantAllowed());
+		rep.setRegistrationAllowed(realm.isRegistrationAllowed());
+		rep.setRegistrationEmailAsUsername(realm.isRegistrationEmailAsUsername());
+		rep.setRememberMe(realm.isRememberMe());
+		rep.setBruteForceProtected(realm.isBruteForceProtected());
+		rep.setMaxFailureWaitSeconds(realm.getMaxFailureWaitSeconds());
+		rep.setMinimumQuickLoginWaitSeconds(realm.getMinimumQuickLoginWaitSeconds());
+		rep.setWaitIncrementSeconds(realm.getWaitIncrementSeconds());
+		rep.setQuickLoginCheckMilliSeconds(realm.getQuickLoginCheckMilliSeconds());
+		rep.setMaxDeltaTimeSeconds(realm.getMaxDeltaTimeSeconds());
+		rep.setFailureFactor(realm.getFailureFactor());
+		rep.setVerifyEmail(realm.isVerifyEmail());
+		rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
+		rep.setAccessTokenLifespan(realm.getAccessTokenLifespan());
+		rep.setSsoSessionIdleTimeout(realm.getSsoSessionIdleTimeout());
+		rep.setSsoSessionMaxLifespan(realm.getSsoSessionMaxLifespan());
+		rep.setAccessCodeLifespan(realm.getAccessCodeLifespan());
+		rep.setAccessCodeLifespanUserAction(realm.getAccessCodeLifespanUserAction());
+		rep.setAccessCodeLifespanLogin(realm.getAccessCodeLifespanLogin());
+		rep.setSmtpServer(realm.getSmtpConfig());
+		rep.setBrowserSecurityHeaders(realm.getBrowserSecurityHeaders());
+		rep.setAccountTheme(realm.getAccountTheme());
+		rep.setLoginTheme(realm.getLoginTheme());
+		rep.setAdminTheme(realm.getAdminTheme());
+		rep.setEmailTheme(realm.getEmailTheme());
+		if (realm.getPasswordPolicy() != null) {
+			rep.setPasswordPolicy(realm.getPasswordPolicy().toString());
+		}
+
+		List<String> defaultRoles = realm.getDefaultRoles();
+		if (!defaultRoles.isEmpty()) {
+			List<String> roleStrings = new ArrayList<String>();
+			roleStrings.addAll(defaultRoles);
+			rep.setDefaultRoles(roleStrings);
+		}
+
+		List<RequiredCredentialModel> requiredCredentialModels = realm.getRequiredCredentials();
+		if (requiredCredentialModels.size() > 0) {
+			rep.setRequiredCredentials(new HashSet<String>());
+			for (RequiredCredentialModel cred : requiredCredentialModels) {
+				rep.getRequiredCredentials().add(cred.getType());
+			}
+		}
+
+		List<UserFederationProviderModel> fedProviderModels = realm.getUserFederationProviders();
+		if (fedProviderModels.size() > 0) {
+			List<UserFederationProviderRepresentation> fedProviderReps = new ArrayList<UserFederationProviderRepresentation>();
+			for (UserFederationProviderModel model : fedProviderModels) {
+				UserFederationProviderRepresentation fedProvRep = toRepresentation(model);
+				fedProviderReps.add(fedProvRep);
+			}
+			rep.setUserFederationProviders(fedProviderReps);
+		}
+
+		for (IdentityProviderModel provider : realm.getIdentityProviders()) {
+			rep.addIdentityProvider(toRepresentation(provider));
+		}
+
+		return rep;
+	}
+
+	public static RealmEventsConfigRepresentation toEventsConfigReprensetation(RealmModel realm) {
+		RealmEventsConfigRepresentation rep = new RealmEventsConfigRepresentation();
+		rep.setEventsEnabled(realm.isEventsEnabled());
+
+		if (realm.getEventsExpiration() != 0) {
+			rep.setEventsExpiration(realm.getEventsExpiration());
+		}
+
+		if (realm.getEventsListeners() != null) {
+			rep.setEventsListeners(new LinkedList<String>(realm.getEventsListeners()));
+		}
+		return rep;
+	}
+
+	public static CredentialRepresentation toRepresentation(UserCredentialModel cred) {
+		CredentialRepresentation rep = new CredentialRepresentation();
+		rep.setType(CredentialRepresentation.SECRET);
+		rep.setValue(cred.getValue());
+		return rep;
+	}
+
+	public static ClaimRepresentation toRepresentation(ClientModel model) {
+		ClaimRepresentation rep = new ClaimRepresentation();
+		rep.setAddress(ClaimMask.hasAddress(model.getAllowedClaimsMask()));
+		rep.setEmail(ClaimMask.hasEmail(model.getAllowedClaimsMask()));
+		rep.setGender(ClaimMask.hasGender(model.getAllowedClaimsMask()));
+		rep.setLocale(ClaimMask.hasLocale(model.getAllowedClaimsMask()));
+		rep.setName(ClaimMask.hasName(model.getAllowedClaimsMask()));
+		rep.setPhone(ClaimMask.hasPhone(model.getAllowedClaimsMask()));
+		rep.setPicture(ClaimMask.hasPicture(model.getAllowedClaimsMask()));
+		rep.setProfile(ClaimMask.hasProfile(model.getAllowedClaimsMask()));
+		rep.setWebsite(ClaimMask.hasWebsite(model.getAllowedClaimsMask()));
+		rep.setUsername(ClaimMask.hasUsername(model.getAllowedClaimsMask()));
+		return rep;
+	}
+
+	public static FederatedIdentityRepresentation toRepresentation(FederatedIdentityModel socialLink) {
+		FederatedIdentityRepresentation rep = new FederatedIdentityRepresentation();
+		rep.setUserName(socialLink.getUserName());
+		rep.setIdentityProvider(socialLink.getIdentityProvider());
+		rep.setUserId(socialLink.getUserId());
+		return rep;
+	}
+
+	public static UserSessionRepresentation toRepresentation(UserSessionModel session) {
+		UserSessionRepresentation rep = new UserSessionRepresentation();
+		rep.setId(session.getId());
+		rep.setStart(((long) session.getStarted()) * 1000L);
+		rep.setLastAccess(((long) session.getLastSessionRefresh()) * 1000L);
+		rep.setUser(session.getUser().getUsername());
+		rep.setIpAddress(session.getIpAddress());
+		for (ClientSessionModel clientSession : session.getClientSessions()) {
+			ClientModel client = clientSession.getClient();
+			if (client instanceof ApplicationModel) {
+				rep.getApplications().put(client.getId(), client.getClientId());
+			} else if (client instanceof OAuthClientModel) {
+				rep.getClients().put(client.getId(), client.getClientId());
+			}
+		}
+		return rep;
+	}
+
+	public static ApplicationRepresentation toRepresentation(ApplicationModel applicationModel) {
+		ApplicationRepresentation rep = new ApplicationRepresentation();
+		rep.setId(applicationModel.getId());
+		rep.setName(applicationModel.getName());
+		rep.setEnabled(applicationModel.isEnabled());
+		rep.setAdminUrl(applicationModel.getManagementUrl());
+		rep.setPublicClient(applicationModel.isPublicClient());
+		rep.setFrontchannelLogout(applicationModel.isFrontchannelLogout());
+		rep.setProtocol(applicationModel.getProtocol());
+		rep.setAttributes(applicationModel.getAttributes());
+		rep.setFullScopeAllowed(applicationModel.isFullScopeAllowed());
+		rep.setBearerOnly(applicationModel.isBearerOnly());
+		rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
+		rep.setBaseUrl(applicationModel.getBaseUrl());
+		rep.setNotBefore(applicationModel.getNotBefore());
+		rep.setNodeReRegistrationTimeout(applicationModel.getNodeReRegistrationTimeout());
+
+		Set<String> redirectUris = applicationModel.getRedirectUris();
+		if (redirectUris != null) {
+			rep.setRedirectUris(new LinkedList<String>(redirectUris));
+		}
+
+		Set<String> webOrigins = applicationModel.getWebOrigins();
+		if (webOrigins != null) {
+			rep.setWebOrigins(new LinkedList<String>(webOrigins));
+		}
+
+		if (!applicationModel.getDefaultRoles().isEmpty()) {
+			rep.setDefaultRoles(applicationModel.getDefaultRoles().toArray(new String[0]));
+		}
+
+		if (!applicationModel.getRegisteredNodes().isEmpty()) {
+			rep.setRegisteredNodes(new HashMap<String, Integer>(applicationModel.getRegisteredNodes()));
+		}
+
+		if (!applicationModel.getIdentityProviders().isEmpty()) {
+			rep.setIdentityProviders(toRepresentation(applicationModel.getIdentityProviders()));
+		}
+
+		if (!applicationModel.getProtocolMappers().isEmpty()) {
+			List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
+			for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) {
+				mappings.add(toRepresentation(model));
+			}
+			rep.setProtocolMappers(mappings);
+		}
+
+		return rep;
+	}
+
+	private static List<ClientIdentityProviderMappingRepresentation> toRepresentation(
+			List<ClientIdentityProviderMappingModel> identityProviders) {
+		ArrayList<ClientIdentityProviderMappingRepresentation> representations = new ArrayList<ClientIdentityProviderMappingRepresentation>();
+
+		for (ClientIdentityProviderMappingModel model : identityProviders) {
+			ClientIdentityProviderMappingRepresentation representation = new ClientIdentityProviderMappingRepresentation();
+
+			representation.setId(model.getIdentityProvider());
+			representation.setRetrieveToken(model.isRetrieveToken());
+
+			representations.add(representation);
+		}
+
+		return representations;
+	}
+
+	public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
+		OAuthClientRepresentation rep = new OAuthClientRepresentation();
+		rep.setId(model.getId());
+		rep.setName(model.getClientId());
+		rep.setEnabled(model.isEnabled());
+		rep.setPublicClient(model.isPublicClient());
+		rep.setFrontchannelLogout(model.isFrontchannelLogout());
+		rep.setProtocol(model.getProtocol());
+		rep.setAttributes(model.getAttributes());
+		rep.setFullScopeAllowed(model.isFullScopeAllowed());
+		rep.setDirectGrantsOnly(model.isDirectGrantsOnly());
+		Set<String> redirectUris = model.getRedirectUris();
+		if (redirectUris != null) {
+			rep.setRedirectUris(new LinkedList<String>(redirectUris));
+		}
+
+		Set<String> webOrigins = model.getWebOrigins();
+		if (webOrigins != null) {
+			rep.setWebOrigins(new LinkedList<String>(webOrigins));
+		}
+		rep.setNotBefore(model.getNotBefore());
+
+		if (!model.getIdentityProviders().isEmpty()) {
+			rep.setIdentityProviders(toRepresentation(model.getIdentityProviders()));
+		}
+
+		if (!model.getProtocolMappers().isEmpty()) {
+			List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
+			for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
+				mappings.add(toRepresentation(mapper));
+			}
+			rep.setProtocolMappers(mappings);
+		}
+
+		return rep;
+	}
+
+	public static UserFederationProviderRepresentation toRepresentation(UserFederationProviderModel model) {
+		UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation();
+		rep.setId(model.getId());
+		rep.setConfig(model.getConfig());
+		rep.setProviderName(model.getProviderName());
+		rep.setPriority(model.getPriority());
+		rep.setDisplayName(model.getDisplayName());
+		rep.setFullSyncPeriod(model.getFullSyncPeriod());
+		rep.setChangedSyncPeriod(model.getChangedSyncPeriod());
+		rep.setLastSync(model.getLastSync());
+		return rep;
+	}
+
+	public static IdentityProviderRepresentation toRepresentation(IdentityProviderModel identityProviderModel) {
+		IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation();
+
+		providerRep.setInternalId(identityProviderModel.getInternalId());
+		providerRep.setProviderId(identityProviderModel.getProviderId());
+		providerRep.setId(identityProviderModel.getId());
+		providerRep.setName(identityProviderModel.getName());
+		providerRep.setEnabled(identityProviderModel.isEnabled());
+		providerRep.setStoreToken(identityProviderModel.isStoreToken());
+		providerRep.setUpdateProfileFirstLogin(identityProviderModel.isUpdateProfileFirstLogin());
+		providerRep.setAuthenticateByDefault(identityProviderModel.isAuthenticateByDefault());
+		providerRep.setConfig(identityProviderModel.getConfig());
+
+		return providerRep;
+	}
+
+	public static ProtocolMapperRepresentation toRepresentation(ProtocolMapperModel model) {
+		ProtocolMapperRepresentation rep = new ProtocolMapperRepresentation();
+		rep.setId(model.getId());
+		rep.setProtocol(model.getProtocol());
+		Map<String, String> config = new HashMap<String, String>();
+		config.putAll(model.getConfig());
+		rep.setConfig(config);
+		rep.setName(model.getName());
+		rep.setProtocolMapper(model.getProtocolMapper());
+		rep.setConsentText(model.getConsentText());
+		rep.setConsentRequired(model.isConsentRequired());
+		return rep;
+	}
 
 }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index 90b00dd..3154ad4 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -1,6 +1,16 @@
 package org.keycloak.models.utils;
 
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import net.iharder.Base64;
+
 import org.jboss.logging.Logger;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
@@ -34,807 +44,904 @@ import org.keycloak.representations.idm.ScopeMappingRepresentation;
 import org.keycloak.representations.idm.UserFederationProviderRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 public class RepresentationToModel {
 
-    private static Logger logger = Logger.getLogger(RepresentationToModel.class);
-
-    public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
-        newRealm.setName(rep.getRealm());
-        if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
-        if (rep.isBruteForceProtected() != null) newRealm.setBruteForceProtected(rep.isBruteForceProtected());
-        if (rep.getMaxFailureWaitSeconds() != null) newRealm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
-        if (rep.getMinimumQuickLoginWaitSeconds() != null) newRealm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
-        if (rep.getWaitIncrementSeconds() != null) newRealm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
-        if (rep.getQuickLoginCheckMilliSeconds() != null) newRealm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
-        if (rep.getMaxDeltaTimeSeconds() != null) newRealm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
-        if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
-        if (rep.isEventsEnabled() != null) newRealm.setEventsEnabled(rep.isEventsEnabled());
-        if (rep.getEventsExpiration() != null) newRealm.setEventsExpiration(rep.getEventsExpiration());
-        if (rep.getEventsListeners() != null) newRealm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
-
-        if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
-
-        if (rep.getAccessTokenLifespan() != null) newRealm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
-        else newRealm.setAccessTokenLifespan(300);
-
-        if (rep.getSsoSessionIdleTimeout() != null) newRealm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
-        else newRealm.setSsoSessionIdleTimeout(1800);
-        if (rep.getSsoSessionMaxLifespan() != null) newRealm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
-        else newRealm.setSsoSessionMaxLifespan(36000);
-
-        if (rep.getAccessCodeLifespan() != null) newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
-        else newRealm.setAccessCodeLifespan(60);
-
-        if (rep.getAccessCodeLifespanUserAction() != null)
-            newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
-        else newRealm.setAccessCodeLifespanUserAction(300);
-
-        if (rep.getAccessCodeLifespanLogin() != null)
-            newRealm.setAccessCodeLifespanLogin(rep.getAccessCodeLifespanLogin());
-        else newRealm.setAccessCodeLifespanLogin(1800);
-
-        if (rep.getSslRequired() != null) newRealm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
-        if (rep.isPasswordCredentialGrantAllowed() != null) newRealm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
-        if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
-        if (rep.isRememberMe() != null) newRealm.setRememberMe(rep.isRememberMe());
-        if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail());
-        if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
-        if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
-            KeycloakModelUtils.generateRealmKeys(newRealm);
-        } else {
-            newRealm.setPrivateKeyPem(rep.getPrivateKey());
-            newRealm.setPublicKeyPem(rep.getPublicKey());
-        }
-        if (rep.getCertificate() == null) {
-            KeycloakModelUtils.generateRealmCertificate(newRealm);
-        } else {
-            newRealm.setCertificatePem(rep.getCertificate());
-        }
-        if (rep.getCodeSecret() == null) {
-            newRealm.setCodeSecret(KeycloakModelUtils.generateCodeSecret());
-        } else {
-            newRealm.setCodeSecret(rep.getCodeSecret());
-        }
-
-        if (rep.getLoginTheme() != null) newRealm.setLoginTheme(rep.getLoginTheme());
-        if (rep.getAccountTheme() != null) newRealm.setAccountTheme(rep.getAccountTheme());
-        if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAdminTheme());
-        if (rep.getEmailTheme() != null) newRealm.setEmailTheme(rep.getEmailTheme());
-
-        if (rep.getRequiredCredentials() != null) {
-            for (String requiredCred : rep.getRequiredCredentials()) {
-                addRequiredCredential(newRealm, requiredCred);
-            }
-        } else {
-            addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
-        }
-
-        if (rep.getPasswordPolicy() != null) newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
-
-        importIdentityProviders(rep, newRealm);
-
-        if (rep.getApplications() != null) {
-            Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
-        }
-
-        if (rep.getRoles() != null) {
-            if (rep.getRoles().getRealm() != null) { // realm roles
-                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
-                    createRole(newRealm, roleRep);
-                }
-            }
-            if (rep.getRoles().getApplication() != null) {
-                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
-                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
-                    if (app == null) {
-                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
-                    }
-                    for (RoleRepresentation roleRep : entry.getValue()) {
-                        // Application role may already exists (for example if it is defaultRole)
-                        RoleModel role = roleRep.getId()!=null ? app.addRole(roleRep.getId(), roleRep.getName()) : app.addRole(roleRep.getName());
-                        role.setDescription(roleRep.getDescription());
-                    }
-                }
-            }
-            // now that all roles are created, re-iterate and set up composites
-            if (rep.getRoles().getRealm() != null) { // realm roles
-                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
-                    RoleModel role = newRealm.getRole(roleRep.getName());
-                    addComposites(role, roleRep, newRealm);
-                }
-            }
-            if (rep.getRoles().getApplication() != null) {
-                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
-                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
-                    if (app == null) {
-                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
-                    }
-                    for (RoleRepresentation roleRep : entry.getValue()) {
-                        RoleModel role = app.getRole(roleRep.getName());
-                        addComposites(role, roleRep, newRealm);
-                    }
-                }
-            }
-        }
-
-        // Setup realm default roles
-        if (rep.getDefaultRoles() != null) {
-            for (String roleString : rep.getDefaultRoles()) {
-                newRealm.addDefaultRole(roleString.trim());
-            }
-        }
-        // Setup application default roles
-        if (rep.getApplications() != null) {
-            for (ApplicationRepresentation resourceRep : rep.getApplications()) {
-                if (resourceRep.getDefaultRoles() != null) {
-                    ApplicationModel appModel = newRealm.getApplicationByName(resourceRep.getName());
-                    appModel.updateDefaultRoles(resourceRep.getDefaultRoles());
-                }
-            }
-        }
-
-        if (rep.getOauthClients() != null) {
-            createOAuthClients(rep, newRealm);
-        }
-
-
-        // Now that all possible roles and applications are created, create scope mappings
-
-        Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap();
-
-        if (rep.getApplicationScopeMappings() != null) {
-
-            for (Map.Entry<String, List<ScopeMappingRepresentation>> entry : rep.getApplicationScopeMappings().entrySet()) {
-                ApplicationModel app = appMap.get(entry.getKey());
-                if (app == null) {
-                    throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
-                }
-                createApplicationScopeMappings(newRealm, app, entry.getValue());
-            }
-        }
-
-        if (rep.getScopeMappings() != null) {
-            for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
-                ClientModel client = newRealm.findClient(scope.getClient());
-                if (client == null) {
-                    throw new RuntimeException("Unknown client specification in realm scope mappings");
-                }
-                for (String roleString : scope.getRoles()) {
-                    RoleModel role = newRealm.getRole(roleString.trim());
-                    if (role == null) {
-                        role = newRealm.addRole(roleString.trim());
-                    }
-                    client.addScopeMapping(role);
-                }
-
-            }
-        }
-
-        if (rep.getSmtpServer() != null) {
-            newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
-        }
-
-        if (rep.getBrowserSecurityHeaders() != null) {
-            newRealm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
-        } else {
-            newRealm.setBrowserSecurityHeaders(BrowserSecurityHeaders.defaultHeaders);
-        }
-
-        if (rep.getUserFederationProviders() != null) {
-            List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
-            newRealm.setUserFederationProviders(providerModels);
-        }
-
-        // create users and their role mappings and social mappings
-
-        if (rep.getUsers() != null) {
-            for (UserRepresentation userRep : rep.getUsers()) {
-                UserModel user = createUser(session, newRealm, userRep, appMap);
-            }
-        }
-    }
-
-    public static void updateRealm(RealmRepresentation rep, RealmModel realm) {
-        if (rep.getRealm() != null) {
-            realm.setName(rep.getRealm());
-        }
-        if (rep.isEnabled() != null) realm.setEnabled(rep.isEnabled());
-        if (rep.isBruteForceProtected() != null) realm.setBruteForceProtected(rep.isBruteForceProtected());
-        if (rep.getMaxFailureWaitSeconds() != null) realm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
-        if (rep.getMinimumQuickLoginWaitSeconds() != null) realm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
-        if (rep.getWaitIncrementSeconds() != null) realm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
-        if (rep.getQuickLoginCheckMilliSeconds() != null) realm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
-        if (rep.getMaxDeltaTimeSeconds() != null) realm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
-        if (rep.getFailureFactor() != null) realm.setFailureFactor(rep.getFailureFactor());
-        if (rep.isPasswordCredentialGrantAllowed() != null) realm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
-        if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
-        if (rep.isRememberMe() != null) realm.setRememberMe(rep.isRememberMe());
-        if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
-        if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
-        if (rep.getSslRequired() != null) realm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
-        if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
-        if (rep.getAccessCodeLifespanUserAction() != null) realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
-        if (rep.getAccessCodeLifespanLogin() != null) realm.setAccessCodeLifespanLogin(rep.getAccessCodeLifespanLogin());
-        if (rep.getNotBefore() != null) realm.setNotBefore(rep.getNotBefore());
-        if (rep.getAccessTokenLifespan() != null) realm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
-        if (rep.getSsoSessionIdleTimeout() != null) realm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
-        if (rep.getSsoSessionMaxLifespan() != null) realm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
-        if (rep.getRequiredCredentials() != null) {
-            realm.updateRequiredCredentials(rep.getRequiredCredentials());
-        }
-        if (rep.getLoginTheme() != null) realm.setLoginTheme(rep.getLoginTheme());
-        if (rep.getAccountTheme() != null) realm.setAccountTheme(rep.getAccountTheme());
-        if (rep.getAdminTheme() != null) realm.setAdminTheme(rep.getAdminTheme());
-        if (rep.getEmailTheme() != null) realm.setEmailTheme(rep.getEmailTheme());
-        if (rep.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
-        if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
-        if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
-
-        if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
-
-        if (rep.getDefaultRoles() != null) {
-            realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()]));
-        }
-
-        if (rep.getSmtpServer() != null) {
-            realm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
-        }
-
-        if (rep.getBrowserSecurityHeaders() != null) {
-            realm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
-        }
-
-        if (rep.getUserFederationProviders() != null) {
-            List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
-            realm.setUserFederationProviders(providerModels);
-        }
-
-        if ("GENERATE".equals(rep.getPublicKey())) {
-            KeycloakModelUtils.generateRealmKeys(realm);
-        }
-    }
-
-    // Basic realm stuff
-
-    public static void addRequiredCredential(RealmModel newRealm, String requiredCred) {
-        newRealm.addRequiredCredential(requiredCred);
-    }
-
-
-    private static List<UserFederationProviderModel> convertFederationProviders(List<UserFederationProviderRepresentation> providers) {
-        List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
-
-        for (UserFederationProviderRepresentation representation : providers) {
-            UserFederationProviderModel model = new UserFederationProviderModel(representation.getId(), representation.getProviderName(),
-                    representation.getConfig(), representation.getPriority(), representation.getDisplayName(),
-                    representation.getFullSyncPeriod(), representation.getChangedSyncPeriod(), representation.getLastSync());
-            result.add(model);
-        }
-        return result;
-    }
-
-    // Roles
-
-    public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
-        RoleModel role = roleRep.getId()!=null ? newRealm.addRole(roleRep.getId(), roleRep.getName()) : newRealm.addRole(roleRep.getName());
-        if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
-    }
-
-    private static void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
-        if (roleRep.getComposites() == null) return;
-        if (roleRep.getComposites().getRealm() != null) {
-            for (String roleStr : roleRep.getComposites().getRealm()) {
-                RoleModel realmRole = realm.getRole(roleStr);
-                if (realmRole == null) throw new RuntimeException("Unable to find composite realm role: " + roleStr);
-                role.addCompositeRole(realmRole);
-            }
-        }
-        if (roleRep.getComposites().getApplication() != null) {
-            for (Map.Entry<String, List<String>> entry : roleRep.getComposites().getApplication().entrySet()) {
-                ApplicationModel app = realm.getApplicationByName(entry.getKey());
-                if (app == null) {
-                    throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName());
-                }
-                for (String roleStr : entry.getValue()) {
-                    RoleModel appRole = app.getRole(roleStr);
-                    if (appRole == null) throw new RuntimeException("Unable to find composite app role: " + roleStr);
-                    role.addCompositeRole(appRole);
-                }
-
-            }
-
-        }
-
-    }
-
-    // APPLICATIONS
-
-    private static Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
-        Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
-        for (ApplicationRepresentation resourceRep : rep.getApplications()) {
-            ApplicationModel app = createApplication(realm, resourceRep, false);
-            appMap.put(app.getName(), app);
-        }
-        return appMap;
-    }
-
-    /**
-     * Does not create scope or role mappings!
-     *
-     * @param realm
-     * @param resourceRep
-     * @return
-     */
-    public static ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
-        logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
-        ApplicationModel applicationModel = resourceRep.getId()!=null ? realm.addApplication(resourceRep.getId(), resourceRep.getName()) : realm.addApplication(resourceRep.getName());
-        if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled());
-        applicationModel.setManagementUrl(resourceRep.getAdminUrl());
-        if (resourceRep.isSurrogateAuthRequired() != null)
-            applicationModel.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
-        applicationModel.setBaseUrl(resourceRep.getBaseUrl());
-        if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly());
-        if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient());
-        if (resourceRep.isFrontchannelLogout() != null) applicationModel.setFrontchannelLogout(resourceRep.isFrontchannelLogout());
-        if (resourceRep.getProtocol() != null) applicationModel.setProtocol(resourceRep.getProtocol());
-        if (resourceRep.isFullScopeAllowed() != null) {
-            applicationModel.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
-        } else {
-            applicationModel.setFullScopeAllowed(true);
-        }
-        if (resourceRep.getNodeReRegistrationTimeout() != null) {
-            applicationModel.setNodeReRegistrationTimeout(resourceRep.getNodeReRegistrationTimeout());
-        } else {
-            applicationModel.setNodeReRegistrationTimeout(-1);
-        }
-        applicationModel.updateApplication();
-
-        if (resourceRep.getNotBefore() != null) {
-            applicationModel.setNotBefore(resourceRep.getNotBefore());
-        }
-
-        applicationModel.setSecret(resourceRep.getSecret());
-        if (applicationModel.getSecret() == null) {
-            KeycloakModelUtils.generateSecret(applicationModel);
-        }
-
-        if (resourceRep.getAttributes() != null) {
-            for (Map.Entry<String, String> entry : resourceRep.getAttributes().entrySet()) {
-                applicationModel.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-
-
-        if (resourceRep.getRedirectUris() != null) {
-            for (String redirectUri : resourceRep.getRedirectUris()) {
-                applicationModel.addRedirectUri(redirectUri);
-            }
-        }
-        if (resourceRep.getWebOrigins() != null) {
-            for (String webOrigin : resourceRep.getWebOrigins()) {
-                logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getName(), webOrigin);
-                applicationModel.addWebOrigin(webOrigin);
-            }
-        } else {
-            // add origins from redirect uris
-            if (resourceRep.getRedirectUris() != null) {
-                Set<String> origins = new HashSet<String>();
-                for (String redirectUri : resourceRep.getRedirectUris()) {
-                    logger.debugv("add redirect-uri to origin: {0}", redirectUri);
-                    if (redirectUri.startsWith("http:")) {
-                        URI uri = URI.create(redirectUri);
-                        String origin = uri.getScheme() + "://" + uri.getHost();
-                        if (uri.getPort() != -1) {
-                            origin += ":" + uri.getPort();
-                        }
-                        logger.debugv("adding default application origin: {0}" , origin);
-                        origins.add(origin);
-                    }
-                }
-                if (origins.size() > 0) {
-                    applicationModel.setWebOrigins(origins);
-                }
-            }
-        }
-
-        if (resourceRep.getRegisteredNodes() != null) {
-            for (Map.Entry<String, Integer> entry : resourceRep.getRegisteredNodes().entrySet()) {
-                applicationModel.registerNode(entry.getKey(), entry.getValue());
-            }
-        }
-
-        if (addDefaultRoles && resourceRep.getDefaultRoles() != null) {
-            applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
-        }
-
-        if (resourceRep.getProtocolMappers() != null) {
-            // first, remove all default/built in mappers
-            Set<ProtocolMapperModel> mappers = applicationModel.getProtocolMappers();
-            for (ProtocolMapperModel mapper : mappers) applicationModel.removeProtocolMapper(mapper);
-
-            for (ProtocolMapperRepresentation mapper : resourceRep.getProtocolMappers()) {
-                applicationModel.addProtocolMapper(toModel(mapper));
-            }
-        }
-
-        applicationModel.updateAllowedIdentityProviders(toModel(resourceRep.getIdentityProviders(), realm));
-
-        return applicationModel;
-    }
-
-    public static void updateApplication(ApplicationRepresentation rep, ApplicationModel resource) {
-        if (rep.getName() != null) resource.setName(rep.getName());
-        if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
-        if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
-        if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
-        if (rep.isFullScopeAllowed() != null) resource.setFullScopeAllowed(rep.isFullScopeAllowed());
-        if (rep.isFrontchannelLogout() != null) resource.setFrontchannelLogout(rep.isFrontchannelLogout());
-        if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl());
-        if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl());
-        if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
-        if (rep.getNodeReRegistrationTimeout() != null) resource.setNodeReRegistrationTimeout(rep.getNodeReRegistrationTimeout());
-        resource.updateApplication();
-
-        if (rep.getProtocol() != null) resource.setProtocol(rep.getProtocol());
-        if (rep.getAttributes() != null) {
-            for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
-                resource.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-
-
-        if (rep.getNotBefore() != null) {
-            resource.setNotBefore(rep.getNotBefore());
-        }
-        if (rep.getDefaultRoles() != null) {
-            resource.updateDefaultRoles(rep.getDefaultRoles());
-        }
-
-        List<String> redirectUris = rep.getRedirectUris();
-        if (redirectUris != null) {
-            resource.setRedirectUris(new HashSet<String>(redirectUris));
-        }
-
-        List<String> webOrigins = rep.getWebOrigins();
-        if (webOrigins != null) {
-            resource.setWebOrigins(new HashSet<String>(webOrigins));
-        }
-
-        if (rep.getRegisteredNodes() != null) {
-            for (Map.Entry<String, Integer> entry : rep.getRegisteredNodes().entrySet()) {
-                resource.registerNode(entry.getKey(), entry.getValue());
-            }
-        }
-
-        updateClientIdentityProvides(rep.getIdentityProviders(), resource);
-    }
-
-    public static void setClaims(ClientModel model, ClaimRepresentation rep) {
-        long mask = model.getAllowedClaimsMask();
-        if (rep.getAddress()) {
-            mask |= ClaimMask.ADDRESS;
-        } else {
-            mask &= ~ClaimMask.ADDRESS;
-        }
-        if (rep.getEmail()) {
-            mask |= ClaimMask.EMAIL;
-        } else {
-            mask &= ~ClaimMask.EMAIL;
-        }
-        if (rep.getGender()) {
-            mask |= ClaimMask.GENDER;
-        } else {
-            mask &= ~ClaimMask.GENDER;
-        }
-        if (rep.getLocale()) {
-            mask |= ClaimMask.LOCALE;
-        } else {
-            mask &= ~ClaimMask.LOCALE;
-        }
-        if (rep.getName()) {
-            mask |= ClaimMask.NAME;
-        } else {
-            mask &= ~ClaimMask.NAME;
-        }
-        if (rep.getPhone()) {
-            mask |= ClaimMask.PHONE;
-        } else {
-            mask &= ~ClaimMask.PHONE;
-        }
-        if (rep.getPicture()) {
-            mask |= ClaimMask.PICTURE;
-        } else {
-            mask &= ~ClaimMask.PICTURE;
-        }
-        if (rep.getProfile()) {
-            mask |= ClaimMask.PROFILE;
-        } else {
-            mask &= ~ClaimMask.PROFILE;
-        }
-        if (rep.getUsername()) {
-            mask |= ClaimMask.USERNAME;
-        } else {
-            mask &= ~ClaimMask.USERNAME;
-        }
-        if (rep.getWebsite()) {
-            mask |= ClaimMask.WEBSITE;
-        } else {
-            mask &= ~ClaimMask.WEBSITE;
-        }
-        model.setAllowedClaimsMask(mask);
-    }
-
-    // OAuth clients
-
-    private static void createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
-        for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
-            createOAuthClient(rep, realm);
-        }
-    }
-
-    public static OAuthClientModel createOAuthClient(String id, String name, RealmModel realm) {
-        OAuthClientModel model = id!=null ? realm.addOAuthClient(id, name) : realm.addOAuthClient(name);
-        KeycloakModelUtils.generateSecret(model);
-        return model;
-    }
-
-    public static OAuthClientModel createOAuthClient(OAuthClientRepresentation rep, RealmModel realm) {
-        OAuthClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
-
-        model.updateAllowedIdentityProviders(toModel(rep.getIdentityProviders(), realm));
-
-        updateOAuthClient(rep, model);
-        return model;
-    }
-
-    public static void updateOAuthClient(OAuthClientRepresentation rep, OAuthClientModel model) {
-        if (rep.getName() != null) model.setClientId(rep.getName());
-        if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
-        if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
-        if (rep.isFrontchannelLogout() != null) model.setFrontchannelLogout(rep.isFrontchannelLogout());
-        if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed());
-        if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
-        if (rep.getClaims() != null) {
-            setClaims(model, rep.getClaims());
-        }
-        if (rep.getNotBefore() != null) {
-            model.setNotBefore(rep.getNotBefore());
-        }
-        if (rep.getSecret() != null) model.setSecret(rep.getSecret());
-        List<String> redirectUris = rep.getRedirectUris();
-        if (redirectUris != null) {
-            model.setRedirectUris(new HashSet<String>(redirectUris));
-        }
-
-        List<String> webOrigins = rep.getWebOrigins();
-        if (webOrigins != null) {
-            model.setWebOrigins(new HashSet<String>(webOrigins));
-        }
-
-        if (rep.getNotBefore() != null) {
-            model.setNotBefore(rep.getNotBefore());
-        }
-        if (rep.getProtocol() != null) model.setProtocol(rep.getProtocol());
-        if (rep.getAttributes() != null) {
-            for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
-                model.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-
-        updateClientIdentityProvides(rep.getIdentityProviders(), model);
-
-        if (rep.getProtocolMappers() != null) {
-            // first, remove all default/built in mappers
-            Set<ProtocolMapperModel> mappers = model.getProtocolMappers();
-            for (ProtocolMapperModel mapper : mappers) model.removeProtocolMapper(mapper);
-
-            for (ProtocolMapperRepresentation mapper : rep.getProtocolMappers()) {
-                model.addProtocolMapper(toModel(mapper));
-            }
-        }
-
-    }
-
-    // Scope mappings
-
-    public static void createApplicationScopeMappings(RealmModel realm, ApplicationModel applicationModel, List<ScopeMappingRepresentation> mappings) {
-        for (ScopeMappingRepresentation mapping : mappings) {
-            ClientModel client = realm.findClient(mapping.getClient());
-            if (client == null) {
-                throw new RuntimeException("Unknown client specified in application scope mappings");
-            }
-            for (String roleString : mapping.getRoles()) {
-                RoleModel role = applicationModel.getRole(roleString.trim());
-                if (role == null) {
-                    role = applicationModel.addRole(roleString.trim());
-                }
-                client.addScopeMapping(role);
-            }
-        }
-    }
-
-    // Users
-
-    public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
-        // Import users just to user storage. Don't federate
-        UserModel user = session.userStorage().addUser(newRealm, userRep.getId(), userRep.getUsername(), false);
-        user.setEnabled(userRep.isEnabled());
-        user.setEmail(userRep.getEmail());
-        user.setFirstName(userRep.getFirstName());
-        user.setLastName(userRep.getLastName());
-        user.setFederationLink(userRep.getFederationLink());
-        user.setTotp(userRep.isTotp());
-        if (userRep.getAttributes() != null) {
-            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
-                user.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-        if (userRep.getRequiredActions() != null) {
-            for (String requiredAction : userRep.getRequiredActions()) {
-                user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction));
-            }
-        }
-        if (userRep.getCredentials() != null) {
-            for (CredentialRepresentation cred : userRep.getCredentials()) {
-                updateCredential(user, cred);
-            }
-        }
-        if (userRep.getFederatedIdentities() != null) {
-            for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
-                FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
-                session.users().addFederatedIdentity(newRealm, user, mappingModel);
-            }
-        }
-        if (userRep.getRealmRoles() != null) {
-            for (String roleString : userRep.getRealmRoles()) {
-                RoleModel role = newRealm.getRole(roleString.trim());
-                if (role == null) {
-                    role = newRealm.addRole(roleString.trim());
-                }
-                user.grantRole(role);
-            }
-        }
-        if (userRep.getApplicationRoles() != null) {
-            for (Map.Entry<String, List<String>> entry : userRep.getApplicationRoles().entrySet()) {
-                ApplicationModel app = appMap.get(entry.getKey());
-                if (app == null) {
-                    throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
-                }
-                createApplicationRoleMappings(app, user, entry.getValue());
-            }
-        }
-        return user;
-    }
-
-    // Detect if it is "plain-text" or "hashed" representation and update model according to it
-    private static void updateCredential(UserModel user, CredentialRepresentation cred) {
-        if (cred.getValue() != null) {
-            UserCredentialModel plainTextCred = convertCredential(cred);
-            user.updateCredential(plainTextCred);
-        } else {
-            UserCredentialValueModel hashedCred = new UserCredentialValueModel();
-            hashedCred.setType(cred.getType());
-            hashedCred.setDevice(cred.getDevice());
-            hashedCred.setHashIterations(cred.getHashIterations());
-            try {
-                if (cred.getSalt() != null) hashedCred.setSalt(Base64.decode(cred.getSalt()));
-            } catch (IOException ioe) {
-                throw new RuntimeException(ioe);
-            }
-            hashedCred.setValue(cred.getHashedSaltedValue());
-            user.updateCredentialDirectly(hashedCred);
-        }
-    }
-
-    public static UserCredentialModel convertCredential(CredentialRepresentation cred) {
-        UserCredentialModel credential = new UserCredentialModel();
-        credential.setType(cred.getType());
-        credential.setValue(cred.getValue());
-        return credential;
-    }
-
-    // Role mappings
-
-    public static void createApplicationRoleMappings(ApplicationModel applicationModel, UserModel user, List<String> roleNames) {
-        if (user == null) {
-            throw new RuntimeException("User not found");
-        }
-
-        for (String roleName : roleNames) {
-            RoleModel role = applicationModel.getRole(roleName.trim());
-            if (role == null) {
-                role = applicationModel.addRole(roleName.trim());
-            }
-            user.grantRole(role);
-
-        }
-    }
-
-    private static void importIdentityProviders(RealmRepresentation rep, RealmModel newRealm) {
-        if (rep.getIdentityProviders() != null) {
-            for (IdentityProviderRepresentation representation : rep.getIdentityProviders()) {
-                newRealm.addIdentityProvider(toModel(representation));
-            }
-        }
-    }
-    public static IdentityProviderModel toModel(IdentityProviderRepresentation representation) {
-        IdentityProviderModel identityProviderModel = new IdentityProviderModel();
-
-        identityProviderModel.setInternalId(representation.getInternalId());
-        identityProviderModel.setId(representation.getId());
-        identityProviderModel.setProviderId(representation.getProviderId());
-        identityProviderModel.setName(representation.getName());
-        identityProviderModel.setEnabled(representation.isEnabled());
-        identityProviderModel.setUpdateProfileFirstLogin(representation.isUpdateProfileFirstLogin());
-        identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
-        identityProviderModel.setStoreToken(representation.isStoreToken());
-        identityProviderModel.setConfig(representation.getConfig());
-
-        return identityProviderModel;
-    }
-
-    public static ProtocolMapperModel toModel(ProtocolMapperRepresentation rep) {
-        ProtocolMapperModel model = new ProtocolMapperModel();
-        model.setId(rep.getId());
-        model.setName(rep.getName());
-        model.setConsentRequired(rep.isConsentRequired());
-        model.setConsentText(rep.getConsentText());
-        model.setProtocol(rep.getProtocol());
-        model.setProtocolMapper(rep.getProtocolMapper());
-        model.setConfig(rep.getConfig());
-        return model;
-    }
-
-    private static List<ClientIdentityProviderMappingModel> toModel(List<ClientIdentityProviderMappingRepresentation> repIdentityProviders, RealmModel realm) {
-        List<ClientIdentityProviderMappingModel> allowedIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
-
-        if (repIdentityProviders == null || repIdentityProviders.isEmpty()) {
-            allowedIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
-
-            for (IdentityProviderModel identityProvider : realm.getIdentityProviders()) {
-                ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
-
-                identityProviderMapping.setIdentityProvider(identityProvider.getId());
-
-                allowedIdentityProviders.add(identityProviderMapping);
-            }
-        } else {
-            for (ClientIdentityProviderMappingRepresentation rep : repIdentityProviders) {
-                ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
-
-                identityProviderMapping.setIdentityProvider(rep.getId());
-                identityProviderMapping.setRetrieveToken(rep.isRetrieveToken());
-
-                allowedIdentityProviders.add(identityProviderMapping);
-            }
-        }
-
-        return allowedIdentityProviders;
-    }
-
-    private static void updateClientIdentityProvides(List<ClientIdentityProviderMappingRepresentation> identityProviders, ClientModel resource) {
-        if (identityProviders != null) {
-            List<ClientIdentityProviderMappingModel> allowedIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
-
-            for (ClientIdentityProviderMappingRepresentation mappingRepresentation : identityProviders) {
-                ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
-
-                identityProviderMapping.setIdentityProvider(mappingRepresentation.getId());
-                identityProviderMapping.setRetrieveToken(mappingRepresentation.isRetrieveToken());
-
-                allowedIdentityProviders.add(identityProviderMapping);
-            }
-
-            resource.updateAllowedIdentityProviders(allowedIdentityProviders);
-        }
-    }
+	private static Logger logger = Logger.getLogger(RepresentationToModel.class);
+
+	public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
+		newRealm.setName(rep.getRealm());
+		if (rep.isEnabled() != null)
+			newRealm.setEnabled(rep.isEnabled());
+		if (rep.isBruteForceProtected() != null)
+			newRealm.setBruteForceProtected(rep.isBruteForceProtected());
+		if (rep.getMaxFailureWaitSeconds() != null)
+			newRealm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
+		if (rep.getMinimumQuickLoginWaitSeconds() != null)
+			newRealm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
+		if (rep.getWaitIncrementSeconds() != null)
+			newRealm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
+		if (rep.getQuickLoginCheckMilliSeconds() != null)
+			newRealm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
+		if (rep.getMaxDeltaTimeSeconds() != null)
+			newRealm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
+		if (rep.getFailureFactor() != null)
+			newRealm.setFailureFactor(rep.getFailureFactor());
+		if (rep.isEventsEnabled() != null)
+			newRealm.setEventsEnabled(rep.isEventsEnabled());
+		if (rep.getEventsExpiration() != null)
+			newRealm.setEventsExpiration(rep.getEventsExpiration());
+		if (rep.getEventsListeners() != null)
+			newRealm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
+
+		if (rep.getNotBefore() != null)
+			newRealm.setNotBefore(rep.getNotBefore());
+
+		if (rep.getAccessTokenLifespan() != null)
+			newRealm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
+		else
+			newRealm.setAccessTokenLifespan(300);
+
+		if (rep.getSsoSessionIdleTimeout() != null)
+			newRealm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
+		else
+			newRealm.setSsoSessionIdleTimeout(1800);
+		if (rep.getSsoSessionMaxLifespan() != null)
+			newRealm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
+		else
+			newRealm.setSsoSessionMaxLifespan(36000);
+
+		if (rep.getAccessCodeLifespan() != null)
+			newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
+		else
+			newRealm.setAccessCodeLifespan(60);
+
+		if (rep.getAccessCodeLifespanUserAction() != null)
+			newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
+		else
+			newRealm.setAccessCodeLifespanUserAction(300);
+
+		if (rep.getAccessCodeLifespanLogin() != null)
+			newRealm.setAccessCodeLifespanLogin(rep.getAccessCodeLifespanLogin());
+		else
+			newRealm.setAccessCodeLifespanLogin(1800);
+
+		if (rep.getSslRequired() != null)
+			newRealm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
+		if (rep.isPasswordCredentialGrantAllowed() != null)
+			newRealm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
+		if (rep.isRegistrationAllowed() != null)
+			newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
+		if (rep.isRegistrationEmailAsUsername() != null)
+			newRealm.setRegistrationEmailAsUsername(rep.isRegistrationEmailAsUsername());
+		if (rep.isRememberMe() != null)
+			newRealm.setRememberMe(rep.isRememberMe());
+		if (rep.isVerifyEmail() != null)
+			newRealm.setVerifyEmail(rep.isVerifyEmail());
+		if (rep.isResetPasswordAllowed() != null)
+			newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
+		if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
+			KeycloakModelUtils.generateRealmKeys(newRealm);
+		} else {
+			newRealm.setPrivateKeyPem(rep.getPrivateKey());
+			newRealm.setPublicKeyPem(rep.getPublicKey());
+		}
+		if (rep.getCertificate() == null) {
+			KeycloakModelUtils.generateRealmCertificate(newRealm);
+		} else {
+			newRealm.setCertificatePem(rep.getCertificate());
+		}
+		if (rep.getCodeSecret() == null) {
+			newRealm.setCodeSecret(KeycloakModelUtils.generateCodeSecret());
+		} else {
+			newRealm.setCodeSecret(rep.getCodeSecret());
+		}
+
+		if (rep.getLoginTheme() != null)
+			newRealm.setLoginTheme(rep.getLoginTheme());
+		if (rep.getAccountTheme() != null)
+			newRealm.setAccountTheme(rep.getAccountTheme());
+		if (rep.getAdminTheme() != null)
+			newRealm.setAdminTheme(rep.getAdminTheme());
+		if (rep.getEmailTheme() != null)
+			newRealm.setEmailTheme(rep.getEmailTheme());
+
+		if (rep.getRequiredCredentials() != null) {
+			for (String requiredCred : rep.getRequiredCredentials()) {
+				addRequiredCredential(newRealm, requiredCred);
+			}
+		} else {
+			addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
+		}
+
+		if (rep.getPasswordPolicy() != null)
+			newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
+
+		importIdentityProviders(rep, newRealm);
+
+		if (rep.getApplications() != null) {
+			Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
+		}
+
+		if (rep.getRoles() != null) {
+			if (rep.getRoles().getRealm() != null) { // realm roles
+				for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+					createRole(newRealm, roleRep);
+				}
+			}
+			if (rep.getRoles().getApplication() != null) {
+				for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+					ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+					if (app == null) {
+						throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+					}
+					for (RoleRepresentation roleRep : entry.getValue()) {
+						// Application role may already exists (for example if it is defaultRole)
+						RoleModel role = roleRep.getId() != null ? app.addRole(roleRep.getId(), roleRep.getName()) : app
+								.addRole(roleRep.getName());
+						role.setDescription(roleRep.getDescription());
+					}
+				}
+			}
+			// now that all roles are created, re-iterate and set up composites
+			if (rep.getRoles().getRealm() != null) { // realm roles
+				for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+					RoleModel role = newRealm.getRole(roleRep.getName());
+					addComposites(role, roleRep, newRealm);
+				}
+			}
+			if (rep.getRoles().getApplication() != null) {
+				for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+					ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+					if (app == null) {
+						throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+					}
+					for (RoleRepresentation roleRep : entry.getValue()) {
+						RoleModel role = app.getRole(roleRep.getName());
+						addComposites(role, roleRep, newRealm);
+					}
+				}
+			}
+		}
+
+		// Setup realm default roles
+		if (rep.getDefaultRoles() != null) {
+			for (String roleString : rep.getDefaultRoles()) {
+				newRealm.addDefaultRole(roleString.trim());
+			}
+		}
+		// Setup application default roles
+		if (rep.getApplications() != null) {
+			for (ApplicationRepresentation resourceRep : rep.getApplications()) {
+				if (resourceRep.getDefaultRoles() != null) {
+					ApplicationModel appModel = newRealm.getApplicationByName(resourceRep.getName());
+					appModel.updateDefaultRoles(resourceRep.getDefaultRoles());
+				}
+			}
+		}
+
+		if (rep.getOauthClients() != null) {
+			createOAuthClients(rep, newRealm);
+		}
+
+		// Now that all possible roles and applications are created, create scope mappings
+
+		Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap();
+
+		if (rep.getApplicationScopeMappings() != null) {
+
+			for (Map.Entry<String, List<ScopeMappingRepresentation>> entry : rep.getApplicationScopeMappings().entrySet()) {
+				ApplicationModel app = appMap.get(entry.getKey());
+				if (app == null) {
+					throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
+				}
+				createApplicationScopeMappings(newRealm, app, entry.getValue());
+			}
+		}
+
+		if (rep.getScopeMappings() != null) {
+			for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
+				ClientModel client = newRealm.findClient(scope.getClient());
+				if (client == null) {
+					throw new RuntimeException("Unknown client specification in realm scope mappings");
+				}
+				for (String roleString : scope.getRoles()) {
+					RoleModel role = newRealm.getRole(roleString.trim());
+					if (role == null) {
+						role = newRealm.addRole(roleString.trim());
+					}
+					client.addScopeMapping(role);
+				}
+
+			}
+		}
+
+		if (rep.getSmtpServer() != null) {
+			newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
+		}
+
+		if (rep.getBrowserSecurityHeaders() != null) {
+			newRealm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
+		} else {
+			newRealm.setBrowserSecurityHeaders(BrowserSecurityHeaders.defaultHeaders);
+		}
+
+		if (rep.getUserFederationProviders() != null) {
+			List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
+			newRealm.setUserFederationProviders(providerModels);
+		}
+
+		// create users and their role mappings and social mappings
+
+		if (rep.getUsers() != null) {
+			for (UserRepresentation userRep : rep.getUsers()) {
+				UserModel user = createUser(session, newRealm, userRep, appMap);
+			}
+		}
+	}
+
+	public static void updateRealm(RealmRepresentation rep, RealmModel realm) {
+		if (rep.getRealm() != null) {
+			realm.setName(rep.getRealm());
+		}
+		if (rep.isEnabled() != null)
+			realm.setEnabled(rep.isEnabled());
+		if (rep.isBruteForceProtected() != null)
+			realm.setBruteForceProtected(rep.isBruteForceProtected());
+		if (rep.getMaxFailureWaitSeconds() != null)
+			realm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
+		if (rep.getMinimumQuickLoginWaitSeconds() != null)
+			realm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
+		if (rep.getWaitIncrementSeconds() != null)
+			realm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
+		if (rep.getQuickLoginCheckMilliSeconds() != null)
+			realm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
+		if (rep.getMaxDeltaTimeSeconds() != null)
+			realm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
+		if (rep.getFailureFactor() != null)
+			realm.setFailureFactor(rep.getFailureFactor());
+		if (rep.isPasswordCredentialGrantAllowed() != null)
+			realm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
+		if (rep.isRegistrationAllowed() != null)
+			realm.setRegistrationAllowed(rep.isRegistrationAllowed());
+		if (rep.isRegistrationEmailAsUsername() != null)
+			realm.setRegistrationEmailAsUsername(rep.isRegistrationEmailAsUsername());
+		if (rep.isRememberMe() != null)
+			realm.setRememberMe(rep.isRememberMe());
+		if (rep.isVerifyEmail() != null)
+			realm.setVerifyEmail(rep.isVerifyEmail());
+		if (rep.isResetPasswordAllowed() != null)
+			realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
+		if (rep.getSslRequired() != null)
+			realm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
+		if (rep.getAccessCodeLifespan() != null)
+			realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
+		if (rep.getAccessCodeLifespanUserAction() != null)
+			realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
+		if (rep.getAccessCodeLifespanLogin() != null)
+			realm.setAccessCodeLifespanLogin(rep.getAccessCodeLifespanLogin());
+		if (rep.getNotBefore() != null)
+			realm.setNotBefore(rep.getNotBefore());
+		if (rep.getAccessTokenLifespan() != null)
+			realm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
+		if (rep.getSsoSessionIdleTimeout() != null)
+			realm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
+		if (rep.getSsoSessionMaxLifespan() != null)
+			realm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
+		if (rep.getRequiredCredentials() != null) {
+			realm.updateRequiredCredentials(rep.getRequiredCredentials());
+		}
+		if (rep.getLoginTheme() != null)
+			realm.setLoginTheme(rep.getLoginTheme());
+		if (rep.getAccountTheme() != null)
+			realm.setAccountTheme(rep.getAccountTheme());
+		if (rep.getAdminTheme() != null)
+			realm.setAdminTheme(rep.getAdminTheme());
+		if (rep.getEmailTheme() != null)
+			realm.setEmailTheme(rep.getEmailTheme());
+		if (rep.isEventsEnabled() != null)
+			realm.setEventsEnabled(rep.isEventsEnabled());
+		if (rep.getEventsExpiration() != null)
+			realm.setEventsExpiration(rep.getEventsExpiration());
+		if (rep.getEventsListeners() != null)
+			realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
+
+		if (rep.getPasswordPolicy() != null)
+			realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
+
+		if (rep.getDefaultRoles() != null) {
+			realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()]));
+		}
+
+		if (rep.getSmtpServer() != null) {
+			realm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
+		}
+
+		if (rep.getBrowserSecurityHeaders() != null) {
+			realm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
+		}
+
+		if (rep.getUserFederationProviders() != null) {
+			List<UserFederationProviderModel> providerModels = convertFederationProviders(rep.getUserFederationProviders());
+			realm.setUserFederationProviders(providerModels);
+		}
+
+		if ("GENERATE".equals(rep.getPublicKey())) {
+			KeycloakModelUtils.generateRealmKeys(realm);
+		}
+	}
+
+	// Basic realm stuff
+
+	public static void addRequiredCredential(RealmModel newRealm, String requiredCred) {
+		newRealm.addRequiredCredential(requiredCred);
+	}
+
+	private static List<UserFederationProviderModel> convertFederationProviders(
+			List<UserFederationProviderRepresentation> providers) {
+		List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
+
+		for (UserFederationProviderRepresentation representation : providers) {
+			UserFederationProviderModel model = new UserFederationProviderModel(representation.getId(),
+					representation.getProviderName(), representation.getConfig(), representation.getPriority(),
+					representation.getDisplayName(), representation.getFullSyncPeriod(), representation.getChangedSyncPeriod(),
+					representation.getLastSync());
+			result.add(model);
+		}
+		return result;
+	}
+
+	// Roles
+
+	public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
+		RoleModel role = roleRep.getId() != null ? newRealm.addRole(roleRep.getId(), roleRep.getName()) : newRealm
+				.addRole(roleRep.getName());
+		if (roleRep.getDescription() != null)
+			role.setDescription(roleRep.getDescription());
+	}
+
+	private static void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
+		if (roleRep.getComposites() == null)
+			return;
+		if (roleRep.getComposites().getRealm() != null) {
+			for (String roleStr : roleRep.getComposites().getRealm()) {
+				RoleModel realmRole = realm.getRole(roleStr);
+				if (realmRole == null)
+					throw new RuntimeException("Unable to find composite realm role: " + roleStr);
+				role.addCompositeRole(realmRole);
+			}
+		}
+		if (roleRep.getComposites().getApplication() != null) {
+			for (Map.Entry<String, List<String>> entry : roleRep.getComposites().getApplication().entrySet()) {
+				ApplicationModel app = realm.getApplicationByName(entry.getKey());
+				if (app == null) {
+					throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName());
+				}
+				for (String roleStr : entry.getValue()) {
+					RoleModel appRole = app.getRole(roleStr);
+					if (appRole == null)
+						throw new RuntimeException("Unable to find composite app role: " + roleStr);
+					role.addCompositeRole(appRole);
+				}
+
+			}
+
+		}
+
+	}
+
+	// APPLICATIONS
+
+	private static Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
+		Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
+		for (ApplicationRepresentation resourceRep : rep.getApplications()) {
+			ApplicationModel app = createApplication(realm, resourceRep, false);
+			appMap.put(app.getName(), app);
+		}
+		return appMap;
+	}
+
+	/**
+	 * Does not create scope or role mappings!
+	 * 
+	 * @param realm
+	 * @param resourceRep
+	 * @return
+	 */
+	public static ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep,
+			boolean addDefaultRoles) {
+		logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
+		ApplicationModel applicationModel = resourceRep.getId() != null ? realm.addApplication(resourceRep.getId(),
+				resourceRep.getName()) : realm.addApplication(resourceRep.getName());
+		if (resourceRep.isEnabled() != null)
+			applicationModel.setEnabled(resourceRep.isEnabled());
+		applicationModel.setManagementUrl(resourceRep.getAdminUrl());
+		if (resourceRep.isSurrogateAuthRequired() != null)
+			applicationModel.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
+		applicationModel.setBaseUrl(resourceRep.getBaseUrl());
+		if (resourceRep.isBearerOnly() != null)
+			applicationModel.setBearerOnly(resourceRep.isBearerOnly());
+		if (resourceRep.isPublicClient() != null)
+			applicationModel.setPublicClient(resourceRep.isPublicClient());
+		if (resourceRep.isFrontchannelLogout() != null)
+			applicationModel.setFrontchannelLogout(resourceRep.isFrontchannelLogout());
+		if (resourceRep.getProtocol() != null)
+			applicationModel.setProtocol(resourceRep.getProtocol());
+		if (resourceRep.isFullScopeAllowed() != null) {
+			applicationModel.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
+		} else {
+			applicationModel.setFullScopeAllowed(true);
+		}
+		if (resourceRep.getNodeReRegistrationTimeout() != null) {
+			applicationModel.setNodeReRegistrationTimeout(resourceRep.getNodeReRegistrationTimeout());
+		} else {
+			applicationModel.setNodeReRegistrationTimeout(-1);
+		}
+		applicationModel.updateApplication();
+
+		if (resourceRep.getNotBefore() != null) {
+			applicationModel.setNotBefore(resourceRep.getNotBefore());
+		}
+
+		applicationModel.setSecret(resourceRep.getSecret());
+		if (applicationModel.getSecret() == null) {
+			KeycloakModelUtils.generateSecret(applicationModel);
+		}
+
+		if (resourceRep.getAttributes() != null) {
+			for (Map.Entry<String, String> entry : resourceRep.getAttributes().entrySet()) {
+				applicationModel.setAttribute(entry.getKey(), entry.getValue());
+			}
+		}
+
+		if (resourceRep.getRedirectUris() != null) {
+			for (String redirectUri : resourceRep.getRedirectUris()) {
+				applicationModel.addRedirectUri(redirectUri);
+			}
+		}
+		if (resourceRep.getWebOrigins() != null) {
+			for (String webOrigin : resourceRep.getWebOrigins()) {
+				logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getName(), webOrigin);
+				applicationModel.addWebOrigin(webOrigin);
+			}
+		} else {
+			// add origins from redirect uris
+			if (resourceRep.getRedirectUris() != null) {
+				Set<String> origins = new HashSet<String>();
+				for (String redirectUri : resourceRep.getRedirectUris()) {
+					logger.debugv("add redirect-uri to origin: {0}", redirectUri);
+					if (redirectUri.startsWith("http:")) {
+						URI uri = URI.create(redirectUri);
+						String origin = uri.getScheme() + "://" + uri.getHost();
+						if (uri.getPort() != -1) {
+							origin += ":" + uri.getPort();
+						}
+						logger.debugv("adding default application origin: {0}", origin);
+						origins.add(origin);
+					}
+				}
+				if (origins.size() > 0) {
+					applicationModel.setWebOrigins(origins);
+				}
+			}
+		}
+
+		if (resourceRep.getRegisteredNodes() != null) {
+			for (Map.Entry<String, Integer> entry : resourceRep.getRegisteredNodes().entrySet()) {
+				applicationModel.registerNode(entry.getKey(), entry.getValue());
+			}
+		}
+
+		if (addDefaultRoles && resourceRep.getDefaultRoles() != null) {
+			applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
+		}
+
+		if (resourceRep.getProtocolMappers() != null) {
+			// first, remove all default/built in mappers
+			Set<ProtocolMapperModel> mappers = applicationModel.getProtocolMappers();
+			for (ProtocolMapperModel mapper : mappers)
+				applicationModel.removeProtocolMapper(mapper);
+
+			for (ProtocolMapperRepresentation mapper : resourceRep.getProtocolMappers()) {
+				applicationModel.addProtocolMapper(toModel(mapper));
+			}
+		}
+
+		applicationModel.updateAllowedIdentityProviders(toModel(resourceRep.getIdentityProviders(), realm));
+
+		return applicationModel;
+	}
+
+	public static void updateApplication(ApplicationRepresentation rep, ApplicationModel resource) {
+		if (rep.getName() != null)
+			resource.setName(rep.getName());
+		if (rep.isEnabled() != null)
+			resource.setEnabled(rep.isEnabled());
+		if (rep.isBearerOnly() != null)
+			resource.setBearerOnly(rep.isBearerOnly());
+		if (rep.isPublicClient() != null)
+			resource.setPublicClient(rep.isPublicClient());
+		if (rep.isFullScopeAllowed() != null)
+			resource.setFullScopeAllowed(rep.isFullScopeAllowed());
+		if (rep.isFrontchannelLogout() != null)
+			resource.setFrontchannelLogout(rep.isFrontchannelLogout());
+		if (rep.getAdminUrl() != null)
+			resource.setManagementUrl(rep.getAdminUrl());
+		if (rep.getBaseUrl() != null)
+			resource.setBaseUrl(rep.getBaseUrl());
+		if (rep.isSurrogateAuthRequired() != null)
+			resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
+		if (rep.getNodeReRegistrationTimeout() != null)
+			resource.setNodeReRegistrationTimeout(rep.getNodeReRegistrationTimeout());
+		resource.updateApplication();
+
+		if (rep.getProtocol() != null)
+			resource.setProtocol(rep.getProtocol());
+		if (rep.getAttributes() != null) {
+			for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
+				resource.setAttribute(entry.getKey(), entry.getValue());
+			}
+		}
+
+		if (rep.getNotBefore() != null) {
+			resource.setNotBefore(rep.getNotBefore());
+		}
+		if (rep.getDefaultRoles() != null) {
+			resource.updateDefaultRoles(rep.getDefaultRoles());
+		}
+
+		List<String> redirectUris = rep.getRedirectUris();
+		if (redirectUris != null) {
+			resource.setRedirectUris(new HashSet<String>(redirectUris));
+		}
+
+		List<String> webOrigins = rep.getWebOrigins();
+		if (webOrigins != null) {
+			resource.setWebOrigins(new HashSet<String>(webOrigins));
+		}
+
+		if (rep.getRegisteredNodes() != null) {
+			for (Map.Entry<String, Integer> entry : rep.getRegisteredNodes().entrySet()) {
+				resource.registerNode(entry.getKey(), entry.getValue());
+			}
+		}
+
+		updateClientIdentityProvides(rep.getIdentityProviders(), resource);
+	}
+
+	public static void setClaims(ClientModel model, ClaimRepresentation rep) {
+		long mask = model.getAllowedClaimsMask();
+		if (rep.getAddress()) {
+			mask |= ClaimMask.ADDRESS;
+		} else {
+			mask &= ~ClaimMask.ADDRESS;
+		}
+		if (rep.getEmail()) {
+			mask |= ClaimMask.EMAIL;
+		} else {
+			mask &= ~ClaimMask.EMAIL;
+		}
+		if (rep.getGender()) {
+			mask |= ClaimMask.GENDER;
+		} else {
+			mask &= ~ClaimMask.GENDER;
+		}
+		if (rep.getLocale()) {
+			mask |= ClaimMask.LOCALE;
+		} else {
+			mask &= ~ClaimMask.LOCALE;
+		}
+		if (rep.getName()) {
+			mask |= ClaimMask.NAME;
+		} else {
+			mask &= ~ClaimMask.NAME;
+		}
+		if (rep.getPhone()) {
+			mask |= ClaimMask.PHONE;
+		} else {
+			mask &= ~ClaimMask.PHONE;
+		}
+		if (rep.getPicture()) {
+			mask |= ClaimMask.PICTURE;
+		} else {
+			mask &= ~ClaimMask.PICTURE;
+		}
+		if (rep.getProfile()) {
+			mask |= ClaimMask.PROFILE;
+		} else {
+			mask &= ~ClaimMask.PROFILE;
+		}
+		if (rep.getUsername()) {
+			mask |= ClaimMask.USERNAME;
+		} else {
+			mask &= ~ClaimMask.USERNAME;
+		}
+		if (rep.getWebsite()) {
+			mask |= ClaimMask.WEBSITE;
+		} else {
+			mask &= ~ClaimMask.WEBSITE;
+		}
+		model.setAllowedClaimsMask(mask);
+	}
+
+	// OAuth clients
+
+	private static void createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
+		for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
+			createOAuthClient(rep, realm);
+		}
+	}
+
+	public static OAuthClientModel createOAuthClient(String id, String name, RealmModel realm) {
+		OAuthClientModel model = id != null ? realm.addOAuthClient(id, name) : realm.addOAuthClient(name);
+		KeycloakModelUtils.generateSecret(model);
+		return model;
+	}
+
+	public static OAuthClientModel createOAuthClient(OAuthClientRepresentation rep, RealmModel realm) {
+		OAuthClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
+
+		model.updateAllowedIdentityProviders(toModel(rep.getIdentityProviders(), realm));
+
+		updateOAuthClient(rep, model);
+		return model;
+	}
+
+	public static void updateOAuthClient(OAuthClientRepresentation rep, OAuthClientModel model) {
+		if (rep.getName() != null)
+			model.setClientId(rep.getName());
+		if (rep.isEnabled() != null)
+			model.setEnabled(rep.isEnabled());
+		if (rep.isPublicClient() != null)
+			model.setPublicClient(rep.isPublicClient());
+		if (rep.isFrontchannelLogout() != null)
+			model.setFrontchannelLogout(rep.isFrontchannelLogout());
+		if (rep.isFullScopeAllowed() != null)
+			model.setFullScopeAllowed(rep.isFullScopeAllowed());
+		if (rep.isDirectGrantsOnly() != null)
+			model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
+		if (rep.getClaims() != null) {
+			setClaims(model, rep.getClaims());
+		}
+		if (rep.getNotBefore() != null) {
+			model.setNotBefore(rep.getNotBefore());
+		}
+		if (rep.getSecret() != null)
+			model.setSecret(rep.getSecret());
+		List<String> redirectUris = rep.getRedirectUris();
+		if (redirectUris != null) {
+			model.setRedirectUris(new HashSet<String>(redirectUris));
+		}
+
+		List<String> webOrigins = rep.getWebOrigins();
+		if (webOrigins != null) {
+			model.setWebOrigins(new HashSet<String>(webOrigins));
+		}
+
+		if (rep.getNotBefore() != null) {
+			model.setNotBefore(rep.getNotBefore());
+		}
+		if (rep.getProtocol() != null)
+			model.setProtocol(rep.getProtocol());
+		if (rep.getAttributes() != null) {
+			for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
+				model.setAttribute(entry.getKey(), entry.getValue());
+			}
+		}
+
+		updateClientIdentityProvides(rep.getIdentityProviders(), model);
+
+		if (rep.getProtocolMappers() != null) {
+			// first, remove all default/built in mappers
+			Set<ProtocolMapperModel> mappers = model.getProtocolMappers();
+			for (ProtocolMapperModel mapper : mappers)
+				model.removeProtocolMapper(mapper);
+
+			for (ProtocolMapperRepresentation mapper : rep.getProtocolMappers()) {
+				model.addProtocolMapper(toModel(mapper));
+			}
+		}
+
+	}
+
+	// Scope mappings
+
+	public static void createApplicationScopeMappings(RealmModel realm, ApplicationModel applicationModel,
+			List<ScopeMappingRepresentation> mappings) {
+		for (ScopeMappingRepresentation mapping : mappings) {
+			ClientModel client = realm.findClient(mapping.getClient());
+			if (client == null) {
+				throw new RuntimeException("Unknown client specified in application scope mappings");
+			}
+			for (String roleString : mapping.getRoles()) {
+				RoleModel role = applicationModel.getRole(roleString.trim());
+				if (role == null) {
+					role = applicationModel.addRole(roleString.trim());
+				}
+				client.addScopeMapping(role);
+			}
+		}
+	}
+
+	// Users
+
+	public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep,
+			Map<String, ApplicationModel> appMap) {
+		// Import users just to user storage. Don't federate
+		UserModel user = session.userStorage().addUser(newRealm, userRep.getId(), userRep.getUsername(), false);
+		user.setEnabled(userRep.isEnabled());
+		user.setEmail(userRep.getEmail());
+		user.setFirstName(userRep.getFirstName());
+		user.setLastName(userRep.getLastName());
+		user.setFederationLink(userRep.getFederationLink());
+		user.setTotp(userRep.isTotp());
+		if (userRep.getAttributes() != null) {
+			for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
+				user.setAttribute(entry.getKey(), entry.getValue());
+			}
+		}
+		if (userRep.getRequiredActions() != null) {
+			for (String requiredAction : userRep.getRequiredActions()) {
+				user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction));
+			}
+		}
+		if (userRep.getCredentials() != null) {
+			for (CredentialRepresentation cred : userRep.getCredentials()) {
+				updateCredential(user, cred);
+			}
+		}
+		if (userRep.getFederatedIdentities() != null) {
+			for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
+				FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(),
+						identity.getUserId(), identity.getUserName());
+				session.users().addFederatedIdentity(newRealm, user, mappingModel);
+			}
+		}
+		if (userRep.getRealmRoles() != null) {
+			for (String roleString : userRep.getRealmRoles()) {
+				RoleModel role = newRealm.getRole(roleString.trim());
+				if (role == null) {
+					role = newRealm.addRole(roleString.trim());
+				}
+				user.grantRole(role);
+			}
+		}
+		if (userRep.getApplicationRoles() != null) {
+			for (Map.Entry<String, List<String>> entry : userRep.getApplicationRoles().entrySet()) {
+				ApplicationModel app = appMap.get(entry.getKey());
+				if (app == null) {
+					throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
+				}
+				createApplicationRoleMappings(app, user, entry.getValue());
+			}
+		}
+		return user;
+	}
+
+	// Detect if it is "plain-text" or "hashed" representation and update model according to it
+	private static void updateCredential(UserModel user, CredentialRepresentation cred) {
+		if (cred.getValue() != null) {
+			UserCredentialModel plainTextCred = convertCredential(cred);
+			user.updateCredential(plainTextCred);
+		} else {
+			UserCredentialValueModel hashedCred = new UserCredentialValueModel();
+			hashedCred.setType(cred.getType());
+			hashedCred.setDevice(cred.getDevice());
+			hashedCred.setHashIterations(cred.getHashIterations());
+			try {
+				if (cred.getSalt() != null)
+					hashedCred.setSalt(Base64.decode(cred.getSalt()));
+			} catch (IOException ioe) {
+				throw new RuntimeException(ioe);
+			}
+			hashedCred.setValue(cred.getHashedSaltedValue());
+			user.updateCredentialDirectly(hashedCred);
+		}
+	}
+
+	public static UserCredentialModel convertCredential(CredentialRepresentation cred) {
+		UserCredentialModel credential = new UserCredentialModel();
+		credential.setType(cred.getType());
+		credential.setValue(cred.getValue());
+		return credential;
+	}
+
+	// Role mappings
+
+	public static void createApplicationRoleMappings(ApplicationModel applicationModel, UserModel user,
+			List<String> roleNames) {
+		if (user == null) {
+			throw new RuntimeException("User not found");
+		}
+
+		for (String roleName : roleNames) {
+			RoleModel role = applicationModel.getRole(roleName.trim());
+			if (role == null) {
+				role = applicationModel.addRole(roleName.trim());
+			}
+			user.grantRole(role);
+
+		}
+	}
+
+	private static void importIdentityProviders(RealmRepresentation rep, RealmModel newRealm) {
+		if (rep.getIdentityProviders() != null) {
+			for (IdentityProviderRepresentation representation : rep.getIdentityProviders()) {
+				newRealm.addIdentityProvider(toModel(representation));
+			}
+		}
+	}
+
+	public static IdentityProviderModel toModel(IdentityProviderRepresentation representation) {
+		IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+		identityProviderModel.setInternalId(representation.getInternalId());
+		identityProviderModel.setId(representation.getId());
+		identityProviderModel.setProviderId(representation.getProviderId());
+		identityProviderModel.setName(representation.getName());
+		identityProviderModel.setEnabled(representation.isEnabled());
+		identityProviderModel.setUpdateProfileFirstLogin(representation.isUpdateProfileFirstLogin());
+		identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
+		identityProviderModel.setStoreToken(representation.isStoreToken());
+		identityProviderModel.setConfig(representation.getConfig());
+
+		return identityProviderModel;
+	}
+
+	public static ProtocolMapperModel toModel(ProtocolMapperRepresentation rep) {
+		ProtocolMapperModel model = new ProtocolMapperModel();
+		model.setId(rep.getId());
+		model.setName(rep.getName());
+		model.setConsentRequired(rep.isConsentRequired());
+		model.setConsentText(rep.getConsentText());
+		model.setProtocol(rep.getProtocol());
+		model.setProtocolMapper(rep.getProtocolMapper());
+		model.setConfig(rep.getConfig());
+		return model;
+	}
+
+	private static List<ClientIdentityProviderMappingModel> toModel(
+			List<ClientIdentityProviderMappingRepresentation> repIdentityProviders, RealmModel realm) {
+		List<ClientIdentityProviderMappingModel> allowedIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
+
+		if (repIdentityProviders == null || repIdentityProviders.isEmpty()) {
+			allowedIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
+
+			for (IdentityProviderModel identityProvider : realm.getIdentityProviders()) {
+				ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
+
+				identityProviderMapping.setIdentityProvider(identityProvider.getId());
+
+				allowedIdentityProviders.add(identityProviderMapping);
+			}
+		} else {
+			for (ClientIdentityProviderMappingRepresentation rep : repIdentityProviders) {
+				ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
+
+				identityProviderMapping.setIdentityProvider(rep.getId());
+				identityProviderMapping.setRetrieveToken(rep.isRetrieveToken());
+
+				allowedIdentityProviders.add(identityProviderMapping);
+			}
+		}
+
+		return allowedIdentityProviders;
+	}
+
+	private static void updateClientIdentityProvides(List<ClientIdentityProviderMappingRepresentation> identityProviders,
+			ClientModel resource) {
+		if (identityProviders != null) {
+			List<ClientIdentityProviderMappingModel> allowedIdentityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
+
+			for (ClientIdentityProviderMappingRepresentation mappingRepresentation : identityProviders) {
+				ClientIdentityProviderMappingModel identityProviderMapping = new ClientIdentityProviderMappingModel();
+
+				identityProviderMapping.setIdentityProvider(mappingRepresentation.getId());
+				identityProviderMapping.setRetrieveToken(mappingRepresentation.isRetrieveToken());
+
+				allowedIdentityProviders.add(identityProviderMapping);
+			}
+
+			resource.updateAllowedIdentityProviders(allowedIdentityProviders);
+		}
+	}
 }
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
index c2cfab8..1151b32 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
@@ -16,21 +16,6 @@
  */
 package org.keycloak.models.file.adapter;
 
-import org.keycloak.enums.SslRequired;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
-import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RequiredCredentialModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserFederationProviderModel;
-import org.keycloak.models.entities.RequiredCredentialEntity;
-import org.keycloak.models.entities.UserFederationProviderEntity;
-import org.keycloak.models.utils.KeycloakModelUtils;
-
 import java.security.Key;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -46,1028 +31,1091 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
+import org.keycloak.enums.SslRequired;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.entities.ApplicationEntity;
 import org.keycloak.models.entities.ClientEntity;
 import org.keycloak.models.entities.OAuthClientEntity;
 import org.keycloak.models.entities.RealmEntity;
+import org.keycloak.models.entities.RequiredCredentialEntity;
 import org.keycloak.models.entities.RoleEntity;
+import org.keycloak.models.entities.UserFederationProviderEntity;
 import org.keycloak.models.file.InMemoryModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
 
 /**
  * RealmModel for JSON persistence.
- *
+ * 
  * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
  */
 public class RealmAdapter implements RealmModel {
 
-    private final InMemoryModel inMemoryModel;
-    private final RealmEntity realm;
-
-    protected volatile transient PublicKey publicKey;
-    protected volatile transient PrivateKey privateKey;
-    protected volatile transient X509Certificate certificate;
-    protected volatile transient Key codeSecretKey;
-
-    private volatile transient PasswordPolicy passwordPolicy;
-    private volatile transient KeycloakSession session;
-
-    private final Map<String, ApplicationModel> allApps = new HashMap<String, ApplicationModel>();
-    private ApplicationModel masterAdminApp = null;
-    private final Map<String, RoleAdapter> allRoles = new HashMap<String, RoleAdapter>();
-    private final Map<String, OAuthClientAdapter> allOAuthClients = new HashMap<String, OAuthClientAdapter>();
-    private final Map<String, IdentityProviderModel> allIdProviders = new HashMap<String, IdentityProviderModel>();
-
-    public RealmAdapter(KeycloakSession session, RealmEntity realm, InMemoryModel inMemoryModel) {
-        this.session = session;
-        this.realm = realm;
-        this.inMemoryModel = inMemoryModel;
-    }
-
-    public RealmEntity getRealmEnity() {
-        return realm;
-    }
-
-    @Override
-    public String getId() {
-        return realm.getId();
-    }
-
-    @Override
-    public String getName() {
-        return realm.getName();
-    }
-
-    @Override
-    public void setName(String name) {
-        if (getName() == null) {
-            realm.setName(name);
-            return;
-        }
-
-        if (getName().equals(name)) return; // allow setting name to same value
-
-        if (inMemoryModel.getRealmByName(name) != null) throw new ModelDuplicateException("Realm " + name + " already exists.");
-        realm.setName(name);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return realm.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        realm.setEnabled(enabled);
-    }
-
-    @Override
-    public SslRequired getSslRequired() {
-        return SslRequired.valueOf(realm.getSslRequired());
-    }
-
-    @Override
-    public void setSslRequired(SslRequired sslRequired) {
-        realm.setSslRequired(sslRequired.name());
-    }
-
-    @Override
-    public boolean isPasswordCredentialGrantAllowed() {
-        return realm.isPasswordCredentialGrantAllowed();
-    }
-
-    @Override
-    public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
-        realm.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
-    }
-
-    @Override
-    public boolean isRegistrationAllowed() {
-        return realm.isRegistrationAllowed();
-    }
-
-    @Override
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        realm.setRegistrationAllowed(registrationAllowed);
-    }
-
-    @Override
-    public boolean isRememberMe() {
-        return realm.isRememberMe();
-    }
-
-    @Override
-    public void setRememberMe(boolean rememberMe) {
-        realm.setRememberMe(rememberMe);
-    }
-
-    @Override
-    public boolean isBruteForceProtected() {
-        return realm.isBruteForceProtected();
-    }
-
-    @Override
-    public void setBruteForceProtected(boolean value) {
-        realm.setBruteForceProtected(value);
-    }
-
-    @Override
-    public int getMaxFailureWaitSeconds() {
-        return realm.getMaxFailureWaitSeconds();
-    }
-
-    @Override
-    public void setMaxFailureWaitSeconds(int val) {
-        realm.setMaxFailureWaitSeconds(val);
-    }
-
-    @Override
-    public int getWaitIncrementSeconds() {
-        return realm.getWaitIncrementSeconds();
-    }
-
-    @Override
-    public void setWaitIncrementSeconds(int val) {
-        realm.setWaitIncrementSeconds(val);
-    }
-
-    @Override
-    public long getQuickLoginCheckMilliSeconds() {
-        return realm.getQuickLoginCheckMilliSeconds();
-    }
-
-    @Override
-    public void setQuickLoginCheckMilliSeconds(long val) {
-        realm.setQuickLoginCheckMilliSeconds(val);
-    }
-
-    @Override
-    public int getMinimumQuickLoginWaitSeconds() {
-        return realm.getMinimumQuickLoginWaitSeconds();
-    }
-
-    @Override
-    public void setMinimumQuickLoginWaitSeconds(int val) {
-        realm.setMinimumQuickLoginWaitSeconds(val);
-    }
-
-
-    @Override
-    public int getMaxDeltaTimeSeconds() {
-        return realm.getMaxDeltaTimeSeconds();
-    }
-
-    @Override
-    public void setMaxDeltaTimeSeconds(int val) {
-        realm.setMaxDeltaTimeSeconds(val);
-    }
-
-    @Override
-    public int getFailureFactor() {
-        return realm.getFailureFactor();
-    }
-
-    @Override
-    public void setFailureFactor(int failureFactor) {
-        realm.setFailureFactor(failureFactor);
-    }
-
-
-    @Override
-    public boolean isVerifyEmail() {
-        return realm.isVerifyEmail();
-    }
-
-    @Override
-    public void setVerifyEmail(boolean verifyEmail) {
-        realm.setVerifyEmail(verifyEmail);
-    }
-
-    @Override
-    public boolean isResetPasswordAllowed() {
-        return realm.isResetPasswordAllowed();
-    }
-
-    @Override
-    public void setResetPasswordAllowed(boolean resetPassword) {
-        realm.setResetPasswordAllowed(resetPassword);
-    }
-
-    @Override
-    public PasswordPolicy getPasswordPolicy() {
-        if (passwordPolicy == null) {
-            passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
-        }
-        return passwordPolicy;
-    }
-
-    @Override
-    public void setPasswordPolicy(PasswordPolicy policy) {
-        this.passwordPolicy = policy;
-        realm.setPasswordPolicy(policy.toString());
-    }
-
-    @Override
-    public int getNotBefore() {
-        return realm.getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        realm.setNotBefore(notBefore);
-    }
-
-
-    @Override
-    public int getSsoSessionIdleTimeout() {
-        return realm.getSsoSessionIdleTimeout();
-    }
-
-    @Override
-    public void setSsoSessionIdleTimeout(int seconds) {
-        realm.setSsoSessionIdleTimeout(seconds);
-    }
-
-    @Override
-    public int getSsoSessionMaxLifespan() {
-        return realm.getSsoSessionMaxLifespan();
-    }
-
-    @Override
-    public void setSsoSessionMaxLifespan(int seconds) {
-        realm.setSsoSessionMaxLifespan(seconds);
-    }
-
-    @Override
-    public int getAccessTokenLifespan() {
-        return realm.getAccessTokenLifespan();
-    }
-
-    @Override
-    public void setAccessTokenLifespan(int tokenLifespan) {
-        realm.setAccessTokenLifespan(tokenLifespan);
-    }
-
-    @Override
-    public int getAccessCodeLifespan() {
-        return realm.getAccessCodeLifespan();
-    }
-
-    @Override
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        realm.setAccessCodeLifespan(accessCodeLifespan);
-    }
-
-    @Override
-    public int getAccessCodeLifespanUserAction() {
-        return realm.getAccessCodeLifespanUserAction();
-    }
-
-    @Override
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
-    }
-
-    @Override
-    public String getPublicKeyPem() {
-        return realm.getPublicKeyPem();
-    }
-
-    @Override
-    public void setPublicKeyPem(String publicKeyPem) {
-        realm.setPublicKeyPem(publicKeyPem);
-        this.publicKey = null;
-    }
-
-    @Override
-    public X509Certificate getCertificate() {
-        if (certificate != null) return certificate;
-        certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
-        return certificate;
-    }
-
-    @Override
-    public void setCertificate(X509Certificate certificate) {
-        this.certificate = certificate;
-        String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
-        setCertificatePem(certificatePem);
-    }
-
-    @Override
-    public String getCertificatePem() {
-        return realm.getCertificatePem();
-    }
-
-    @Override
-    public void setCertificatePem(String certificate) {
-        realm.setCertificatePem(certificate);
-
-    }
-
-
-    @Override
-    public String getPrivateKeyPem() {
-        return realm.getPrivateKeyPem();
-    }
-
-    @Override
-    public void setPrivateKeyPem(String privateKeyPem) {
-        realm.setPrivateKeyPem(privateKeyPem);
-        this.privateKey = null;
-    }
-
-    @Override
-    public PublicKey getPublicKey() {
-        if (publicKey != null) return publicKey;
-        publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
-        return publicKey;
-    }
-
-    @Override
-    public void setPublicKey(PublicKey publicKey) {
-        this.publicKey = publicKey;
-        String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
-        setPublicKeyPem(publicKeyPem);
-    }
-
-    @Override
-    public PrivateKey getPrivateKey() {
-        if (privateKey != null) return privateKey;
-        privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
-        return privateKey;
-    }
-
-    @Override
-    public void setPrivateKey(PrivateKey privateKey) {
-        this.privateKey = privateKey;
-        String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
-        setPrivateKeyPem(privateKeyPem);
-    }
-
-    @Override
-    public String getCodeSecret() {
-        return realm.getCodeSecret();
-    }
-
-    @Override
-    public Key getCodeSecretKey() {
-        if (codeSecretKey == null) {
-            codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
-        }
-        return codeSecretKey;
-    }
-
-    @Override
-    public void setCodeSecret(String codeSecret) {
-        realm.setCodeSecret(codeSecret);
-    }
-
-    @Override
-    public String getLoginTheme() {
-        return realm.getLoginTheme();
-    }
-
-    @Override
-    public void setLoginTheme(String name) {
-        realm.setLoginTheme(name);
-    }
-
-    @Override
-    public String getAccountTheme() {
-        return realm.getAccountTheme();
-    }
-
-    @Override
-    public void setAccountTheme(String name) {
-        realm.setAccountTheme(name);
-    }
-
-    @Override
-    public String getAdminTheme() {
-        return realm.getAdminTheme();
-    }
-
-    @Override
-    public void setAdminTheme(String name) {
-        realm.setAdminTheme(name);
-    }
-
-    @Override
-    public String getEmailTheme() {
-        return realm.getEmailTheme();
-    }
-
-    @Override
-    public void setEmailTheme(String name) {
-        realm.setEmailTheme(name);
-    }
-
-    @Override
-    public RoleAdapter getRole(String name) {
-        for (RoleAdapter role : allRoles.values()) {
-            if (role.getName().equals(name)) return role;
-        }
-        return null;
-    }
-
-    @Override
-    public RoleModel addRole(String name) {
-        return this.addRole(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public RoleModel addRole(String id, String name) {
-        if (id == null) throw new NullPointerException("id == null");
-        if (name == null) throw new NullPointerException("name == null");
-        if (hasRoleWithName(name)) throw new ModelDuplicateException("Realm already contains role with name " + name + ".");
-
-        RoleEntity roleEntity = new RoleEntity();
-        roleEntity.setId(id);
-        roleEntity.setName(name);
-        roleEntity.setRealmId(getId());
-
-        RoleAdapter roleModel = new RoleAdapter(this, roleEntity, this);
-        allRoles.put(id, roleModel);
-        return roleModel;
-    }
-
-    @Override
-    public boolean removeRole(RoleModel role) {
-        return removeRoleById(role.getId());
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        if (id == null) throw new NullPointerException("id == null");
-
-        // try realm roles first
-        if (allRoles.remove(id) != null) return true;
-
-        for (ApplicationModel app : getApplications()) {
-            for (RoleModel appRole : app.getRoles()) {
-                if (id.equals(appRole.getId())) {
-                    app.removeRole(appRole);
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public Set<RoleModel> getRoles() {
-        return new HashSet(allRoles.values());
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        RoleModel found = allRoles.get(id);
-        if (found != null) return found;
-
-        for (ApplicationModel app : getApplications()) {
-            for (RoleModel appRole : app.getRoles()) {
-                if (appRole.getId().equals(id)) return appRole;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<String> getDefaultRoles() {
-        return realm.getDefaultRoles();
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        RoleModel role = getRole(name);
-        if (role == null) {
-            addRole(name);
-        }
-
-        List<String> roleNames = getDefaultRoles();
-        if (roleNames.contains(name)) throw new IllegalArgumentException("Realm " + realm.getName() + " already contains default role named " + name);
-
-        roleNames.add(name);
-        realm.setDefaultRoles(roleNames);
-    }
-
-    boolean hasRoleWithName(String name) {
-        for (RoleModel role : allRoles.values()) {
-            if (role.getName().equals(name)) return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        List<String> roleNames = new ArrayList<String>();
-        for (String roleName : defaultRoles) {
-            RoleModel role = getRole(roleName);
-            if (role == null) {
-                addRole(roleName);
-            }
-
-            roleNames.add(roleName);
-        }
-
-        realm.setDefaultRoles(roleNames);
-    }
-
-    @Override
-    public ClientModel findClient(String clientId) {
-        ClientModel model = getApplicationByName(clientId);
-        if (model != null) return model;
-        return getOAuthClient(clientId);
-    }
-
-    @Override
-    public ClientModel findClientById(String id) {
-        ClientModel clientModel = getApplicationById(id);
-        if (clientModel != null) return clientModel;
-        return getOAuthClientById(id);
-    }
-
-
-
-    @Override
-    public ApplicationModel getApplicationById(String id) {
-        return allApps.get(id);
-    }
-
-    @Override
-    public ApplicationModel getApplicationByName(String name) {
-        for (ApplicationModel app : getApplications()) {
-            if (app.getName().equals(name)) return app;
-        }
-
-        return null;
-    }
-
-    @Override
-    public Map<String, ApplicationModel> getApplicationNameMap() {
-        Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
-        for (ApplicationModel resource : getApplications()) {
-            resourceMap.put(resource.getName(), resource);
-        }
-        return resourceMap;
-    }
-
-    @Override
-    public List<ApplicationModel> getApplications() {
-        return new ArrayList<ApplicationModel>(allApps.values());
-    }
-
-    @Override
-    public ApplicationModel addApplication(String name) {
-        return this.addApplication(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public ApplicationModel addApplication(String id, String name) {
-        if (name == null) throw new NullPointerException("name == null");
-        if (id == null) throw new NullPointerException("id == null");
-
-        if (getApplicationNameMap().containsKey(name)) {
-            throw new ModelDuplicateException("Application named '" + name + "' already exists.");
-        }
-
-        ApplicationEntity appEntity = new ApplicationEntity();
-        appEntity.setId(id);
-        appEntity.setName(name);
-        appEntity.setRealmId(getId());
-        appEntity.setEnabled(true);
-
-        ClientEntity clientEntity = new ClientEntity();
-        clientEntity.setId(id);
-        clientEntity.setName(name);
-        clientEntity.setRealmId(getId());
-        clientEntity.setEnabled(true);
-
-        final ApplicationModel app = new ApplicationAdapter(session, this, appEntity, clientEntity, inMemoryModel);
-        session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
-            @Override
-            public ApplicationModel getCreatedApplication() {
-                return app;
-            }
-
-            @Override
-            public ClientModel getCreatedClient() {
-                return app;
-            }
-        });
-
-        allApps.put(id, app);
-
-        return app;
-    }
-
-    @Override
-    public boolean removeApplication(String id) {
-        ApplicationModel appToBeRemoved = this.getApplicationById(id);
-        if (appToBeRemoved == null) return false;
-
-        // remove any composite role assignments for this app
-        for (RoleModel role : this.getRoles()) {
-            RoleAdapter roleAdapter = (RoleAdapter)role;
-            roleAdapter.removeApplicationComposites(id);
-        }
-
-        for (RoleModel role : appToBeRemoved.getRoles()) {
-            appToBeRemoved.removeRole(role);
-        }
-
-        return (allApps.remove(id) != null);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String name) {
-        return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String id, String name) {
-        if (id == null) throw new NullPointerException("id == null");
-        if (name == null) throw new NullPointerException("name == null");
-        if (hasOAuthClientWithName(name)) throw new ModelDuplicateException("OAuth Client with name " + name + " already exists.");
-        OAuthClientEntity oauthClient = new OAuthClientEntity();
-        oauthClient.setId(id);
-        oauthClient.setRealmId(getId());
-        oauthClient.setName(name);
-
-        OAuthClientAdapter oAuthClient = new OAuthClientAdapter(session, this, oauthClient);
-        allOAuthClients.put(id, oAuthClient);
-
-        return oAuthClient;
-    }
-
-    boolean hasOAuthClientWithName(String name) {
-        for (OAuthClientAdapter oaClient : allOAuthClients.values()) {
-            if (oaClient.getName().equals(name)) return true;
-        }
-
-        return false;
-    }
-
-    boolean hasOAuthClientWithClientId(String id) {
-        for (OAuthClientAdapter oaClient : allOAuthClients.values()) {
-            if (oaClient.getClientId().equals(id)) return true;
-        }
-
-        return false;
-    }
-
-    boolean hasUserWithEmail(String email) {
-        for (UserModel user : inMemoryModel.getUsers(getId())) {
-            if (user.getEmail() == null) continue;
-            if (user.getEmail().equals(email)) return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean removeOAuthClient(String id) {
-        return allOAuthClients.remove(id) != null;
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClient(String name) {
-        for (OAuthClientAdapter oAuthClient : allOAuthClients.values()) {
-            if (oAuthClient.getName().equals(name)) return oAuthClient;
-        }
-
-        return null;
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id) {
-        for (OAuthClientAdapter oAuthClient : allOAuthClients.values()) {
-            if (oAuthClient.getId().equals(id)) return oAuthClient;
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<OAuthClientModel> getOAuthClients() {
-        return new ArrayList(allOAuthClients.values());
-    }
-
-    @Override
-    public void addRequiredCredential(String type) {
-        RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
-        addRequiredCredential(credentialModel, realm.getRequiredCredentials());
-    }
-
-    protected void addRequiredCredential(RequiredCredentialModel credentialModel, List<RequiredCredentialEntity> persistentCollection) {
-        RequiredCredentialEntity credEntity = new RequiredCredentialEntity();
-        credEntity.setType(credentialModel.getType());
-        credEntity.setFormLabel(credentialModel.getFormLabel());
-        credEntity.setInput(credentialModel.isInput());
-        credEntity.setSecret(credentialModel.isSecret());
-
-        persistentCollection.add(credEntity);
-    }
-
-    @Override
-    public void updateRequiredCredentials(Set<String> creds) {
-        updateRequiredCredentials(creds, realm.getRequiredCredentials());
-    }
-
-    protected void updateRequiredCredentials(Set<String> creds, List<RequiredCredentialEntity> credsEntities) {
-        Set<String> already = new HashSet<String>();
-        Set<RequiredCredentialEntity> toRemove = new HashSet<RequiredCredentialEntity>();
-        for (RequiredCredentialEntity entity : credsEntities) {
-            if (!creds.contains(entity.getType())) {
-                toRemove.add(entity);
-            } else {
-                already.add(entity.getType());
-            }
-        }
-        for (RequiredCredentialEntity entity : toRemove) {
-            credsEntities.remove(entity);
-        }
-        for (String cred : creds) {
-            if (!already.contains(cred)) {
-                RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred);
-                addRequiredCredential(credentialModel, credsEntities);
-            }
-        }
-    }
-
-    @Override
-    public List<RequiredCredentialModel> getRequiredCredentials() {
-        return convertRequiredCredentialEntities(realm.getRequiredCredentials());
-    }
-
-    protected List<RequiredCredentialModel> convertRequiredCredentialEntities(Collection<RequiredCredentialEntity> credEntities) {
-
-        List<RequiredCredentialModel> result = new ArrayList<RequiredCredentialModel>();
-        for (RequiredCredentialEntity entity : credEntities) {
-            RequiredCredentialModel credentialModel = new RequiredCredentialModel();
-            credentialModel.setFormLabel(entity.getFormLabel());
-            credentialModel.setInput(entity.isInput());
-            credentialModel.setSecret(entity.isSecret());
-            credentialModel.setType(entity.getType());
-
-            result.add(credentialModel);
-        }
-        return result;
-    }
-
-    protected RequiredCredentialModel initRequiredCredentialModel(String type) {
-        RequiredCredentialModel credentialModel = RequiredCredentialModel.BUILT_IN.get(type);
-        if (credentialModel == null) {
-            throw new RuntimeException("Unknown credential type " + type);
-        }
-        return credentialModel;
-    }
-
-    @Override
-    public Map<String, String> getBrowserSecurityHeaders() {
-        return realm.getBrowserSecurityHeaders();
-    }
-
-    @Override
-    public void setBrowserSecurityHeaders(Map<String, String> headers) {
-        realm.setBrowserSecurityHeaders(headers);
-    }
-
-    @Override
-    public Map<String, String> getSmtpConfig() {
-        return realm.getSmtpConfig();
-    }
-
-    @Override
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        realm.setSmtpConfig(smtpConfig);
-    }
-
-    @Override
-    public List<IdentityProviderModel> getIdentityProviders() {
-        return new ArrayList(allIdProviders.values());
-    }
-
-    @Override
-    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
-        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
-            if (identityProviderModel.getId().equals(identityProviderId)) {
-                return identityProviderModel;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public void addIdentityProvider(IdentityProviderModel identityProvider) {
-        if (identityProvider.getId() == null) throw new NullPointerException("identityProvider.getId() == null");
-        if (identityProvider.getInternalId() == null) identityProvider.setInternalId(KeycloakModelUtils.generateId());
-        allIdProviders.put(identityProvider.getInternalId(), identityProvider);
-    }
-
-    @Override
-    public void removeIdentityProviderById(String providerId) {
-        for (IdentityProviderModel provider : getIdentityProviders()) {
-            if (provider.getId().equals(providerId)) {
-                allIdProviders.remove(provider.getInternalId());
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
-        removeIdentityProviderById(identityProvider.getId());
-        addIdentityProvider(identityProvider);
-    }
-
-    @Override
-    public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
-        UserFederationProviderEntity entity = new UserFederationProviderEntity();
-        entity.setId(KeycloakModelUtils.generateId());
-        entity.setPriority(priority);
-        entity.setProviderName(providerName);
-        entity.setConfig(config);
-        if (displayName == null) {
-            displayName = entity.getId();
-        }
-        entity.setDisplayName(displayName);
-        entity.setFullSyncPeriod(fullSyncPeriod);
-        entity.setChangedSyncPeriod(changedSyncPeriod);
-        entity.setLastSync(lastSync);
-        realm.getUserFederationProviders().add(entity);
-
-        return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
-    }
-
-    @Override
-    public void removeUserFederationProvider(UserFederationProviderModel provider) {
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            if (entity.getId().equals(provider.getId())) {
-                session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
-                        entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-                it.remove();
-            }
-        }
-    }
-
-    @Override
-    public void updateUserFederationProvider(UserFederationProviderModel model) {
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            if (entity.getId().equals(model.getId())) {
-                entity.setProviderName(model.getProviderName());
-                entity.setConfig(model.getConfig());
-                entity.setPriority(model.getPriority());
-                String displayName = model.getDisplayName();
-                if (displayName != null) {
-                    entity.setDisplayName(model.getDisplayName());
-                }
-                entity.setFullSyncPeriod(model.getFullSyncPeriod());
-                entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-                entity.setLastSync(model.getLastSync());
-            }
-        }
-    }
-
-    @Override
-    public List<UserFederationProviderModel> getUserFederationProviders() {
-        List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();
-        List<UserFederationProviderEntity> copy = new LinkedList<UserFederationProviderEntity>();
-        for (UserFederationProviderEntity entity : entities) {
-            copy.add(entity);
-
-        }
-        Collections.sort(copy, new Comparator<UserFederationProviderEntity>() {
-
-            @Override
-            public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) {
-                return o1.getPriority() - o2.getPriority();
-            }
-
-        });
-        List<UserFederationProviderModel> result = new LinkedList<UserFederationProviderModel>();
-        for (UserFederationProviderEntity entity : copy) {
-            result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
-                    entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-        }
-
-        return result;
-    }
-
-    @Override
-    public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
-        List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
-        for (UserFederationProviderModel model : providers) {
-            UserFederationProviderEntity entity = new UserFederationProviderEntity();
-            if (model.getId() != null) entity.setId(model.getId());
-            else entity.setId(KeycloakModelUtils.generateId());
-            entity.setProviderName(model.getProviderName());
-            entity.setConfig(model.getConfig());
-            entity.setPriority(model.getPriority());
-            String displayName = model.getDisplayName();
-            if (displayName == null) {
-                entity.setDisplayName(entity.getId());
-            }
-            entity.setDisplayName(displayName);
-            entity.setFullSyncPeriod(model.getFullSyncPeriod());
-            entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-            entity.setLastSync(model.getLastSync());
-            entities.add(entity);
-        }
-
-        realm.setUserFederationProviders(entities);
-    }
-
-    @Override
-    public boolean isEventsEnabled() {
-        return realm.isEventsEnabled();
-    }
-
-    @Override
-    public void setEventsEnabled(boolean enabled) {
-        realm.setEventsEnabled(enabled);
-    }
-
-    @Override
-    public long getEventsExpiration() {
-        return realm.getEventsExpiration();
-    }
-
-    @Override
-    public void setEventsExpiration(long expiration) {
-        realm.setEventsExpiration(expiration);
-    }
-
-    @Override
-    public Set<String> getEventsListeners() {
-        return new HashSet<String>(realm.getEventsListeners());
-    }
-
-    @Override
-    public void setEventsListeners(Set<String> listeners) {
-        if (listeners != null) {
-            realm.setEventsListeners(new ArrayList<String>(listeners));
-        } else {
-            realm.setEventsListeners(Collections.EMPTY_LIST);
-        }
-    }
-
-    @Override
-    public ApplicationModel getMasterAdminApp() {
-        return this.masterAdminApp;
-    }
-
-    @Override
-    public void setMasterAdminApp(ApplicationModel app) {
-        if (app == null) {
-            realm.setAdminAppId(null);
-            this.masterAdminApp = null;
-        } else {
-            String appId = app.getId();
-            if (appId == null) {
-                throw new IllegalStateException("Master Admin app not initialized.");
-            }
-            realm.setAdminAppId(appId);
-            this.masterAdminApp = app;
-        }
-    }
-
-    @Override
-    public boolean isIdentityFederationEnabled() {
-        //TODO: not sure if we will support identity federation storage for file
-        return getIdentityProviders() != null && !getIdentityProviders().isEmpty();
-    }
-
-    @Override
-    public int getAccessCodeLifespanLogin() {
-        return realm.getAccessCodeLifespanLogin();
-    }
-
-    @Override
-    public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
-        realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || !(o instanceof RealmModel)) return false;
-
-        RealmModel that = (RealmModel) o;
-        return that.getId().equals(getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return getId().hashCode();
-    }
+	private final InMemoryModel inMemoryModel;
+	private final RealmEntity realm;
+
+	protected volatile transient PublicKey publicKey;
+	protected volatile transient PrivateKey privateKey;
+	protected volatile transient X509Certificate certificate;
+	protected volatile transient Key codeSecretKey;
+
+	private volatile transient PasswordPolicy passwordPolicy;
+	private volatile transient KeycloakSession session;
+
+	private final Map<String, ApplicationModel> allApps = new HashMap<String, ApplicationModel>();
+	private ApplicationModel masterAdminApp = null;
+	private final Map<String, RoleAdapter> allRoles = new HashMap<String, RoleAdapter>();
+	private final Map<String, OAuthClientAdapter> allOAuthClients = new HashMap<String, OAuthClientAdapter>();
+	private final Map<String, IdentityProviderModel> allIdProviders = new HashMap<String, IdentityProviderModel>();
+
+	public RealmAdapter(KeycloakSession session, RealmEntity realm, InMemoryModel inMemoryModel) {
+		this.session = session;
+		this.realm = realm;
+		this.inMemoryModel = inMemoryModel;
+	}
+
+	public RealmEntity getRealmEnity() {
+		return realm;
+	}
+
+	@Override
+	public String getId() {
+		return realm.getId();
+	}
+
+	@Override
+	public String getName() {
+		return realm.getName();
+	}
+
+	@Override
+	public void setName(String name) {
+		if (getName() == null) {
+			realm.setName(name);
+			return;
+		}
+
+		if (getName().equals(name))
+			return; // allow setting name to same value
+
+		if (inMemoryModel.getRealmByName(name) != null)
+			throw new ModelDuplicateException("Realm " + name + " already exists.");
+		realm.setName(name);
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return realm.isEnabled();
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		realm.setEnabled(enabled);
+	}
+
+	@Override
+	public SslRequired getSslRequired() {
+		return SslRequired.valueOf(realm.getSslRequired());
+	}
+
+	@Override
+	public void setSslRequired(SslRequired sslRequired) {
+		realm.setSslRequired(sslRequired.name());
+	}
+
+	@Override
+	public boolean isPasswordCredentialGrantAllowed() {
+		return realm.isPasswordCredentialGrantAllowed();
+	}
+
+	@Override
+	public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
+		realm.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
+	}
+
+	@Override
+	public boolean isRegistrationAllowed() {
+		return realm.isRegistrationAllowed();
+	}
+
+	@Override
+	public void setRegistrationAllowed(boolean registrationAllowed) {
+		realm.setRegistrationAllowed(registrationAllowed);
+	}
+
+	@Override
+	public boolean isRegistrationEmailAsUsername() {
+		return realm.isRegistrationEmailAsUsername();
+	}
+
+	@Override
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		realm.setRegistrationEmailAsUsername(registrationEmailAsUsername);
+	}
+
+	@Override
+	public boolean isRememberMe() {
+		return realm.isRememberMe();
+	}
+
+	@Override
+	public void setRememberMe(boolean rememberMe) {
+		realm.setRememberMe(rememberMe);
+	}
+
+	@Override
+	public boolean isBruteForceProtected() {
+		return realm.isBruteForceProtected();
+	}
+
+	@Override
+	public void setBruteForceProtected(boolean value) {
+		realm.setBruteForceProtected(value);
+	}
+
+	@Override
+	public int getMaxFailureWaitSeconds() {
+		return realm.getMaxFailureWaitSeconds();
+	}
+
+	@Override
+	public void setMaxFailureWaitSeconds(int val) {
+		realm.setMaxFailureWaitSeconds(val);
+	}
+
+	@Override
+	public int getWaitIncrementSeconds() {
+		return realm.getWaitIncrementSeconds();
+	}
+
+	@Override
+	public void setWaitIncrementSeconds(int val) {
+		realm.setWaitIncrementSeconds(val);
+	}
+
+	@Override
+	public long getQuickLoginCheckMilliSeconds() {
+		return realm.getQuickLoginCheckMilliSeconds();
+	}
+
+	@Override
+	public void setQuickLoginCheckMilliSeconds(long val) {
+		realm.setQuickLoginCheckMilliSeconds(val);
+	}
+
+	@Override
+	public int getMinimumQuickLoginWaitSeconds() {
+		return realm.getMinimumQuickLoginWaitSeconds();
+	}
+
+	@Override
+	public void setMinimumQuickLoginWaitSeconds(int val) {
+		realm.setMinimumQuickLoginWaitSeconds(val);
+	}
+
+	@Override
+	public int getMaxDeltaTimeSeconds() {
+		return realm.getMaxDeltaTimeSeconds();
+	}
+
+	@Override
+	public void setMaxDeltaTimeSeconds(int val) {
+		realm.setMaxDeltaTimeSeconds(val);
+	}
+
+	@Override
+	public int getFailureFactor() {
+		return realm.getFailureFactor();
+	}
+
+	@Override
+	public void setFailureFactor(int failureFactor) {
+		realm.setFailureFactor(failureFactor);
+	}
+
+	@Override
+	public boolean isVerifyEmail() {
+		return realm.isVerifyEmail();
+	}
+
+	@Override
+	public void setVerifyEmail(boolean verifyEmail) {
+		realm.setVerifyEmail(verifyEmail);
+	}
+
+	@Override
+	public boolean isResetPasswordAllowed() {
+		return realm.isResetPasswordAllowed();
+	}
+
+	@Override
+	public void setResetPasswordAllowed(boolean resetPassword) {
+		realm.setResetPasswordAllowed(resetPassword);
+	}
+
+	@Override
+	public PasswordPolicy getPasswordPolicy() {
+		if (passwordPolicy == null) {
+			passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
+		}
+		return passwordPolicy;
+	}
+
+	@Override
+	public void setPasswordPolicy(PasswordPolicy policy) {
+		this.passwordPolicy = policy;
+		realm.setPasswordPolicy(policy.toString());
+	}
+
+	@Override
+	public int getNotBefore() {
+		return realm.getNotBefore();
+	}
+
+	@Override
+	public void setNotBefore(int notBefore) {
+		realm.setNotBefore(notBefore);
+	}
+
+	@Override
+	public int getSsoSessionIdleTimeout() {
+		return realm.getSsoSessionIdleTimeout();
+	}
+
+	@Override
+	public void setSsoSessionIdleTimeout(int seconds) {
+		realm.setSsoSessionIdleTimeout(seconds);
+	}
+
+	@Override
+	public int getSsoSessionMaxLifespan() {
+		return realm.getSsoSessionMaxLifespan();
+	}
+
+	@Override
+	public void setSsoSessionMaxLifespan(int seconds) {
+		realm.setSsoSessionMaxLifespan(seconds);
+	}
+
+	@Override
+	public int getAccessTokenLifespan() {
+		return realm.getAccessTokenLifespan();
+	}
+
+	@Override
+	public void setAccessTokenLifespan(int tokenLifespan) {
+		realm.setAccessTokenLifespan(tokenLifespan);
+	}
+
+	@Override
+	public int getAccessCodeLifespan() {
+		return realm.getAccessCodeLifespan();
+	}
+
+	@Override
+	public void setAccessCodeLifespan(int accessCodeLifespan) {
+		realm.setAccessCodeLifespan(accessCodeLifespan);
+	}
+
+	@Override
+	public int getAccessCodeLifespanUserAction() {
+		return realm.getAccessCodeLifespanUserAction();
+	}
+
+	@Override
+	public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+		realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
+	}
+
+	@Override
+	public String getPublicKeyPem() {
+		return realm.getPublicKeyPem();
+	}
+
+	@Override
+	public void setPublicKeyPem(String publicKeyPem) {
+		realm.setPublicKeyPem(publicKeyPem);
+		this.publicKey = null;
+	}
+
+	@Override
+	public X509Certificate getCertificate() {
+		if (certificate != null)
+			return certificate;
+		certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
+		return certificate;
+	}
+
+	@Override
+	public void setCertificate(X509Certificate certificate) {
+		this.certificate = certificate;
+		String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
+		setCertificatePem(certificatePem);
+	}
+
+	@Override
+	public String getCertificatePem() {
+		return realm.getCertificatePem();
+	}
+
+	@Override
+	public void setCertificatePem(String certificate) {
+		realm.setCertificatePem(certificate);
+
+	}
+
+	@Override
+	public String getPrivateKeyPem() {
+		return realm.getPrivateKeyPem();
+	}
+
+	@Override
+	public void setPrivateKeyPem(String privateKeyPem) {
+		realm.setPrivateKeyPem(privateKeyPem);
+		this.privateKey = null;
+	}
+
+	@Override
+	public PublicKey getPublicKey() {
+		if (publicKey != null)
+			return publicKey;
+		publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
+		return publicKey;
+	}
+
+	@Override
+	public void setPublicKey(PublicKey publicKey) {
+		this.publicKey = publicKey;
+		String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
+		setPublicKeyPem(publicKeyPem);
+	}
+
+	@Override
+	public PrivateKey getPrivateKey() {
+		if (privateKey != null)
+			return privateKey;
+		privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
+		return privateKey;
+	}
+
+	@Override
+	public void setPrivateKey(PrivateKey privateKey) {
+		this.privateKey = privateKey;
+		String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
+		setPrivateKeyPem(privateKeyPem);
+	}
+
+	@Override
+	public String getCodeSecret() {
+		return realm.getCodeSecret();
+	}
+
+	@Override
+	public Key getCodeSecretKey() {
+		if (codeSecretKey == null) {
+			codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
+		}
+		return codeSecretKey;
+	}
+
+	@Override
+	public void setCodeSecret(String codeSecret) {
+		realm.setCodeSecret(codeSecret);
+	}
+
+	@Override
+	public String getLoginTheme() {
+		return realm.getLoginTheme();
+	}
+
+	@Override
+	public void setLoginTheme(String name) {
+		realm.setLoginTheme(name);
+	}
+
+	@Override
+	public String getAccountTheme() {
+		return realm.getAccountTheme();
+	}
+
+	@Override
+	public void setAccountTheme(String name) {
+		realm.setAccountTheme(name);
+	}
+
+	@Override
+	public String getAdminTheme() {
+		return realm.getAdminTheme();
+	}
+
+	@Override
+	public void setAdminTheme(String name) {
+		realm.setAdminTheme(name);
+	}
+
+	@Override
+	public String getEmailTheme() {
+		return realm.getEmailTheme();
+	}
+
+	@Override
+	public void setEmailTheme(String name) {
+		realm.setEmailTheme(name);
+	}
+
+	@Override
+	public RoleAdapter getRole(String name) {
+		for (RoleAdapter role : allRoles.values()) {
+			if (role.getName().equals(name))
+				return role;
+		}
+		return null;
+	}
+
+	@Override
+	public RoleModel addRole(String name) {
+		return this.addRole(KeycloakModelUtils.generateId(), name);
+	}
+
+	@Override
+	public RoleModel addRole(String id, String name) {
+		if (id == null)
+			throw new NullPointerException("id == null");
+		if (name == null)
+			throw new NullPointerException("name == null");
+		if (hasRoleWithName(name))
+			throw new ModelDuplicateException("Realm already contains role with name " + name + ".");
+
+		RoleEntity roleEntity = new RoleEntity();
+		roleEntity.setId(id);
+		roleEntity.setName(name);
+		roleEntity.setRealmId(getId());
+
+		RoleAdapter roleModel = new RoleAdapter(this, roleEntity, this);
+		allRoles.put(id, roleModel);
+		return roleModel;
+	}
+
+	@Override
+	public boolean removeRole(RoleModel role) {
+		return removeRoleById(role.getId());
+	}
+
+	@Override
+	public boolean removeRoleById(String id) {
+		if (id == null)
+			throw new NullPointerException("id == null");
+
+		// try realm roles first
+		if (allRoles.remove(id) != null)
+			return true;
+
+		for (ApplicationModel app : getApplications()) {
+			for (RoleModel appRole : app.getRoles()) {
+				if (id.equals(appRole.getId())) {
+					app.removeRole(appRole);
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	@Override
+	public Set<RoleModel> getRoles() {
+		return new HashSet<RoleModel>(allRoles.values());
+	}
+
+	@Override
+	public RoleModel getRoleById(String id) {
+		RoleModel found = allRoles.get(id);
+		if (found != null)
+			return found;
+
+		for (ApplicationModel app : getApplications()) {
+			for (RoleModel appRole : app.getRoles()) {
+				if (appRole.getId().equals(id))
+					return appRole;
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public List<String> getDefaultRoles() {
+		return realm.getDefaultRoles();
+	}
+
+	@Override
+	public void addDefaultRole(String name) {
+		RoleModel role = getRole(name);
+		if (role == null) {
+			addRole(name);
+		}
+
+		List<String> roleNames = getDefaultRoles();
+		if (roleNames.contains(name))
+			throw new IllegalArgumentException("Realm " + realm.getName() + " already contains default role named " + name);
+
+		roleNames.add(name);
+		realm.setDefaultRoles(roleNames);
+	}
+
+	boolean hasRoleWithName(String name) {
+		for (RoleModel role : allRoles.values()) {
+			if (role.getName().equals(name))
+				return true;
+		}
+
+		return false;
+	}
+
+	@Override
+	public void updateDefaultRoles(String[] defaultRoles) {
+		List<String> roleNames = new ArrayList<String>();
+		for (String roleName : defaultRoles) {
+			RoleModel role = getRole(roleName);
+			if (role == null) {
+				addRole(roleName);
+			}
+
+			roleNames.add(roleName);
+		}
+
+		realm.setDefaultRoles(roleNames);
+	}
+
+	@Override
+	public ClientModel findClient(String clientId) {
+		ClientModel model = getApplicationByName(clientId);
+		if (model != null)
+			return model;
+		return getOAuthClient(clientId);
+	}
+
+	@Override
+	public ClientModel findClientById(String id) {
+		ClientModel clientModel = getApplicationById(id);
+		if (clientModel != null)
+			return clientModel;
+		return getOAuthClientById(id);
+	}
+
+	@Override
+	public ApplicationModel getApplicationById(String id) {
+		return allApps.get(id);
+	}
+
+	@Override
+	public ApplicationModel getApplicationByName(String name) {
+		for (ApplicationModel app : getApplications()) {
+			if (app.getName().equals(name))
+				return app;
+		}
+
+		return null;
+	}
+
+	@Override
+	public Map<String, ApplicationModel> getApplicationNameMap() {
+		Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
+		for (ApplicationModel resource : getApplications()) {
+			resourceMap.put(resource.getName(), resource);
+		}
+		return resourceMap;
+	}
+
+	@Override
+	public List<ApplicationModel> getApplications() {
+		return new ArrayList<ApplicationModel>(allApps.values());
+	}
+
+	@Override
+	public ApplicationModel addApplication(String name) {
+		return this.addApplication(KeycloakModelUtils.generateId(), name);
+	}
+
+	@Override
+	public ApplicationModel addApplication(String id, String name) {
+		if (name == null)
+			throw new NullPointerException("name == null");
+		if (id == null)
+			throw new NullPointerException("id == null");
+
+		if (getApplicationNameMap().containsKey(name)) {
+			throw new ModelDuplicateException("Application named '" + name + "' already exists.");
+		}
+
+		ApplicationEntity appEntity = new ApplicationEntity();
+		appEntity.setId(id);
+		appEntity.setName(name);
+		appEntity.setRealmId(getId());
+		appEntity.setEnabled(true);
+
+		ClientEntity clientEntity = new ClientEntity();
+		clientEntity.setId(id);
+		clientEntity.setName(name);
+		clientEntity.setRealmId(getId());
+		clientEntity.setEnabled(true);
+
+		final ApplicationModel app = new ApplicationAdapter(session, this, appEntity, clientEntity, inMemoryModel);
+		session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
+			@Override
+			public ApplicationModel getCreatedApplication() {
+				return app;
+			}
+
+			@Override
+			public ClientModel getCreatedClient() {
+				return app;
+			}
+		});
+
+		allApps.put(id, app);
+
+		return app;
+	}
+
+	@Override
+	public boolean removeApplication(String id) {
+		ApplicationModel appToBeRemoved = this.getApplicationById(id);
+		if (appToBeRemoved == null)
+			return false;
+
+		// remove any composite role assignments for this app
+		for (RoleModel role : this.getRoles()) {
+			RoleAdapter roleAdapter = (RoleAdapter) role;
+			roleAdapter.removeApplicationComposites(id);
+		}
+
+		for (RoleModel role : appToBeRemoved.getRoles()) {
+			appToBeRemoved.removeRole(role);
+		}
+
+		return (allApps.remove(id) != null);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String name) {
+		return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String id, String name) {
+		if (id == null)
+			throw new NullPointerException("id == null");
+		if (name == null)
+			throw new NullPointerException("name == null");
+		if (hasOAuthClientWithName(name))
+			throw new ModelDuplicateException("OAuth Client with name " + name + " already exists.");
+		OAuthClientEntity oauthClient = new OAuthClientEntity();
+		oauthClient.setId(id);
+		oauthClient.setRealmId(getId());
+		oauthClient.setName(name);
+
+		OAuthClientAdapter oAuthClient = new OAuthClientAdapter(session, this, oauthClient);
+		allOAuthClients.put(id, oAuthClient);
+
+		return oAuthClient;
+	}
+
+	boolean hasOAuthClientWithName(String name) {
+		for (OAuthClientAdapter oaClient : allOAuthClients.values()) {
+			if (oaClient.getName().equals(name))
+				return true;
+		}
+
+		return false;
+	}
+
+	boolean hasOAuthClientWithClientId(String id) {
+		for (OAuthClientAdapter oaClient : allOAuthClients.values()) {
+			if (oaClient.getClientId().equals(id))
+				return true;
+		}
+
+		return false;
+	}
+
+	boolean hasUserWithEmail(String email) {
+		for (UserModel user : inMemoryModel.getUsers(getId())) {
+			if (user.getEmail() == null)
+				continue;
+			if (user.getEmail().equals(email))
+				return true;
+		}
+
+		return false;
+	}
+
+	@Override
+	public boolean removeOAuthClient(String id) {
+		return allOAuthClients.remove(id) != null;
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClient(String name) {
+		for (OAuthClientAdapter oAuthClient : allOAuthClients.values()) {
+			if (oAuthClient.getName().equals(name))
+				return oAuthClient;
+		}
+
+		return null;
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClientById(String id) {
+		for (OAuthClientAdapter oAuthClient : allOAuthClients.values()) {
+			if (oAuthClient.getId().equals(id))
+				return oAuthClient;
+		}
+
+		return null;
+	}
+
+	@Override
+	public List<OAuthClientModel> getOAuthClients() {
+		return new ArrayList<OAuthClientModel>(allOAuthClients.values());
+	}
+
+	@Override
+	public void addRequiredCredential(String type) {
+		RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
+		addRequiredCredential(credentialModel, realm.getRequiredCredentials());
+	}
+
+	protected void addRequiredCredential(RequiredCredentialModel credentialModel,
+			List<RequiredCredentialEntity> persistentCollection) {
+		RequiredCredentialEntity credEntity = new RequiredCredentialEntity();
+		credEntity.setType(credentialModel.getType());
+		credEntity.setFormLabel(credentialModel.getFormLabel());
+		credEntity.setInput(credentialModel.isInput());
+		credEntity.setSecret(credentialModel.isSecret());
+
+		persistentCollection.add(credEntity);
+	}
+
+	@Override
+	public void updateRequiredCredentials(Set<String> creds) {
+		updateRequiredCredentials(creds, realm.getRequiredCredentials());
+	}
+
+	protected void updateRequiredCredentials(Set<String> creds, List<RequiredCredentialEntity> credsEntities) {
+		Set<String> already = new HashSet<String>();
+		Set<RequiredCredentialEntity> toRemove = new HashSet<RequiredCredentialEntity>();
+		for (RequiredCredentialEntity entity : credsEntities) {
+			if (!creds.contains(entity.getType())) {
+				toRemove.add(entity);
+			} else {
+				already.add(entity.getType());
+			}
+		}
+		for (RequiredCredentialEntity entity : toRemove) {
+			credsEntities.remove(entity);
+		}
+		for (String cred : creds) {
+			if (!already.contains(cred)) {
+				RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred);
+				addRequiredCredential(credentialModel, credsEntities);
+			}
+		}
+	}
+
+	@Override
+	public List<RequiredCredentialModel> getRequiredCredentials() {
+		return convertRequiredCredentialEntities(realm.getRequiredCredentials());
+	}
+
+	protected List<RequiredCredentialModel> convertRequiredCredentialEntities(
+			Collection<RequiredCredentialEntity> credEntities) {
+
+		List<RequiredCredentialModel> result = new ArrayList<RequiredCredentialModel>();
+		for (RequiredCredentialEntity entity : credEntities) {
+			RequiredCredentialModel credentialModel = new RequiredCredentialModel();
+			credentialModel.setFormLabel(entity.getFormLabel());
+			credentialModel.setInput(entity.isInput());
+			credentialModel.setSecret(entity.isSecret());
+			credentialModel.setType(entity.getType());
+
+			result.add(credentialModel);
+		}
+		return result;
+	}
+
+	protected RequiredCredentialModel initRequiredCredentialModel(String type) {
+		RequiredCredentialModel credentialModel = RequiredCredentialModel.BUILT_IN.get(type);
+		if (credentialModel == null) {
+			throw new RuntimeException("Unknown credential type " + type);
+		}
+		return credentialModel;
+	}
+
+	@Override
+	public Map<String, String> getBrowserSecurityHeaders() {
+		return realm.getBrowserSecurityHeaders();
+	}
+
+	@Override
+	public void setBrowserSecurityHeaders(Map<String, String> headers) {
+		realm.setBrowserSecurityHeaders(headers);
+	}
+
+	@Override
+	public Map<String, String> getSmtpConfig() {
+		return realm.getSmtpConfig();
+	}
+
+	@Override
+	public void setSmtpConfig(Map<String, String> smtpConfig) {
+		realm.setSmtpConfig(smtpConfig);
+	}
+
+	@Override
+	public List<IdentityProviderModel> getIdentityProviders() {
+		return new ArrayList<IdentityProviderModel>(allIdProviders.values());
+	}
+
+	@Override
+	public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+		for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+			if (identityProviderModel.getId().equals(identityProviderId)) {
+				return identityProviderModel;
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public void addIdentityProvider(IdentityProviderModel identityProvider) {
+		if (identityProvider.getId() == null)
+			throw new NullPointerException("identityProvider.getId() == null");
+		if (identityProvider.getInternalId() == null)
+			identityProvider.setInternalId(KeycloakModelUtils.generateId());
+		allIdProviders.put(identityProvider.getInternalId(), identityProvider);
+	}
+
+	@Override
+	public void removeIdentityProviderById(String providerId) {
+		for (IdentityProviderModel provider : getIdentityProviders()) {
+			if (provider.getId().equals(providerId)) {
+				allIdProviders.remove(provider.getInternalId());
+				break;
+			}
+		}
+	}
+
+	@Override
+	public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+		removeIdentityProviderById(identityProvider.getId());
+		addIdentityProvider(identityProvider);
+	}
+
+	@Override
+	public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config,
+			int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
+		UserFederationProviderEntity entity = new UserFederationProviderEntity();
+		entity.setId(KeycloakModelUtils.generateId());
+		entity.setPriority(priority);
+		entity.setProviderName(providerName);
+		entity.setConfig(config);
+		if (displayName == null) {
+			displayName = entity.getId();
+		}
+		entity.setDisplayName(displayName);
+		entity.setFullSyncPeriod(fullSyncPeriod);
+		entity.setChangedSyncPeriod(changedSyncPeriod);
+		entity.setLastSync(lastSync);
+		realm.getUserFederationProviders().add(entity);
+
+		return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod,
+				changedSyncPeriod, lastSync);
+	}
+
+	@Override
+	public void removeUserFederationProvider(UserFederationProviderModel provider) {
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			if (entity.getId().equals(provider.getId())) {
+				session.users().preRemove(
+						this,
+						new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity
+								.getPriority(), entity.getDisplayName(), entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(),
+								entity.getLastSync()));
+				it.remove();
+			}
+		}
+	}
+
+	@Override
+	public void updateUserFederationProvider(UserFederationProviderModel model) {
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			if (entity.getId().equals(model.getId())) {
+				entity.setProviderName(model.getProviderName());
+				entity.setConfig(model.getConfig());
+				entity.setPriority(model.getPriority());
+				String displayName = model.getDisplayName();
+				if (displayName != null) {
+					entity.setDisplayName(model.getDisplayName());
+				}
+				entity.setFullSyncPeriod(model.getFullSyncPeriod());
+				entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+				entity.setLastSync(model.getLastSync());
+			}
+		}
+	}
+
+	@Override
+	public List<UserFederationProviderModel> getUserFederationProviders() {
+		List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();
+		List<UserFederationProviderEntity> copy = new LinkedList<UserFederationProviderEntity>();
+		for (UserFederationProviderEntity entity : entities) {
+			copy.add(entity);
+
+		}
+		Collections.sort(copy, new Comparator<UserFederationProviderEntity>() {
+
+			@Override
+			public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) {
+				return o1.getPriority() - o2.getPriority();
+			}
+
+		});
+		List<UserFederationProviderModel> result = new LinkedList<UserFederationProviderModel>();
+		for (UserFederationProviderEntity entity : copy) {
+			result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity
+					.getPriority(), entity.getDisplayName(), entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity
+					.getLastSync()));
+		}
+
+		return result;
+	}
+
+	@Override
+	public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
+		List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
+		for (UserFederationProviderModel model : providers) {
+			UserFederationProviderEntity entity = new UserFederationProviderEntity();
+			if (model.getId() != null)
+				entity.setId(model.getId());
+			else
+				entity.setId(KeycloakModelUtils.generateId());
+			entity.setProviderName(model.getProviderName());
+			entity.setConfig(model.getConfig());
+			entity.setPriority(model.getPriority());
+			String displayName = model.getDisplayName();
+			if (displayName == null) {
+				entity.setDisplayName(entity.getId());
+			}
+			entity.setDisplayName(displayName);
+			entity.setFullSyncPeriod(model.getFullSyncPeriod());
+			entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+			entity.setLastSync(model.getLastSync());
+			entities.add(entity);
+		}
+
+		realm.setUserFederationProviders(entities);
+	}
+
+	@Override
+	public boolean isEventsEnabled() {
+		return realm.isEventsEnabled();
+	}
+
+	@Override
+	public void setEventsEnabled(boolean enabled) {
+		realm.setEventsEnabled(enabled);
+	}
+
+	@Override
+	public long getEventsExpiration() {
+		return realm.getEventsExpiration();
+	}
+
+	@Override
+	public void setEventsExpiration(long expiration) {
+		realm.setEventsExpiration(expiration);
+	}
+
+	@Override
+	public Set<String> getEventsListeners() {
+		return new HashSet<String>(realm.getEventsListeners());
+	}
+
+	@Override
+	public void setEventsListeners(Set<String> listeners) {
+		if (listeners != null) {
+			realm.setEventsListeners(new ArrayList<String>(listeners));
+		} else {
+			realm.setEventsListeners(Collections.EMPTY_LIST);
+		}
+	}
+
+	@Override
+	public ApplicationModel getMasterAdminApp() {
+		return this.masterAdminApp;
+	}
+
+	@Override
+	public void setMasterAdminApp(ApplicationModel app) {
+		if (app == null) {
+			realm.setAdminAppId(null);
+			this.masterAdminApp = null;
+		} else {
+			String appId = app.getId();
+			if (appId == null) {
+				throw new IllegalStateException("Master Admin app not initialized.");
+			}
+			realm.setAdminAppId(appId);
+			this.masterAdminApp = app;
+		}
+	}
+
+	@Override
+	public boolean isIdentityFederationEnabled() {
+		// TODO: not sure if we will support identity federation storage for file
+		return getIdentityProviders() != null && !getIdentityProviders().isEmpty();
+	}
+
+	@Override
+	public int getAccessCodeLifespanLogin() {
+		return realm.getAccessCodeLifespanLogin();
+	}
+
+	@Override
+	public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
+		realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o == null || !(o instanceof RealmModel))
+			return false;
+
+		RealmModel that = (RealmModel) o;
+		return that.getId().equals(getId());
+	}
+
+	@Override
+	public int hashCode() {
+		return getId().hashCode();
+	}
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
index 8089e4e..2372746 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
@@ -1,12 +1,18 @@
 package org.keycloak.models.cache.entities;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RequiredCredentialModel;
@@ -14,337 +20,335 @@ import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.cache.RealmCache;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class CachedRealm {
 
-    private String id;
-    private String name;
-    private boolean enabled;
-    private SslRequired sslRequired;
-    private boolean registrationAllowed;
-    private boolean rememberMe;
-    private boolean verifyEmail;
-    private boolean passwordCredentialGrantAllowed;
-    private boolean resetPasswordAllowed;
-    private boolean identityFederationEnabled;
-    //--- brute force settings
-    private boolean bruteForceProtected;
-    private int maxFailureWaitSeconds;
-    private int minimumQuickLoginWaitSeconds;
-    private int waitIncrementSeconds;
-    private long quickLoginCheckMilliSeconds;
-    private int maxDeltaTimeSeconds;
-    private int failureFactor;
-    //--- end brute force settings
-
-    private int ssoSessionIdleTimeout;
-    private int ssoSessionMaxLifespan;
-    private int accessTokenLifespan;
-    private int accessCodeLifespan;
-    private int accessCodeLifespanUserAction;
-    private int accessCodeLifespanLogin;
-    private int notBefore;
-    private PasswordPolicy passwordPolicy;
-
-    private String publicKeyPem;
-    private String privateKeyPem;
-    private String certificatePem;
-    private String codeSecret;
-
-    private String loginTheme;
-    private String accountTheme;
-    private String adminTheme;
-    private String emailTheme;
-    private String masterAdminApp;
-
-    private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
-    private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
-    private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
-
-    private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
-    private Map<String, String> smtpConfig = new HashMap<String, String>();
-
-    private boolean eventsEnabled;
-    private long eventsExpiration;
-    private Set<String> eventsListeners = new HashSet<String>();
-    private List<String> defaultRoles = new LinkedList<String>();
-    private Map<String, String> realmRoles = new HashMap<String, String>();
-    private Map<String, String> applications = new HashMap<String, String>();
-    private Map<String, String> clients = new HashMap<String, String>();
-
-    public CachedRealm() {
-    }
-
-    public CachedRealm(RealmCache cache, RealmProvider delegate, RealmModel model) {
-        id = model.getId();
-        name = model.getName();
-        enabled = model.isEnabled();
-        sslRequired = model.getSslRequired();
-        registrationAllowed = model.isRegistrationAllowed();
-        rememberMe = model.isRememberMe();
-        verifyEmail = model.isVerifyEmail();
-        passwordCredentialGrantAllowed = model.isPasswordCredentialGrantAllowed();
-        resetPasswordAllowed = model.isResetPasswordAllowed();
-        identityFederationEnabled = model.isIdentityFederationEnabled();
-        //--- brute force settings
-        bruteForceProtected = model.isBruteForceProtected();
-        maxFailureWaitSeconds = model.getMaxFailureWaitSeconds();
-        minimumQuickLoginWaitSeconds = model.getMinimumQuickLoginWaitSeconds();
-        waitIncrementSeconds = model.getWaitIncrementSeconds();
-        quickLoginCheckMilliSeconds = model.getQuickLoginCheckMilliSeconds();
-        maxDeltaTimeSeconds = model.getMaxDeltaTimeSeconds();
-        failureFactor = model.getFailureFactor();
-        //--- end brute force settings
-
-        ssoSessionIdleTimeout = model.getSsoSessionIdleTimeout();
-        ssoSessionMaxLifespan = model.getSsoSessionMaxLifespan();
-        accessTokenLifespan = model.getAccessTokenLifespan();
-        accessCodeLifespan = model.getAccessCodeLifespan();
-        accessCodeLifespanUserAction = model.getAccessCodeLifespanUserAction();
-        accessCodeLifespanLogin = model.getAccessCodeLifespanLogin();
-        notBefore = model.getNotBefore();
-        passwordPolicy = model.getPasswordPolicy();
-
-        publicKeyPem = model.getPublicKeyPem();
-        privateKeyPem = model.getPrivateKeyPem();
-        certificatePem = model.getCertificatePem();
-        codeSecret = model.getCodeSecret();
-
-        loginTheme = model.getLoginTheme();
-        accountTheme = model.getAccountTheme();
-        adminTheme = model.getAdminTheme();
-        emailTheme = model.getEmailTheme();
-
-        requiredCredentials = model.getRequiredCredentials();
-        userFederationProviders = model.getUserFederationProviders();
-
-        this.identityProviders = new ArrayList<IdentityProviderModel>();
-
-        for (IdentityProviderModel identityProviderModel : model.getIdentityProviders()) {
-            this.identityProviders.add(new IdentityProviderModel(identityProviderModel));
-        }
-
-        smtpConfig.putAll(model.getSmtpConfig());
-        browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders());
-
-        eventsEnabled = model.isEventsEnabled();
-        eventsExpiration = model.getEventsExpiration();
-        eventsListeners.addAll(model.getEventsListeners());
-        defaultRoles.addAll(model.getDefaultRoles());
-        masterAdminApp = model.getMasterAdminApp().getId();
-
-        for (RoleModel role : model.getRoles()) {
-            realmRoles.put(role.getName(), role.getId());
-            CachedRole cachedRole = new CachedRealmRole(role, model);
-            cache.addCachedRole(cachedRole);
-        }
-
-        for (ApplicationModel app : model.getApplications()) {
-            applications.put(app.getName(), app.getId());
-            CachedApplication cachedApp = new CachedApplication(cache, delegate, model, app);
-            cache.addCachedApplication(cachedApp);
-        }
-
-        for (OAuthClientModel client : model.getOAuthClients()) {
-            clients.put(client.getClientId(), client.getId());
-            CachedOAuthClient cachedApp = new CachedOAuthClient(cache, delegate, model, client);
-            cache.addCachedOAuthClient(cachedApp);
-        }
-
-    }
-
-
-    public String getId() {
-        return id;
-    }
-
-    public String getMasterAdminApp() {
-        return masterAdminApp;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public List<String> getDefaultRoles() {
-        return defaultRoles;
-    }
-
-    public Map<String, String> getRealmRoles() {
-        return realmRoles;
-    }
-
-    public Map<String, String> getApplications() {
-        return applications;
-    }
-
-    public Map<String, String> getClients() {
-        return clients;
-    }
-
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public SslRequired getSslRequired() {
-        return sslRequired;
-    }
-
-    public boolean isRegistrationAllowed() {
-        return registrationAllowed;
-    }
-
-    public boolean isPasswordCredentialGrantAllowed() {
-        return passwordCredentialGrantAllowed;
-    }
-
-    public boolean isRememberMe() {
-        return this.rememberMe;
-    }
-
-    public boolean isBruteForceProtected() {
-        return bruteForceProtected;
-    }
-
-    public int getMaxFailureWaitSeconds() {
-        return this.maxFailureWaitSeconds;
-    }
+	private String id;
+	private String name;
+	private boolean enabled;
+	private SslRequired sslRequired;
+	private boolean registrationAllowed;
+	protected boolean registrationEmailAsUsername;
+	private boolean rememberMe;
+	private boolean verifyEmail;
+	private boolean passwordCredentialGrantAllowed;
+	private boolean resetPasswordAllowed;
+	private boolean identityFederationEnabled;
+	// --- brute force settings
+	private boolean bruteForceProtected;
+	private int maxFailureWaitSeconds;
+	private int minimumQuickLoginWaitSeconds;
+	private int waitIncrementSeconds;
+	private long quickLoginCheckMilliSeconds;
+	private int maxDeltaTimeSeconds;
+	private int failureFactor;
+	// --- end brute force settings
+
+	private int ssoSessionIdleTimeout;
+	private int ssoSessionMaxLifespan;
+	private int accessTokenLifespan;
+	private int accessCodeLifespan;
+	private int accessCodeLifespanUserAction;
+	private int accessCodeLifespanLogin;
+	private int notBefore;
+	private PasswordPolicy passwordPolicy;
+
+	private String publicKeyPem;
+	private String privateKeyPem;
+	private String certificatePem;
+	private String codeSecret;
+
+	private String loginTheme;
+	private String accountTheme;
+	private String adminTheme;
+	private String emailTheme;
+	private String masterAdminApp;
+
+	private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
+	private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
+	private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
+
+	private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
+	private Map<String, String> smtpConfig = new HashMap<String, String>();
+
+	private boolean eventsEnabled;
+	private long eventsExpiration;
+	private Set<String> eventsListeners = new HashSet<String>();
+	private List<String> defaultRoles = new LinkedList<String>();
+	private Map<String, String> realmRoles = new HashMap<String, String>();
+	private Map<String, String> applications = new HashMap<String, String>();
+	private Map<String, String> clients = new HashMap<String, String>();
+
+	public CachedRealm() {
+	}
+
+	public CachedRealm(RealmCache cache, RealmProvider delegate, RealmModel model) {
+		id = model.getId();
+		name = model.getName();
+		enabled = model.isEnabled();
+		sslRequired = model.getSslRequired();
+		registrationAllowed = model.isRegistrationAllowed();
+		registrationEmailAsUsername = model.isRegistrationEmailAsUsername();
+		rememberMe = model.isRememberMe();
+		verifyEmail = model.isVerifyEmail();
+		passwordCredentialGrantAllowed = model.isPasswordCredentialGrantAllowed();
+		resetPasswordAllowed = model.isResetPasswordAllowed();
+		identityFederationEnabled = model.isIdentityFederationEnabled();
+		// --- brute force settings
+		bruteForceProtected = model.isBruteForceProtected();
+		maxFailureWaitSeconds = model.getMaxFailureWaitSeconds();
+		minimumQuickLoginWaitSeconds = model.getMinimumQuickLoginWaitSeconds();
+		waitIncrementSeconds = model.getWaitIncrementSeconds();
+		quickLoginCheckMilliSeconds = model.getQuickLoginCheckMilliSeconds();
+		maxDeltaTimeSeconds = model.getMaxDeltaTimeSeconds();
+		failureFactor = model.getFailureFactor();
+		// --- end brute force settings
+
+		ssoSessionIdleTimeout = model.getSsoSessionIdleTimeout();
+		ssoSessionMaxLifespan = model.getSsoSessionMaxLifespan();
+		accessTokenLifespan = model.getAccessTokenLifespan();
+		accessCodeLifespan = model.getAccessCodeLifespan();
+		accessCodeLifespanUserAction = model.getAccessCodeLifespanUserAction();
+		accessCodeLifespanLogin = model.getAccessCodeLifespanLogin();
+		notBefore = model.getNotBefore();
+		passwordPolicy = model.getPasswordPolicy();
+
+		publicKeyPem = model.getPublicKeyPem();
+		privateKeyPem = model.getPrivateKeyPem();
+		certificatePem = model.getCertificatePem();
+		codeSecret = model.getCodeSecret();
+
+		loginTheme = model.getLoginTheme();
+		accountTheme = model.getAccountTheme();
+		adminTheme = model.getAdminTheme();
+		emailTheme = model.getEmailTheme();
+
+		requiredCredentials = model.getRequiredCredentials();
+		userFederationProviders = model.getUserFederationProviders();
+
+		this.identityProviders = new ArrayList<IdentityProviderModel>();
+
+		for (IdentityProviderModel identityProviderModel : model.getIdentityProviders()) {
+			this.identityProviders.add(new IdentityProviderModel(identityProviderModel));
+		}
+
+		smtpConfig.putAll(model.getSmtpConfig());
+		browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders());
+
+		eventsEnabled = model.isEventsEnabled();
+		eventsExpiration = model.getEventsExpiration();
+		eventsListeners.addAll(model.getEventsListeners());
+		defaultRoles.addAll(model.getDefaultRoles());
+		masterAdminApp = model.getMasterAdminApp().getId();
+
+		for (RoleModel role : model.getRoles()) {
+			realmRoles.put(role.getName(), role.getId());
+			CachedRole cachedRole = new CachedRealmRole(role, model);
+			cache.addCachedRole(cachedRole);
+		}
+
+		for (ApplicationModel app : model.getApplications()) {
+			applications.put(app.getName(), app.getId());
+			CachedApplication cachedApp = new CachedApplication(cache, delegate, model, app);
+			cache.addCachedApplication(cachedApp);
+		}
+
+		for (OAuthClientModel client : model.getOAuthClients()) {
+			clients.put(client.getClientId(), client.getId());
+			CachedOAuthClient cachedApp = new CachedOAuthClient(cache, delegate, model, client);
+			cache.addCachedOAuthClient(cachedApp);
+		}
+
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getMasterAdminApp() {
+		return masterAdminApp;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public List<String> getDefaultRoles() {
+		return defaultRoles;
+	}
+
+	public Map<String, String> getRealmRoles() {
+		return realmRoles;
+	}
+
+	public Map<String, String> getApplications() {
+		return applications;
+	}
+
+	public Map<String, String> getClients() {
+		return clients;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public SslRequired getSslRequired() {
+		return sslRequired;
+	}
+
+	public boolean isRegistrationAllowed() {
+		return registrationAllowed;
+	}
+
+	public boolean isRegistrationEmailAsUsername() {
+		return registrationEmailAsUsername;
+	}
+
+	public boolean isPasswordCredentialGrantAllowed() {
+		return passwordCredentialGrantAllowed;
+	}
+
+	public boolean isRememberMe() {
+		return this.rememberMe;
+	}
+
+	public boolean isBruteForceProtected() {
+		return bruteForceProtected;
+	}
+
+	public int getMaxFailureWaitSeconds() {
+		return this.maxFailureWaitSeconds;
+	}
+
+	public int getWaitIncrementSeconds() {
+		return this.waitIncrementSeconds;
+	}
+
+	public int getMinimumQuickLoginWaitSeconds() {
+		return this.minimumQuickLoginWaitSeconds;
+	}
+
+	public long getQuickLoginCheckMilliSeconds() {
+		return quickLoginCheckMilliSeconds;
+	}
+
+	public int getMaxDeltaTimeSeconds() {
+		return maxDeltaTimeSeconds;
+	}
+
+	public int getFailureFactor() {
+		return failureFactor;
+	}
+
+	public boolean isVerifyEmail() {
+		return verifyEmail;
+	}
+
+	public boolean isResetPasswordAllowed() {
+		return resetPasswordAllowed;
+	}
+
+	public int getSsoSessionIdleTimeout() {
+		return ssoSessionIdleTimeout;
+	}
+
+	public int getSsoSessionMaxLifespan() {
+		return ssoSessionMaxLifespan;
+	}
+
+	public int getAccessTokenLifespan() {
+		return accessTokenLifespan;
+	}
+
+	public int getAccessCodeLifespan() {
+		return accessCodeLifespan;
+	}
+
+	public int getAccessCodeLifespanUserAction() {
+		return accessCodeLifespanUserAction;
+	}
+
+	public int getAccessCodeLifespanLogin() {
+		return accessCodeLifespanLogin;
+	}
+
+	public String getPublicKeyPem() {
+		return publicKeyPem;
+	}
+
+	public String getPrivateKeyPem() {
+		return privateKeyPem;
+	}
+
+	public String getCodeSecret() {
+		return codeSecret;
+	}
+
+	public List<RequiredCredentialModel> getRequiredCredentials() {
+		return requiredCredentials;
+	}
+
+	public PasswordPolicy getPasswordPolicy() {
+		return passwordPolicy;
+	}
+
+	public boolean isIdentityFederationEnabled() {
+		return identityFederationEnabled;
+	}
+
+	public Map<String, String> getSmtpConfig() {
+		return smtpConfig;
+	}
+
+	public Map<String, String> getBrowserSecurityHeaders() {
+		return browserSecurityHeaders;
+	}
+
+	public String getLoginTheme() {
+		return loginTheme;
+	}
+
+	public String getAccountTheme() {
+		return accountTheme;
+	}
+
+	public String getAdminTheme() {
+		return this.adminTheme;
+	}
 
-    public int getWaitIncrementSeconds() {
-        return this.waitIncrementSeconds;
-    }
+	public String getEmailTheme() {
+		return emailTheme;
+	}
 
-    public int getMinimumQuickLoginWaitSeconds() {
-        return this.minimumQuickLoginWaitSeconds;
-    }
+	public int getNotBefore() {
+		return notBefore;
+	}
 
-    public long getQuickLoginCheckMilliSeconds() {
-        return quickLoginCheckMilliSeconds;
-    }
-
-    public int getMaxDeltaTimeSeconds() {
-        return maxDeltaTimeSeconds;
-    }
-
-    public int getFailureFactor() {
-        return failureFactor;
-    }
-
-    public boolean isVerifyEmail() {
-        return verifyEmail;
-    }
-
-    public boolean isResetPasswordAllowed() {
-        return resetPasswordAllowed;
-    }
+	public boolean isEventsEnabled() {
+		return eventsEnabled;
+	}
 
-    public int getSsoSessionIdleTimeout() {
-        return ssoSessionIdleTimeout;
-    }
+	public long getEventsExpiration() {
+		return eventsExpiration;
+	}
 
-    public int getSsoSessionMaxLifespan() {
-        return ssoSessionMaxLifespan;
-    }
+	public Set<String> getEventsListeners() {
+		return eventsListeners;
+	}
 
-    public int getAccessTokenLifespan() {
-        return accessTokenLifespan;
-    }
+	public List<UserFederationProviderModel> getUserFederationProviders() {
+		return userFederationProviders;
+	}
 
-    public int getAccessCodeLifespan() {
-        return accessCodeLifespan;
-    }
+	public String getCertificatePem() {
+		return certificatePem;
+	}
 
-    public int getAccessCodeLifespanUserAction() {
-        return accessCodeLifespanUserAction;
-    }
-    public int getAccessCodeLifespanLogin() {
-        return accessCodeLifespanLogin;
-    }
-
-    public String getPublicKeyPem() {
-        return publicKeyPem;
-    }
-
-    public String getPrivateKeyPem() {
-        return privateKeyPem;
-    }
-
-    public String getCodeSecret() {
-        return codeSecret;
-    }
-
-    public List<RequiredCredentialModel> getRequiredCredentials() {
-        return requiredCredentials;
-    }
-
-    public PasswordPolicy getPasswordPolicy() {
-        return passwordPolicy;
-    }
-
-    public boolean isIdentityFederationEnabled() {
-        return identityFederationEnabled;
-    }
-
-    public Map<String, String> getSmtpConfig() {
-        return smtpConfig;
-    }
-
-    public Map<String, String> getBrowserSecurityHeaders() {
-        return browserSecurityHeaders;
-    }
-
-    public String getLoginTheme() {
-        return loginTheme;
-    }
-
-    public String getAccountTheme() {
-        return accountTheme;
-    }
-
-    public String getAdminTheme() {
-        return this.adminTheme;
-    }
-
-    public String getEmailTheme() {
-        return emailTheme;
-    }
-
-    public int getNotBefore() {
-        return notBefore;
-    }
-
-    public boolean isEventsEnabled() {
-        return eventsEnabled;
-    }
-
-    public long getEventsExpiration() {
-        return eventsExpiration;
-    }
-
-    public Set<String> getEventsListeners() {
-        return eventsListeners;
-    }
-
-    public List<UserFederationProviderModel> getUserFederationProviders() {
-        return userFederationProviders;
-    }
-
-    public String getCertificatePem() {
-        return certificatePem;
-    }
-
-    public List<IdentityProviderModel> getIdentityProviders() {
-        return identityProviders;
-    }
+	public List<IdentityProviderModel> getIdentityProviders() {
+		return identityProviders;
+	}
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
index 57013cf..070f5b0 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
@@ -1,14 +1,23 @@
 package org.keycloak.models.cache;
 
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.keycloak.Config;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClaimTypeModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
@@ -16,864 +25,930 @@ import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
-import java.security.Key;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class RealmAdapter implements RealmModel {
-    protected CachedRealm cached;
-    protected CacheRealmProvider cacheSession;
-    protected RealmModel updated;
-    protected RealmCache cache;
-    protected volatile transient PublicKey publicKey;
-    protected volatile transient PrivateKey privateKey;
-    protected volatile transient Key codeSecretKey;
-    protected volatile transient X509Certificate certificate;
-
-    public RealmAdapter(CachedRealm cached, CacheRealmProvider cacheSession) {
-        this.cached = cached;
-        this.cacheSession = cacheSession;
-    }
-
-    protected void getDelegateForUpdate() {
-        if (updated == null) {
-            cacheSession.registerRealmInvalidation(getId());
-            updated = cacheSession.getDelegate().getRealm(getId());
-            if (updated == null) throw new IllegalStateException("Not found in database");
-        }
-    }
-
-    @Override
-    public String getId() {
-        if (updated != null) return updated.getId();
-        return cached.getId();
-    }
-
-    @Override
-    public String getName() {
-        if (updated != null) return updated.getName();
-        return cached.getName();
-    }
-
-    @Override
-    public void setName(String name) {
-        getDelegateForUpdate();
-        updated.setName(name);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        if (updated != null) return updated.isEnabled();
-        return cached.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        getDelegateForUpdate();
-        updated.setEnabled(enabled);
-    }
-
-    @Override
-    public SslRequired getSslRequired() {
-        if (updated != null) return updated.getSslRequired();
-        return cached.getSslRequired();
-    }
-
-    @Override
-    public void setSslRequired(SslRequired sslRequired) {
-        getDelegateForUpdate();
-        updated.setSslRequired(sslRequired);
-    }
-
-    @Override
-    public boolean isRegistrationAllowed() {
-        if (updated != null) return updated.isRegistrationAllowed();
-        return cached.isRegistrationAllowed();
-    }
-
-    @Override
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        getDelegateForUpdate();
-        updated.setRegistrationAllowed(registrationAllowed);
-    }
-
-    @Override
-    public boolean isPasswordCredentialGrantAllowed() {
-        if (updated != null) return updated.isPasswordCredentialGrantAllowed();
-        return cached.isPasswordCredentialGrantAllowed();
-    }
-
-    @Override
-    public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
-        getDelegateForUpdate();
-        updated.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
-    }
-
-    @Override
-    public boolean isRememberMe() {
-        if (updated != null) return updated.isRememberMe();
-        return cached.isRememberMe();
-    }
-
-    @Override
-    public void setRememberMe(boolean rememberMe) {
-        getDelegateForUpdate();
-        updated.setRememberMe(rememberMe);
-    }
-
-    @Override
-    public boolean isBruteForceProtected() {
-        if (updated != null) return updated.isBruteForceProtected();
-        return cached.isBruteForceProtected();
-    }
-
-    @Override
-    public void setBruteForceProtected(boolean value) {
-        getDelegateForUpdate();
-        updated.setBruteForceProtected(value);
-    }
-
-    @Override
-    public int getMaxFailureWaitSeconds() {
-        if (updated != null) return updated.getMaxFailureWaitSeconds();
-        return cached.getMaxFailureWaitSeconds();
-    }
-
-    @Override
-    public void setMaxFailureWaitSeconds(int val) {
-        getDelegateForUpdate();
-        updated.setMaxFailureWaitSeconds(val);
-    }
-
-    @Override
-    public int getWaitIncrementSeconds() {
-        if (updated != null) return updated.getWaitIncrementSeconds();
-        return cached.getWaitIncrementSeconds();
-    }
-
-    @Override
-    public void setWaitIncrementSeconds(int val) {
-        getDelegateForUpdate();
-        updated.setWaitIncrementSeconds(val);
-    }
-
-    @Override
-    public int getMinimumQuickLoginWaitSeconds() {
-        if (updated != null) return updated.getMinimumQuickLoginWaitSeconds();
-        return cached.getMinimumQuickLoginWaitSeconds();
-    }
-
-    @Override
-    public void setMinimumQuickLoginWaitSeconds(int val) {
-        getDelegateForUpdate();
-        updated.setMinimumQuickLoginWaitSeconds(val);
-    }
-
-    @Override
-    public long getQuickLoginCheckMilliSeconds() {
-        if (updated != null) return updated.getQuickLoginCheckMilliSeconds();
-        return cached.getQuickLoginCheckMilliSeconds();
-    }
-
-    @Override
-    public void setQuickLoginCheckMilliSeconds(long val) {
-        getDelegateForUpdate();
-        updated.setQuickLoginCheckMilliSeconds(val);
-    }
-
-    @Override
-    public int getMaxDeltaTimeSeconds() {
-        if (updated != null) return updated.getMaxDeltaTimeSeconds();
-        return cached.getMaxDeltaTimeSeconds();
-    }
-
-    @Override
-    public void setMaxDeltaTimeSeconds(int val) {
-        getDelegateForUpdate();
-        updated.setMaxDeltaTimeSeconds(val);
-    }
-
-    @Override
-    public int getFailureFactor() {
-        if (updated != null) return updated.getFailureFactor();
-        return cached.getFailureFactor();
-    }
-
-    @Override
-    public void setFailureFactor(int failureFactor) {
-        getDelegateForUpdate();
-        updated.setFailureFactor(failureFactor);
-    }
-
-    @Override
-    public boolean isVerifyEmail() {
-        if (updated != null) return updated.isVerifyEmail();
-        return cached.isVerifyEmail();
-    }
-
-    @Override
-    public void setVerifyEmail(boolean verifyEmail) {
-        getDelegateForUpdate();
-        updated.setVerifyEmail(verifyEmail);
-    }
-
-    @Override
-    public boolean isResetPasswordAllowed() {
-        if (updated != null) return updated.isResetPasswordAllowed();
-        return cached.isResetPasswordAllowed();
-    }
-
-    @Override
-    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
-        getDelegateForUpdate();
-        updated.setResetPasswordAllowed(resetPasswordAllowed);
-    }
-
-    @Override
-    public int getSsoSessionIdleTimeout() {
-        if (updated != null) return updated.getSsoSessionIdleTimeout();
-        return cached.getSsoSessionIdleTimeout();
-    }
-
-    @Override
-    public void setSsoSessionIdleTimeout(int seconds) {
-        getDelegateForUpdate();
-        updated.setSsoSessionIdleTimeout(seconds);
-    }
-
-    @Override
-    public int getSsoSessionMaxLifespan() {
-        if (updated != null) return updated.getSsoSessionMaxLifespan();
-        return cached.getSsoSessionMaxLifespan();
-    }
-
-    @Override
-    public void setSsoSessionMaxLifespan(int seconds) {
-        getDelegateForUpdate();
-        updated.setSsoSessionMaxLifespan(seconds);
-    }
-
-    @Override
-    public int getAccessTokenLifespan() {
-        if (updated != null) return updated.getAccessTokenLifespan();
-        return cached.getAccessTokenLifespan();
-    }
-
-    @Override
-    public void setAccessTokenLifespan(int seconds) {
-        getDelegateForUpdate();
-        updated.setAccessTokenLifespan(seconds);
-    }
-
-    @Override
-    public int getAccessCodeLifespan() {
-        if (updated != null) return updated.getAccessCodeLifespan();
-        return cached.getAccessCodeLifespan();
-    }
-
-    @Override
-    public void setAccessCodeLifespan(int seconds) {
-        getDelegateForUpdate();
-        updated.setAccessCodeLifespan(seconds);
-    }
-
-    @Override
-    public int getAccessCodeLifespanUserAction() {
-        if (updated != null) return updated.getAccessCodeLifespanUserAction();
-        return cached.getAccessCodeLifespanUserAction();
-    }
-
-    @Override
-    public void setAccessCodeLifespanUserAction(int seconds) {
-        getDelegateForUpdate();
-        updated.setAccessCodeLifespanUserAction(seconds);
-    }
-
-    @Override
-    public int getAccessCodeLifespanLogin() {
-        if (updated != null) return updated.getAccessCodeLifespanLogin();
-        return cached.getAccessCodeLifespanLogin();
-    }
-
-    @Override
-    public void setAccessCodeLifespanLogin(int seconds) {
-        getDelegateForUpdate();
-        updated.setAccessCodeLifespanLogin(seconds);
-    }
-
-    @Override
-    public String getPublicKeyPem() {
-        if (updated != null) return updated.getPublicKeyPem();
-        return cached.getPublicKeyPem();
-    }
-
-    @Override
-    public void setPublicKeyPem(String publicKeyPem) {
-        getDelegateForUpdate();
-        updated.setPublicKeyPem(publicKeyPem);
-    }
-
-    @Override
-    public String getPrivateKeyPem() {
-        if (updated != null) return updated.getPrivateKeyPem();
-        return cached.getPrivateKeyPem();
-    }
-
-    @Override
-    public void setPrivateKeyPem(String privateKeyPem) {
-        getDelegateForUpdate();
-        updated.setPrivateKeyPem(privateKeyPem);
-    }
-
-    @Override
-    public PublicKey getPublicKey() {
-        if (publicKey != null) return publicKey;
-        publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
-        return publicKey;
-    }
-
-    @Override
-    public void setPublicKey(PublicKey publicKey) {
-        this.publicKey = publicKey;
-        String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
-        setPublicKeyPem(publicKeyPem);
-    }
-
-    @Override
-    public X509Certificate getCertificate() {
-        if (certificate != null) return certificate;
-        certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
-        return certificate;
-    }
-
-    @Override
-    public void setCertificate(X509Certificate certificate) {
-        this.certificate = certificate;
-        String certPem = KeycloakModelUtils.getPemFromCertificate(certificate);
-        setCertificatePem(certPem);
-    }
-
-    @Override
-    public String getCertificatePem() {
-        if (updated != null) return updated.getCertificatePem();
-        return cached.getCertificatePem();
-    }
-
-    @Override
-    public void setCertificatePem(String certificate) {
-        getDelegateForUpdate();
-        updated.setCertificatePem(certificate);
-
-    }
-
-    @Override
-    public PrivateKey getPrivateKey() {
-        if (privateKey != null) return privateKey;
-        privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
-        return privateKey;
-    }
-
-    @Override
-    public void setPrivateKey(PrivateKey privateKey) {
-        this.privateKey = privateKey;
-        String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
-        setPrivateKeyPem(privateKeyPem);
-    }
-
-    @Override
-    public String getCodeSecret() {
-        return updated != null ? updated.getCodeSecret() : cached.getCodeSecret();
-    }
-
-    @Override
-    public Key getCodeSecretKey() {
-        if (codeSecretKey == null) {
-            codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
-        }
-        return codeSecretKey;
-    }
-
-    @Override
-    public void setCodeSecret(String codeSecret) {
-        getDelegateForUpdate();
-        updated.setCodeSecret(codeSecret);
-    }
-
-    @Override
-    public List<RequiredCredentialModel> getRequiredCredentials() {
-
-        List<RequiredCredentialModel> copy = new LinkedList<RequiredCredentialModel>();
-        if (updated != null) copy.addAll(updated.getRequiredCredentials());
-        else copy.addAll(cached.getRequiredCredentials());
-        return copy;
-    }
-
-    @Override
-    public void addRequiredCredential(String cred) {
-        getDelegateForUpdate();
-        updated.addRequiredCredential(cred);
-    }
-
-    @Override
-    public PasswordPolicy getPasswordPolicy() {
-        if (updated != null) return updated.getPasswordPolicy();
-        return cached.getPasswordPolicy();
-    }
-
-    @Override
-    public void setPasswordPolicy(PasswordPolicy policy) {
-        getDelegateForUpdate();
-        updated.setPasswordPolicy(policy);
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        if (updated != null) return updated.getRoleById(id);
-        return cacheSession.getRoleById(id, this);
-     }
-
-    @Override
-    public List<String> getDefaultRoles() {
-        if (updated != null) return updated.getDefaultRoles();
-        return cached.getDefaultRoles();
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        getDelegateForUpdate();
-        updated.addDefaultRole(name);
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        getDelegateForUpdate();
-        updated.updateDefaultRoles(defaultRoles);
-    }
-
-    @Override
-    public ClientModel findClient(String clientId) {
-        if (updated != null) return updated.findClient(clientId);
-        String appId = cached.getApplications().get(clientId);
-        if (appId != null) {
-            return cacheSession.getApplicationById(appId, this);
-        }
-        String oauth = cached.getClients().get(clientId);
-        if (oauth != null) {
-            return cacheSession.getOAuthClientById(oauth, this);
-        }
-        return null;
-    }
-
-    @Override
-    public Map<String, ApplicationModel> getApplicationNameMap() {
-        if (updated != null) return updated.getApplicationNameMap();
-        Map<String, ApplicationModel> map = new HashMap<String, ApplicationModel>();
-        for (String id : cached.getApplications().values()) {
-            ApplicationModel model = cacheSession.getApplicationById(id, this);
-            if (model == null) {
-                throw new IllegalStateException("Cached application not found: " + id);
-            }
-            map.put(model.getName(), model);
-        }
-        return map;
-    }
-
-    @Override
-    public List<ApplicationModel> getApplications() {
-        if (updated != null) return updated.getApplications();
-        List<ApplicationModel> apps = new LinkedList<ApplicationModel>();
-        for (String id : cached.getApplications().values()) {
-            ApplicationModel model = cacheSession.getApplicationById(id, this);
-            if (model == null) {
-                throw new IllegalStateException("Cached application not found: " + id);
-            }
-            apps.add(model);
-        }
-        return apps;
-
-    }
-
-    @Override
-    public ApplicationModel addApplication(String name) {
-        getDelegateForUpdate();
-        ApplicationModel app = updated.addApplication(name);
-        cacheSession.registerApplicationInvalidation(app.getId());
-        return app;
-    }
-
-    @Override
-    public ApplicationModel addApplication(String id, String name) {
-        getDelegateForUpdate();
-        ApplicationModel app =  updated.addApplication(id, name);
-        cacheSession.registerApplicationInvalidation(app.getId());
-        return app;
-    }
-
-    @Override
-    public boolean removeApplication(String id) {
-        cacheSession.registerApplicationInvalidation(id);
-        getDelegateForUpdate();
-        return updated.removeApplication(id);
-    }
-
-    @Override
-    public ApplicationModel getApplicationById(String id) {
-        if (updated != null) return updated.getApplicationById(id);
-        return cacheSession.getApplicationById(id, this);
-    }
-
-    @Override
-    public ApplicationModel getApplicationByName(String name) {
-        if (updated != null) return updated.getApplicationByName(name);
-        String id = cached.getApplications().get(name);
-        if (id == null) return null;
-        return getApplicationById(id);
-    }
-
-    @Override
-    public void updateRequiredCredentials(Set<String> creds) {
-        getDelegateForUpdate();
-        updated.updateRequiredCredentials(creds);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String name) {
-        getDelegateForUpdate();
-        OAuthClientModel client = updated.addOAuthClient(name);
-        cacheSession.registerOAuthClientInvalidation(client.getId());
-        return client;
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String id, String name) {
-        getDelegateForUpdate();
-        OAuthClientModel client =  updated.addOAuthClient(id, name);
-        cacheSession.registerOAuthClientInvalidation(client.getId());
-        return client;
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClient(String name) {
-        if (updated != null) return updated.getOAuthClient(name);
-        String id = cached.getClients().get(name);
-        if (id == null) return null;
-        return getOAuthClientById(id);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id) {
-        if (updated != null) return updated.getOAuthClientById(id);
-        return cacheSession.getOAuthClientById(id, this);
-    }
-
-    @Override
-    public boolean removeOAuthClient(String id) {
-        cacheSession.registerOAuthClientInvalidation(id);
-        getDelegateForUpdate();
-        return updated.removeOAuthClient(id);
-    }
-
-    @Override
-    public List<OAuthClientModel> getOAuthClients() {
-        if (updated != null) return updated.getOAuthClients();
-        List<OAuthClientModel> clients = new LinkedList<OAuthClientModel>();
-        for (String id : cached.getClients().values()) {
-            OAuthClientModel model = cacheSession.getOAuthClientById(id, this);
-            if (model == null) {
-                throw new IllegalStateException("Cached oauth client not found: " + id);
-            }
-            clients.add(model);
-        }
-        return clients;
-    }
-
-    @Override
-    public Map<String, String> getBrowserSecurityHeaders() {
-        if (updated != null) return updated.getBrowserSecurityHeaders();
-        return cached.getBrowserSecurityHeaders();
-    }
-
-    @Override
-    public void setBrowserSecurityHeaders(Map<String, String> headers) {
-        getDelegateForUpdate();
-        updated.setBrowserSecurityHeaders(headers);
-
-    }
-
-    @Override
-    public Map<String, String> getSmtpConfig() {
-        if (updated != null) return updated.getSmtpConfig();
-        return cached.getSmtpConfig();
-    }
-
-    @Override
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        getDelegateForUpdate();
-        updated.setSmtpConfig(smtpConfig);
-    }
-
-
-    @Override
-    public List<IdentityProviderModel> getIdentityProviders() {
-        if (updated != null) return updated.getIdentityProviders();
-        return cached.getIdentityProviders();
-    }
-
-    @Override
-    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
-        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
-            if (identityProviderModel.getId().equals(identityProviderId)) {
-                return identityProviderModel;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public void addIdentityProvider(IdentityProviderModel identityProvider) {
-        getDelegateForUpdate();
-        updated.addIdentityProvider(identityProvider);
-    }
-
-    @Override
-    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
-        getDelegateForUpdate();
-        updated.updateIdentityProvider(identityProvider);
-    }
-
-    @Override
-    public void removeIdentityProviderById(String providerId) {
-        getDelegateForUpdate();
-        updated.removeIdentityProviderById(providerId);
-    }
-
-    @Override
-    public List<UserFederationProviderModel> getUserFederationProviders() {
-        if (updated != null) return updated.getUserFederationProviders();
-        return cached.getUserFederationProviders();
-    }
-
-    @Override
-    public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
-        getDelegateForUpdate();
-        updated.setUserFederationProviders(providers);
-    }
-
-    @Override
-    public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
-        getDelegateForUpdate();
-        return updated.addUserFederationProvider(providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
-    }
-
-    @Override
-    public void removeUserFederationProvider(UserFederationProviderModel provider) {
-        getDelegateForUpdate();
-        updated.removeUserFederationProvider(provider);
-
-    }
-
-    @Override
-    public void updateUserFederationProvider(UserFederationProviderModel provider) {
-        getDelegateForUpdate();
-        updated.updateUserFederationProvider(provider);
-
-    }
-
-    @Override
-    public String getLoginTheme() {
-        if (updated != null) return updated.getLoginTheme();
-        return cached.getLoginTheme();
-    }
-
-    @Override
-    public void setLoginTheme(String name) {
-        getDelegateForUpdate();
-        updated.setLoginTheme(name);
-    }
-
-    @Override
-    public String getAccountTheme() {
-        if (updated != null) return updated.getAccountTheme();
-        return cached.getAccountTheme();
-    }
-
-    @Override
-    public void setAccountTheme(String name) {
-        getDelegateForUpdate();
-        updated.setAccountTheme(name);
-    }
-
-    @Override
-    public String getAdminTheme() {
-        if (updated != null) return updated.getAdminTheme();
-        return cached.getAdminTheme();
-    }
-
-    @Override
-    public void setAdminTheme(String name) {
-        getDelegateForUpdate();
-        updated.setAdminTheme(name);
-    }
-
-    @Override
-    public String getEmailTheme() {
-        if (updated != null) return updated.getEmailTheme();
-        return cached.getEmailTheme();
-    }
-
-    @Override
-    public void setEmailTheme(String name) {
-        getDelegateForUpdate();
-        updated.setEmailTheme(name);
-    }
-
-    @Override
-    public int getNotBefore() {
-        if (updated != null) return updated.getNotBefore();
-        return cached.getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        getDelegateForUpdate();
-        updated.setNotBefore(notBefore);
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        cacheSession.registerRoleInvalidation(id);
-        getDelegateForUpdate();
-        return updated.removeRoleById(id);
-    }
-
-    @Override
-    public boolean isEventsEnabled() {
-        if (updated != null) return updated.isEventsEnabled();
-        return cached.isEventsEnabled();
-    }
-
-    @Override
-    public void setEventsEnabled(boolean enabled) {
-        getDelegateForUpdate();
-        updated.setEventsEnabled(enabled);
-    }
-
-    @Override
-    public long getEventsExpiration() {
-        if (updated != null) return updated.getEventsExpiration();
-        return cached.getEventsExpiration();
-    }
-
-    @Override
-    public void setEventsExpiration(long expiration) {
-        getDelegateForUpdate();
-        updated.setEventsExpiration(expiration);
-    }
-
-    @Override
-    public Set<String> getEventsListeners() {
-        if (updated != null) return updated.getEventsListeners();
-        return cached.getEventsListeners();
-    }
-
-    @Override
-    public void setEventsListeners(Set<String> listeners) {
-        getDelegateForUpdate();
-        updated.setEventsListeners(listeners);
-    }
-
-    @Override
-    public ApplicationModel getMasterAdminApp() {
-        return cacheSession.getRealm(Config.getAdminRealm()).getApplicationById(cached.getMasterAdminApp());
-    }
-
-    @Override
-    public void setMasterAdminApp(ApplicationModel app) {
-        getDelegateForUpdate();
-        updated.setMasterAdminApp(app);
-    }
-
-    @Override
-    public RoleModel getRole(String name) {
-        if (updated != null) return updated.getRole(name);
-        String id = cached.getRealmRoles().get(name);
-        if (id == null) return null;
-        return cacheSession.getRoleById(id, this);
-    }
-
-    @Override
-    public RoleModel addRole(String name) {
-        getDelegateForUpdate();
-        RoleModel role = updated.addRole(name);
-        cacheSession.registerRoleInvalidation(role.getId());
-        return role;
-    }
-
-    @Override
-    public RoleModel addRole(String id, String name) {
-        getDelegateForUpdate();
-        RoleModel role =  updated.addRole(id, name);
-        cacheSession.registerRoleInvalidation(role.getId());
-        return role;
-    }
-
-    @Override
-    public boolean removeRole(RoleModel role) {
-        cacheSession.registerRoleInvalidation(role.getId());
-        getDelegateForUpdate();
-        return updated.removeRole(role);
-    }
-
-    @Override
-    public Set<RoleModel> getRoles() {
-        if (updated != null) return updated.getRoles();
-
-        Set<RoleModel> roles = new HashSet<RoleModel>();
-        for (String id : cached.getRealmRoles().values()) {
-            RoleModel roleById = cacheSession.getRoleById(id, this);
-            if (roleById == null) continue;
-            roles.add(roleById);
-        }
-        return roles;
-    }
-
-    @Override
-    public ClientModel findClientById(String id) {
-        ClientModel model = getApplicationById(id);
-        if (model != null) return model;
-        return getOAuthClientById(id);
-    }
-
-    @Override
-    public boolean isIdentityFederationEnabled() {
-        if (updated != null) return updated.isIdentityFederationEnabled();
-        return cached.isIdentityFederationEnabled();
-    }
-
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || !(o instanceof RealmModel)) return false;
-
-        RealmModel that = (RealmModel) o;
-        return that.getId().equals(getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return getId().hashCode();
-    }
+	protected CachedRealm cached;
+	protected CacheRealmProvider cacheSession;
+	protected RealmModel updated;
+	protected RealmCache cache;
+	protected volatile transient PublicKey publicKey;
+	protected volatile transient PrivateKey privateKey;
+	protected volatile transient Key codeSecretKey;
+	protected volatile transient X509Certificate certificate;
+
+	public RealmAdapter(CachedRealm cached, CacheRealmProvider cacheSession) {
+		this.cached = cached;
+		this.cacheSession = cacheSession;
+	}
+
+	protected void getDelegateForUpdate() {
+		if (updated == null) {
+			cacheSession.registerRealmInvalidation(getId());
+			updated = cacheSession.getDelegate().getRealm(getId());
+			if (updated == null)
+				throw new IllegalStateException("Not found in database");
+		}
+	}
+
+	@Override
+	public String getId() {
+		if (updated != null)
+			return updated.getId();
+		return cached.getId();
+	}
+
+	@Override
+	public String getName() {
+		if (updated != null)
+			return updated.getName();
+		return cached.getName();
+	}
+
+	@Override
+	public void setName(String name) {
+		getDelegateForUpdate();
+		updated.setName(name);
+	}
+
+	@Override
+	public boolean isEnabled() {
+		if (updated != null)
+			return updated.isEnabled();
+		return cached.isEnabled();
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		getDelegateForUpdate();
+		updated.setEnabled(enabled);
+	}
+
+	@Override
+	public SslRequired getSslRequired() {
+		if (updated != null)
+			return updated.getSslRequired();
+		return cached.getSslRequired();
+	}
+
+	@Override
+	public void setSslRequired(SslRequired sslRequired) {
+		getDelegateForUpdate();
+		updated.setSslRequired(sslRequired);
+	}
+
+	@Override
+	public boolean isRegistrationAllowed() {
+		if (updated != null)
+			return updated.isRegistrationAllowed();
+		return cached.isRegistrationAllowed();
+	}
+
+	@Override
+	public void setRegistrationAllowed(boolean registrationAllowed) {
+		getDelegateForUpdate();
+		updated.setRegistrationAllowed(registrationAllowed);
+	}
+
+	@Override
+	public boolean isRegistrationEmailAsUsername() {
+		if (updated != null)
+			return updated.isRegistrationEmailAsUsername();
+		return cached.isRegistrationEmailAsUsername();
+	}
+
+	@Override
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		getDelegateForUpdate();
+		updated.setRegistrationEmailAsUsername(registrationEmailAsUsername);
+	}
+
+	@Override
+	public boolean isPasswordCredentialGrantAllowed() {
+		if (updated != null)
+			return updated.isPasswordCredentialGrantAllowed();
+		return cached.isPasswordCredentialGrantAllowed();
+	}
+
+	@Override
+	public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
+		getDelegateForUpdate();
+		updated.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
+	}
+
+	@Override
+	public boolean isRememberMe() {
+		if (updated != null)
+			return updated.isRememberMe();
+		return cached.isRememberMe();
+	}
+
+	@Override
+	public void setRememberMe(boolean rememberMe) {
+		getDelegateForUpdate();
+		updated.setRememberMe(rememberMe);
+	}
+
+	@Override
+	public boolean isBruteForceProtected() {
+		if (updated != null)
+			return updated.isBruteForceProtected();
+		return cached.isBruteForceProtected();
+	}
+
+	@Override
+	public void setBruteForceProtected(boolean value) {
+		getDelegateForUpdate();
+		updated.setBruteForceProtected(value);
+	}
+
+	@Override
+	public int getMaxFailureWaitSeconds() {
+		if (updated != null)
+			return updated.getMaxFailureWaitSeconds();
+		return cached.getMaxFailureWaitSeconds();
+	}
+
+	@Override
+	public void setMaxFailureWaitSeconds(int val) {
+		getDelegateForUpdate();
+		updated.setMaxFailureWaitSeconds(val);
+	}
+
+	@Override
+	public int getWaitIncrementSeconds() {
+		if (updated != null)
+			return updated.getWaitIncrementSeconds();
+		return cached.getWaitIncrementSeconds();
+	}
+
+	@Override
+	public void setWaitIncrementSeconds(int val) {
+		getDelegateForUpdate();
+		updated.setWaitIncrementSeconds(val);
+	}
+
+	@Override
+	public int getMinimumQuickLoginWaitSeconds() {
+		if (updated != null)
+			return updated.getMinimumQuickLoginWaitSeconds();
+		return cached.getMinimumQuickLoginWaitSeconds();
+	}
+
+	@Override
+	public void setMinimumQuickLoginWaitSeconds(int val) {
+		getDelegateForUpdate();
+		updated.setMinimumQuickLoginWaitSeconds(val);
+	}
+
+	@Override
+	public long getQuickLoginCheckMilliSeconds() {
+		if (updated != null)
+			return updated.getQuickLoginCheckMilliSeconds();
+		return cached.getQuickLoginCheckMilliSeconds();
+	}
+
+	@Override
+	public void setQuickLoginCheckMilliSeconds(long val) {
+		getDelegateForUpdate();
+		updated.setQuickLoginCheckMilliSeconds(val);
+	}
+
+	@Override
+	public int getMaxDeltaTimeSeconds() {
+		if (updated != null)
+			return updated.getMaxDeltaTimeSeconds();
+		return cached.getMaxDeltaTimeSeconds();
+	}
+
+	@Override
+	public void setMaxDeltaTimeSeconds(int val) {
+		getDelegateForUpdate();
+		updated.setMaxDeltaTimeSeconds(val);
+	}
+
+	@Override
+	public int getFailureFactor() {
+		if (updated != null)
+			return updated.getFailureFactor();
+		return cached.getFailureFactor();
+	}
+
+	@Override
+	public void setFailureFactor(int failureFactor) {
+		getDelegateForUpdate();
+		updated.setFailureFactor(failureFactor);
+	}
+
+	@Override
+	public boolean isVerifyEmail() {
+		if (updated != null)
+			return updated.isVerifyEmail();
+		return cached.isVerifyEmail();
+	}
+
+	@Override
+	public void setVerifyEmail(boolean verifyEmail) {
+		getDelegateForUpdate();
+		updated.setVerifyEmail(verifyEmail);
+	}
+
+	@Override
+	public boolean isResetPasswordAllowed() {
+		if (updated != null)
+			return updated.isResetPasswordAllowed();
+		return cached.isResetPasswordAllowed();
+	}
+
+	@Override
+	public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+		getDelegateForUpdate();
+		updated.setResetPasswordAllowed(resetPasswordAllowed);
+	}
+
+	@Override
+	public int getSsoSessionIdleTimeout() {
+		if (updated != null)
+			return updated.getSsoSessionIdleTimeout();
+		return cached.getSsoSessionIdleTimeout();
+	}
+
+	@Override
+	public void setSsoSessionIdleTimeout(int seconds) {
+		getDelegateForUpdate();
+		updated.setSsoSessionIdleTimeout(seconds);
+	}
+
+	@Override
+	public int getSsoSessionMaxLifespan() {
+		if (updated != null)
+			return updated.getSsoSessionMaxLifespan();
+		return cached.getSsoSessionMaxLifespan();
+	}
+
+	@Override
+	public void setSsoSessionMaxLifespan(int seconds) {
+		getDelegateForUpdate();
+		updated.setSsoSessionMaxLifespan(seconds);
+	}
+
+	@Override
+	public int getAccessTokenLifespan() {
+		if (updated != null)
+			return updated.getAccessTokenLifespan();
+		return cached.getAccessTokenLifespan();
+	}
+
+	@Override
+	public void setAccessTokenLifespan(int seconds) {
+		getDelegateForUpdate();
+		updated.setAccessTokenLifespan(seconds);
+	}
+
+	@Override
+	public int getAccessCodeLifespan() {
+		if (updated != null)
+			return updated.getAccessCodeLifespan();
+		return cached.getAccessCodeLifespan();
+	}
+
+	@Override
+	public void setAccessCodeLifespan(int seconds) {
+		getDelegateForUpdate();
+		updated.setAccessCodeLifespan(seconds);
+	}
+
+	@Override
+	public int getAccessCodeLifespanUserAction() {
+		if (updated != null)
+			return updated.getAccessCodeLifespanUserAction();
+		return cached.getAccessCodeLifespanUserAction();
+	}
+
+	@Override
+	public void setAccessCodeLifespanUserAction(int seconds) {
+		getDelegateForUpdate();
+		updated.setAccessCodeLifespanUserAction(seconds);
+	}
+
+	@Override
+	public int getAccessCodeLifespanLogin() {
+		if (updated != null)
+			return updated.getAccessCodeLifespanLogin();
+		return cached.getAccessCodeLifespanLogin();
+	}
+
+	@Override
+	public void setAccessCodeLifespanLogin(int seconds) {
+		getDelegateForUpdate();
+		updated.setAccessCodeLifespanLogin(seconds);
+	}
+
+	@Override
+	public String getPublicKeyPem() {
+		if (updated != null)
+			return updated.getPublicKeyPem();
+		return cached.getPublicKeyPem();
+	}
+
+	@Override
+	public void setPublicKeyPem(String publicKeyPem) {
+		getDelegateForUpdate();
+		updated.setPublicKeyPem(publicKeyPem);
+	}
+
+	@Override
+	public String getPrivateKeyPem() {
+		if (updated != null)
+			return updated.getPrivateKeyPem();
+		return cached.getPrivateKeyPem();
+	}
+
+	@Override
+	public void setPrivateKeyPem(String privateKeyPem) {
+		getDelegateForUpdate();
+		updated.setPrivateKeyPem(privateKeyPem);
+	}
+
+	@Override
+	public PublicKey getPublicKey() {
+		if (publicKey != null)
+			return publicKey;
+		publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
+		return publicKey;
+	}
+
+	@Override
+	public void setPublicKey(PublicKey publicKey) {
+		this.publicKey = publicKey;
+		String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
+		setPublicKeyPem(publicKeyPem);
+	}
+
+	@Override
+	public X509Certificate getCertificate() {
+		if (certificate != null)
+			return certificate;
+		certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
+		return certificate;
+	}
+
+	@Override
+	public void setCertificate(X509Certificate certificate) {
+		this.certificate = certificate;
+		String certPem = KeycloakModelUtils.getPemFromCertificate(certificate);
+		setCertificatePem(certPem);
+	}
+
+	@Override
+	public String getCertificatePem() {
+		if (updated != null)
+			return updated.getCertificatePem();
+		return cached.getCertificatePem();
+	}
+
+	@Override
+	public void setCertificatePem(String certificate) {
+		getDelegateForUpdate();
+		updated.setCertificatePem(certificate);
+
+	}
+
+	@Override
+	public PrivateKey getPrivateKey() {
+		if (privateKey != null)
+			return privateKey;
+		privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
+		return privateKey;
+	}
+
+	@Override
+	public void setPrivateKey(PrivateKey privateKey) {
+		this.privateKey = privateKey;
+		String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
+		setPrivateKeyPem(privateKeyPem);
+	}
+
+	@Override
+	public String getCodeSecret() {
+		return updated != null ? updated.getCodeSecret() : cached.getCodeSecret();
+	}
+
+	@Override
+	public Key getCodeSecretKey() {
+		if (codeSecretKey == null) {
+			codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
+		}
+		return codeSecretKey;
+	}
+
+	@Override
+	public void setCodeSecret(String codeSecret) {
+		getDelegateForUpdate();
+		updated.setCodeSecret(codeSecret);
+	}
+
+	@Override
+	public List<RequiredCredentialModel> getRequiredCredentials() {
+
+		List<RequiredCredentialModel> copy = new LinkedList<RequiredCredentialModel>();
+		if (updated != null)
+			copy.addAll(updated.getRequiredCredentials());
+		else
+			copy.addAll(cached.getRequiredCredentials());
+		return copy;
+	}
+
+	@Override
+	public void addRequiredCredential(String cred) {
+		getDelegateForUpdate();
+		updated.addRequiredCredential(cred);
+	}
+
+	@Override
+	public PasswordPolicy getPasswordPolicy() {
+		if (updated != null)
+			return updated.getPasswordPolicy();
+		return cached.getPasswordPolicy();
+	}
+
+	@Override
+	public void setPasswordPolicy(PasswordPolicy policy) {
+		getDelegateForUpdate();
+		updated.setPasswordPolicy(policy);
+	}
+
+	@Override
+	public RoleModel getRoleById(String id) {
+		if (updated != null)
+			return updated.getRoleById(id);
+		return cacheSession.getRoleById(id, this);
+	}
+
+	@Override
+	public List<String> getDefaultRoles() {
+		if (updated != null)
+			return updated.getDefaultRoles();
+		return cached.getDefaultRoles();
+	}
+
+	@Override
+	public void addDefaultRole(String name) {
+		getDelegateForUpdate();
+		updated.addDefaultRole(name);
+	}
+
+	@Override
+	public void updateDefaultRoles(String[] defaultRoles) {
+		getDelegateForUpdate();
+		updated.updateDefaultRoles(defaultRoles);
+	}
+
+	@Override
+	public ClientModel findClient(String clientId) {
+		if (updated != null)
+			return updated.findClient(clientId);
+		String appId = cached.getApplications().get(clientId);
+		if (appId != null) {
+			return cacheSession.getApplicationById(appId, this);
+		}
+		String oauth = cached.getClients().get(clientId);
+		if (oauth != null) {
+			return cacheSession.getOAuthClientById(oauth, this);
+		}
+		return null;
+	}
+
+	@Override
+	public Map<String, ApplicationModel> getApplicationNameMap() {
+		if (updated != null)
+			return updated.getApplicationNameMap();
+		Map<String, ApplicationModel> map = new HashMap<String, ApplicationModel>();
+		for (String id : cached.getApplications().values()) {
+			ApplicationModel model = cacheSession.getApplicationById(id, this);
+			if (model == null) {
+				throw new IllegalStateException("Cached application not found: " + id);
+			}
+			map.put(model.getName(), model);
+		}
+		return map;
+	}
+
+	@Override
+	public List<ApplicationModel> getApplications() {
+		if (updated != null)
+			return updated.getApplications();
+		List<ApplicationModel> apps = new LinkedList<ApplicationModel>();
+		for (String id : cached.getApplications().values()) {
+			ApplicationModel model = cacheSession.getApplicationById(id, this);
+			if (model == null) {
+				throw new IllegalStateException("Cached application not found: " + id);
+			}
+			apps.add(model);
+		}
+		return apps;
+
+	}
+
+	@Override
+	public ApplicationModel addApplication(String name) {
+		getDelegateForUpdate();
+		ApplicationModel app = updated.addApplication(name);
+		cacheSession.registerApplicationInvalidation(app.getId());
+		return app;
+	}
+
+	@Override
+	public ApplicationModel addApplication(String id, String name) {
+		getDelegateForUpdate();
+		ApplicationModel app = updated.addApplication(id, name);
+		cacheSession.registerApplicationInvalidation(app.getId());
+		return app;
+	}
+
+	@Override
+	public boolean removeApplication(String id) {
+		cacheSession.registerApplicationInvalidation(id);
+		getDelegateForUpdate();
+		return updated.removeApplication(id);
+	}
+
+	@Override
+	public ApplicationModel getApplicationById(String id) {
+		if (updated != null)
+			return updated.getApplicationById(id);
+		return cacheSession.getApplicationById(id, this);
+	}
+
+	@Override
+	public ApplicationModel getApplicationByName(String name) {
+		if (updated != null)
+			return updated.getApplicationByName(name);
+		String id = cached.getApplications().get(name);
+		if (id == null)
+			return null;
+		return getApplicationById(id);
+	}
+
+	@Override
+	public void updateRequiredCredentials(Set<String> creds) {
+		getDelegateForUpdate();
+		updated.updateRequiredCredentials(creds);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String name) {
+		getDelegateForUpdate();
+		OAuthClientModel client = updated.addOAuthClient(name);
+		cacheSession.registerOAuthClientInvalidation(client.getId());
+		return client;
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String id, String name) {
+		getDelegateForUpdate();
+		OAuthClientModel client = updated.addOAuthClient(id, name);
+		cacheSession.registerOAuthClientInvalidation(client.getId());
+		return client;
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClient(String name) {
+		if (updated != null)
+			return updated.getOAuthClient(name);
+		String id = cached.getClients().get(name);
+		if (id == null)
+			return null;
+		return getOAuthClientById(id);
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClientById(String id) {
+		if (updated != null)
+			return updated.getOAuthClientById(id);
+		return cacheSession.getOAuthClientById(id, this);
+	}
+
+	@Override
+	public boolean removeOAuthClient(String id) {
+		cacheSession.registerOAuthClientInvalidation(id);
+		getDelegateForUpdate();
+		return updated.removeOAuthClient(id);
+	}
+
+	@Override
+	public List<OAuthClientModel> getOAuthClients() {
+		if (updated != null)
+			return updated.getOAuthClients();
+		List<OAuthClientModel> clients = new LinkedList<OAuthClientModel>();
+		for (String id : cached.getClients().values()) {
+			OAuthClientModel model = cacheSession.getOAuthClientById(id, this);
+			if (model == null) {
+				throw new IllegalStateException("Cached oauth client not found: " + id);
+			}
+			clients.add(model);
+		}
+		return clients;
+	}
+
+	@Override
+	public Map<String, String> getBrowserSecurityHeaders() {
+		if (updated != null)
+			return updated.getBrowserSecurityHeaders();
+		return cached.getBrowserSecurityHeaders();
+	}
+
+	@Override
+	public void setBrowserSecurityHeaders(Map<String, String> headers) {
+		getDelegateForUpdate();
+		updated.setBrowserSecurityHeaders(headers);
+
+	}
+
+	@Override
+	public Map<String, String> getSmtpConfig() {
+		if (updated != null)
+			return updated.getSmtpConfig();
+		return cached.getSmtpConfig();
+	}
+
+	@Override
+	public void setSmtpConfig(Map<String, String> smtpConfig) {
+		getDelegateForUpdate();
+		updated.setSmtpConfig(smtpConfig);
+	}
+
+	@Override
+	public List<IdentityProviderModel> getIdentityProviders() {
+		if (updated != null)
+			return updated.getIdentityProviders();
+		return cached.getIdentityProviders();
+	}
+
+	@Override
+	public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+		for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+			if (identityProviderModel.getId().equals(identityProviderId)) {
+				return identityProviderModel;
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public void addIdentityProvider(IdentityProviderModel identityProvider) {
+		getDelegateForUpdate();
+		updated.addIdentityProvider(identityProvider);
+	}
+
+	@Override
+	public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+		getDelegateForUpdate();
+		updated.updateIdentityProvider(identityProvider);
+	}
+
+	@Override
+	public void removeIdentityProviderById(String providerId) {
+		getDelegateForUpdate();
+		updated.removeIdentityProviderById(providerId);
+	}
+
+	@Override
+	public List<UserFederationProviderModel> getUserFederationProviders() {
+		if (updated != null)
+			return updated.getUserFederationProviders();
+		return cached.getUserFederationProviders();
+	}
+
+	@Override
+	public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
+		getDelegateForUpdate();
+		updated.setUserFederationProviders(providers);
+	}
+
+	@Override
+	public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config,
+			int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
+		getDelegateForUpdate();
+		return updated.addUserFederationProvider(providerName, config, priority, displayName, fullSyncPeriod,
+				changedSyncPeriod, lastSync);
+	}
+
+	@Override
+	public void removeUserFederationProvider(UserFederationProviderModel provider) {
+		getDelegateForUpdate();
+		updated.removeUserFederationProvider(provider);
+
+	}
+
+	@Override
+	public void updateUserFederationProvider(UserFederationProviderModel provider) {
+		getDelegateForUpdate();
+		updated.updateUserFederationProvider(provider);
+
+	}
+
+	@Override
+	public String getLoginTheme() {
+		if (updated != null)
+			return updated.getLoginTheme();
+		return cached.getLoginTheme();
+	}
+
+	@Override
+	public void setLoginTheme(String name) {
+		getDelegateForUpdate();
+		updated.setLoginTheme(name);
+	}
+
+	@Override
+	public String getAccountTheme() {
+		if (updated != null)
+			return updated.getAccountTheme();
+		return cached.getAccountTheme();
+	}
+
+	@Override
+	public void setAccountTheme(String name) {
+		getDelegateForUpdate();
+		updated.setAccountTheme(name);
+	}
+
+	@Override
+	public String getAdminTheme() {
+		if (updated != null)
+			return updated.getAdminTheme();
+		return cached.getAdminTheme();
+	}
+
+	@Override
+	public void setAdminTheme(String name) {
+		getDelegateForUpdate();
+		updated.setAdminTheme(name);
+	}
+
+	@Override
+	public String getEmailTheme() {
+		if (updated != null)
+			return updated.getEmailTheme();
+		return cached.getEmailTheme();
+	}
+
+	@Override
+	public void setEmailTheme(String name) {
+		getDelegateForUpdate();
+		updated.setEmailTheme(name);
+	}
+
+	@Override
+	public int getNotBefore() {
+		if (updated != null)
+			return updated.getNotBefore();
+		return cached.getNotBefore();
+	}
+
+	@Override
+	public void setNotBefore(int notBefore) {
+		getDelegateForUpdate();
+		updated.setNotBefore(notBefore);
+	}
+
+	@Override
+	public boolean removeRoleById(String id) {
+		cacheSession.registerRoleInvalidation(id);
+		getDelegateForUpdate();
+		return updated.removeRoleById(id);
+	}
+
+	@Override
+	public boolean isEventsEnabled() {
+		if (updated != null)
+			return updated.isEventsEnabled();
+		return cached.isEventsEnabled();
+	}
+
+	@Override
+	public void setEventsEnabled(boolean enabled) {
+		getDelegateForUpdate();
+		updated.setEventsEnabled(enabled);
+	}
+
+	@Override
+	public long getEventsExpiration() {
+		if (updated != null)
+			return updated.getEventsExpiration();
+		return cached.getEventsExpiration();
+	}
+
+	@Override
+	public void setEventsExpiration(long expiration) {
+		getDelegateForUpdate();
+		updated.setEventsExpiration(expiration);
+	}
+
+	@Override
+	public Set<String> getEventsListeners() {
+		if (updated != null)
+			return updated.getEventsListeners();
+		return cached.getEventsListeners();
+	}
+
+	@Override
+	public void setEventsListeners(Set<String> listeners) {
+		getDelegateForUpdate();
+		updated.setEventsListeners(listeners);
+	}
+
+	@Override
+	public ApplicationModel getMasterAdminApp() {
+		return cacheSession.getRealm(Config.getAdminRealm()).getApplicationById(cached.getMasterAdminApp());
+	}
+
+	@Override
+	public void setMasterAdminApp(ApplicationModel app) {
+		getDelegateForUpdate();
+		updated.setMasterAdminApp(app);
+	}
+
+	@Override
+	public RoleModel getRole(String name) {
+		if (updated != null)
+			return updated.getRole(name);
+		String id = cached.getRealmRoles().get(name);
+		if (id == null)
+			return null;
+		return cacheSession.getRoleById(id, this);
+	}
+
+	@Override
+	public RoleModel addRole(String name) {
+		getDelegateForUpdate();
+		RoleModel role = updated.addRole(name);
+		cacheSession.registerRoleInvalidation(role.getId());
+		return role;
+	}
+
+	@Override
+	public RoleModel addRole(String id, String name) {
+		getDelegateForUpdate();
+		RoleModel role = updated.addRole(id, name);
+		cacheSession.registerRoleInvalidation(role.getId());
+		return role;
+	}
+
+	@Override
+	public boolean removeRole(RoleModel role) {
+		cacheSession.registerRoleInvalidation(role.getId());
+		getDelegateForUpdate();
+		return updated.removeRole(role);
+	}
+
+	@Override
+	public Set<RoleModel> getRoles() {
+		if (updated != null)
+			return updated.getRoles();
+
+		Set<RoleModel> roles = new HashSet<RoleModel>();
+		for (String id : cached.getRealmRoles().values()) {
+			RoleModel roleById = cacheSession.getRoleById(id, this);
+			if (roleById == null)
+				continue;
+			roles.add(roleById);
+		}
+		return roles;
+	}
+
+	@Override
+	public ClientModel findClientById(String id) {
+		ClientModel model = getApplicationById(id);
+		if (model != null)
+			return model;
+		return getOAuthClientById(id);
+	}
+
+	@Override
+	public boolean isIdentityFederationEnabled() {
+		if (updated != null)
+			return updated.isIdentityFederationEnabled();
+		return cached.isIdentityFederationEnabled();
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o == null || !(o instanceof RealmModel))
+			return false;
+
+		RealmModel that = (RealmModel) o;
+		return that.getId().equals(getId());
+	}
+
+	@Override
+	public int hashCode() {
+		return getId().hashCode();
+	}
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index 9a4358b..702f8cd 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -1,5 +1,13 @@
 package org.keycloak.models.jpa.entities;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
@@ -15,432 +23,433 @@ import javax.persistence.NamedQuery;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-@Table(name="REALM")
+@Table(name = "REALM")
 @Entity
-@NamedQueries({
-        @NamedQuery(name="getAllRealms", query="select realm from RealmEntity realm"),
-        @NamedQuery(name="getRealmByName", query="select realm from RealmEntity realm where realm.name = :name"),
-})
+@NamedQueries({ @NamedQuery(name = "getAllRealms", query = "select realm from RealmEntity realm"),
+		@NamedQuery(name = "getRealmByName", query = "select realm from RealmEntity realm where realm.name = :name"), })
 public class RealmEntity {
-    @Id
-    @Column(name="ID", length = 36)
-    protected String id;
-
-    @Column(name="NAME", unique = true)
-    protected String name;
-
-    @Column(name="ENABLED")
-    protected boolean enabled;
-    @Column(name="SSL_REQUIRED")
-    protected String sslRequired;
-    @Column(name="REGISTRATION_ALLOWED")
-    protected boolean registrationAllowed;
-    @Column(name="PASSWORD_CRED_GRANT_ALLOWED")
-    protected boolean passwordCredentialGrantAllowed;
-    @Column(name="VERIFY_EMAIL")
-    protected boolean verifyEmail;
-    @Column(name="RESET_PASSWORD_ALLOWED")
-    protected boolean resetPasswordAllowed;
-    @Column(name="REMEMBER_ME")
-    protected boolean rememberMe;
-    @Column(name="PASSWORD_POLICY")
-    protected String passwordPolicy;
-
-    @Column(name="SSO_IDLE_TIMEOUT")
-    private int ssoSessionIdleTimeout;
-    @Column(name="SSO_MAX_LIFESPAN")
-    private int ssoSessionMaxLifespan;
-    @Column(name="ACCESS_TOKEN_LIFESPAN")
-    protected int accessTokenLifespan;
-    @Column(name="ACCESS_CODE_LIFESPAN")
-    protected int accessCodeLifespan;
-    @Column(name="USER_ACTION_LIFESPAN")
-    protected int accessCodeLifespanUserAction;
-    @Column(name="LOGIN_LIFESPAN")
-    protected int accessCodeLifespanLogin;
-    @Column(name="NOT_BEFORE")
-    protected int notBefore;
-
-    @Column(name="PUBLIC_KEY", length = 2048)
-    protected String publicKeyPem;
-    @Column(name="PRIVATE_KEY", length = 2048)
-    protected String privateKeyPem;
-    @Column(name="CERTIFICATE", length = 2048)
-    protected String certificatePem;
-    @Column(name="CODE_SECRET", length = 255)
-    protected String codeSecret;
-
-    @Column(name="LOGIN_THEME")
-    protected String loginTheme;
-    @Column(name="ACCOUNT_THEME")
-    protected String accountTheme;
-    @Column(name="ADMIN_THEME")
-    protected String adminTheme;
-    @Column(name="EMAIL_THEME")
-    protected String emailTheme;
-
-    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
-    Collection<RealmAttributeEntity> attributes = new ArrayList<RealmAttributeEntity>();
-
-    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
-    Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
-
-    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
-    @JoinTable(name="FED_PROVIDERS")
-    List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
-
-    @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
-    @JoinTable(name="REALM_APPLICATION", joinColumns={ @JoinColumn(name="APPLICATION_ID") }, inverseJoinColumns={ @JoinColumn(name="REALM_ID") })
-    Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
-
-    @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
-    Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
-
-    @ElementCollection
-    @MapKeyColumn(name="NAME")
-    @Column(name="VALUE")
-    @CollectionTable(name="REALM_SMTP_CONFIG", joinColumns={ @JoinColumn(name="REALM_ID") })
-    protected Map<String, String> smtpConfig = new HashMap<String, String>();
-
-    @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
-    @JoinTable(name="REALM_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="REALM_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")})
-    protected Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
-
-    @Column(name="EVENTS_ENABLED")
-    protected boolean eventsEnabled;
-    @Column(name="EVENTS_EXPIRATION")
-    protected long eventsExpiration;
-
-    @ElementCollection
-    @Column(name="VALUE")
-    @CollectionTable(name="REALM_EVENTS_LISTENERS", joinColumns={ @JoinColumn(name="REALM_ID") })
-    protected Set<String> eventsListeners = new HashSet<String>();
-
-    @OneToOne
-    @JoinColumn(name="MASTER_ADMIN_APP")
-    protected ApplicationEntity masterAdminApp;
-
-    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
-    protected List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    public String getSslRequired() {
-        return sslRequired;
-    }
-
-    public void setSslRequired(String sslRequired) {
-        this.sslRequired = sslRequired;
-    }
-
-    public boolean isPasswordCredentialGrantAllowed() {
-        return passwordCredentialGrantAllowed;
-    }
-
-    public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
-        this.passwordCredentialGrantAllowed = passwordCredentialGrantAllowed;
-    }
-
-    public boolean isRegistrationAllowed() {
-        return registrationAllowed;
-    }
-
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        this.registrationAllowed = registrationAllowed;
-    }
-
-    public boolean isRememberMe() {
-        return rememberMe;
-    }
-
-    public void setRememberMe(boolean rememberMe) {
-        this.rememberMe = rememberMe;
-    }
+	@Id
+	@Column(name = "ID", length = 36)
+	protected String id;
+
+	@Column(name = "NAME", unique = true)
+	protected String name;
+
+	@Column(name = "ENABLED")
+	protected boolean enabled;
+	@Column(name = "SSL_REQUIRED")
+	protected String sslRequired;
+	@Column(name = "REGISTRATION_ALLOWED")
+	protected boolean registrationAllowed;
+	@Column(name = "REGISTRATION_EMAIL_AS_USERNAME")
+	protected boolean registrationEmailAsUsername;
+	@Column(name = "PASSWORD_CRED_GRANT_ALLOWED")
+	protected boolean passwordCredentialGrantAllowed;
+	@Column(name = "VERIFY_EMAIL")
+	protected boolean verifyEmail;
+	@Column(name = "RESET_PASSWORD_ALLOWED")
+	protected boolean resetPasswordAllowed;
+	@Column(name = "REMEMBER_ME")
+	protected boolean rememberMe;
+	@Column(name = "PASSWORD_POLICY")
+	protected String passwordPolicy;
+
+	@Column(name = "SSO_IDLE_TIMEOUT")
+	private int ssoSessionIdleTimeout;
+	@Column(name = "SSO_MAX_LIFESPAN")
+	private int ssoSessionMaxLifespan;
+	@Column(name = "ACCESS_TOKEN_LIFESPAN")
+	protected int accessTokenLifespan;
+	@Column(name = "ACCESS_CODE_LIFESPAN")
+	protected int accessCodeLifespan;
+	@Column(name = "USER_ACTION_LIFESPAN")
+	protected int accessCodeLifespanUserAction;
+	@Column(name = "LOGIN_LIFESPAN")
+	protected int accessCodeLifespanLogin;
+	@Column(name = "NOT_BEFORE")
+	protected int notBefore;
+
+	@Column(name = "PUBLIC_KEY", length = 2048)
+	protected String publicKeyPem;
+	@Column(name = "PRIVATE_KEY", length = 2048)
+	protected String privateKeyPem;
+	@Column(name = "CERTIFICATE", length = 2048)
+	protected String certificatePem;
+	@Column(name = "CODE_SECRET", length = 255)
+	protected String codeSecret;
+
+	@Column(name = "LOGIN_THEME")
+	protected String loginTheme;
+	@Column(name = "ACCOUNT_THEME")
+	protected String accountTheme;
+	@Column(name = "ADMIN_THEME")
+	protected String adminTheme;
+	@Column(name = "EMAIL_THEME")
+	protected String emailTheme;
+
+	@OneToMany(cascade = { CascadeType.REMOVE }, orphanRemoval = true, mappedBy = "realm")
+	Collection<RealmAttributeEntity> attributes = new ArrayList<RealmAttributeEntity>();
+
+	@OneToMany(cascade = { CascadeType.REMOVE }, orphanRemoval = true, mappedBy = "realm")
+	Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
+
+	@OneToMany(cascade = { CascadeType.REMOVE }, orphanRemoval = true)
+	@JoinTable(name = "FED_PROVIDERS")
+	List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, orphanRemoval = true)
+	@JoinTable(name = "REALM_APPLICATION", joinColumns = { @JoinColumn(name = "APPLICATION_ID") }, inverseJoinColumns = { @JoinColumn(name = "REALM_ID") })
+	Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, orphanRemoval = true, mappedBy = "realm")
+	Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
+
+	@ElementCollection
+	@MapKeyColumn(name = "NAME")
+	@Column(name = "VALUE")
+	@CollectionTable(name = "REALM_SMTP_CONFIG", joinColumns = { @JoinColumn(name = "REALM_ID") })
+	protected Map<String, String> smtpConfig = new HashMap<String, String>();
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, orphanRemoval = true)
+	@JoinTable(name = "REALM_DEFAULT_ROLES", joinColumns = { @JoinColumn(name = "REALM_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
+	protected Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
+
+	@Column(name = "EVENTS_ENABLED")
+	protected boolean eventsEnabled;
+	@Column(name = "EVENTS_EXPIRATION")
+	protected long eventsExpiration;
+
+	@ElementCollection
+	@Column(name = "VALUE")
+	@CollectionTable(name = "REALM_EVENTS_LISTENERS", joinColumns = { @JoinColumn(name = "REALM_ID") })
+	protected Set<String> eventsListeners = new HashSet<String>();
+
+	@OneToOne
+	@JoinColumn(name = "MASTER_ADMIN_APP")
+	protected ApplicationEntity masterAdminApp;
+
+	@OneToMany(cascade = { CascadeType.REMOVE }, orphanRemoval = true, mappedBy = "realm")
+	protected List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	public String getSslRequired() {
+		return sslRequired;
+	}
+
+	public void setSslRequired(String sslRequired) {
+		this.sslRequired = sslRequired;
+	}
+
+	public boolean isPasswordCredentialGrantAllowed() {
+		return passwordCredentialGrantAllowed;
+	}
+
+	public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
+		this.passwordCredentialGrantAllowed = passwordCredentialGrantAllowed;
+	}
+
+	public boolean isRegistrationAllowed() {
+		return registrationAllowed;
+	}
+
+	public void setRegistrationAllowed(boolean registrationAllowed) {
+		this.registrationAllowed = registrationAllowed;
+	}
+
+	public boolean isRegistrationEmailAsUsername() {
+		return registrationEmailAsUsername;
+	}
 
-    public boolean isVerifyEmail() {
-        return verifyEmail;
-    }
-
-    public void setVerifyEmail(boolean verifyEmail) {
-        this.verifyEmail = verifyEmail;
-    }
-
-    public boolean isResetPasswordAllowed() {
-        return resetPasswordAllowed;
-    }
-
-    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
-        this.resetPasswordAllowed = resetPasswordAllowed;
-    }
-
-    public int getSsoSessionIdleTimeout() {
-        return ssoSessionIdleTimeout;
-    }
-
-    public void setSsoSessionIdleTimeout(int ssoSessionIdleTimeout) {
-        this.ssoSessionIdleTimeout = ssoSessionIdleTimeout;
-    }
-
-    public int getSsoSessionMaxLifespan() {
-        return ssoSessionMaxLifespan;
-    }
-
-    public void setSsoSessionMaxLifespan(int ssoSessionMaxLifespan) {
-        this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
-    }
-
-    public int getAccessTokenLifespan() {
-        return accessTokenLifespan;
-    }
-
-    public void setAccessTokenLifespan(int accessTokenLifespan) {
-        this.accessTokenLifespan = accessTokenLifespan;
-    }
-
-    public int getAccessCodeLifespan() {
-        return accessCodeLifespan;
-    }
-
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        this.accessCodeLifespan = accessCodeLifespan;
-    }
-
-    public int getAccessCodeLifespanUserAction() {
-        return accessCodeLifespanUserAction;
-    }
-
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
-    }
-    public int getAccessCodeLifespanLogin() {
-        return accessCodeLifespanLogin;
-    }
-
-    public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
-        this.accessCodeLifespanLogin = accessCodeLifespanLogin;
-    }
-
-    public String getPublicKeyPem() {
-        return publicKeyPem;
-    }
-
-    public void setPublicKeyPem(String publicKeyPem) {
-        this.publicKeyPem = publicKeyPem;
-    }
-
-    public String getPrivateKeyPem() {
-        return privateKeyPem;
-    }
-
-    public void setPrivateKeyPem(String privateKeyPem) {
-        this.privateKeyPem = privateKeyPem;
-    }
-
-    public String getCodeSecret() {
-        return codeSecret;
-    }
-
-    public void setCodeSecret(String codeSecret) {
-        this.codeSecret = codeSecret;
-    }
-
-    public Collection<RequiredCredentialEntity> getRequiredCredentials() {
-        return requiredCredentials;
-    }
-
-    public void setRequiredCredentials(Collection<RequiredCredentialEntity> requiredCredentials) {
-        this.requiredCredentials = requiredCredentials;
-    }
-
-    public Collection<ApplicationEntity> getApplications() {
-        return applications;
-    }
-
-    public void setApplications(Collection<ApplicationEntity> applications) {
-        this.applications = applications;
-    }
-
-    public Collection<RoleEntity> getRoles() {
-        return roles;
-    }
-
-    public void setRoles(Collection<RoleEntity> roles) {
-        this.roles = roles;
-    }
-
-    public void addRole(RoleEntity role) {
-        if (roles == null) {
-            roles = new ArrayList<RoleEntity>();
-        }
-        roles.add(role);
-    }
-
-    public Map<String, String> getSmtpConfig() {
-        return smtpConfig;
-    }
-
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        this.smtpConfig = smtpConfig;
-    }
-
-    public Collection<RoleEntity> getDefaultRoles() {
-        return defaultRoles;
-    }
-
-    public void setDefaultRoles(Collection<RoleEntity> defaultRoles) {
-        this.defaultRoles = defaultRoles;
-    }
-
-    public String getPasswordPolicy() {
-        return passwordPolicy;
-    }
-
-    public void setPasswordPolicy(String passwordPolicy) {
-        this.passwordPolicy = passwordPolicy;
-    }
-
-    public String getLoginTheme() {
-        return loginTheme;
-    }
-
-    public void setLoginTheme(String theme) {
-        this.loginTheme = theme;
-    }
-
-    public String getAccountTheme() {
-        return accountTheme;
-    }
-
-    public void setAccountTheme(String theme) {
-        this.accountTheme = theme;
-    }
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		this.registrationEmailAsUsername = registrationEmailAsUsername;
+	}
 
-    public String getAdminTheme() {
-        return adminTheme;
-    }
+	public boolean isRememberMe() {
+		return rememberMe;
+	}
 
-    public void setAdminTheme(String adminTheme) {
-        this.adminTheme = adminTheme;
-    }
+	public void setRememberMe(boolean rememberMe) {
+		this.rememberMe = rememberMe;
+	}
 
-    public String getEmailTheme() {
-        return emailTheme;
-    }
+	public boolean isVerifyEmail() {
+		return verifyEmail;
+	}
 
-    public void setEmailTheme(String emailTheme) {
-        this.emailTheme = emailTheme;
-    }
+	public void setVerifyEmail(boolean verifyEmail) {
+		this.verifyEmail = verifyEmail;
+	}
 
-    public int getNotBefore() {
-        return notBefore;
-    }
+	public boolean isResetPasswordAllowed() {
+		return resetPasswordAllowed;
+	}
 
-    public void setNotBefore(int notBefore) {
-        this.notBefore = notBefore;
-    }
+	public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+		this.resetPasswordAllowed = resetPasswordAllowed;
+	}
+
+	public int getSsoSessionIdleTimeout() {
+		return ssoSessionIdleTimeout;
+	}
+
+	public void setSsoSessionIdleTimeout(int ssoSessionIdleTimeout) {
+		this.ssoSessionIdleTimeout = ssoSessionIdleTimeout;
+	}
 
-    public boolean isEventsEnabled() {
-        return eventsEnabled;
-    }
+	public int getSsoSessionMaxLifespan() {
+		return ssoSessionMaxLifespan;
+	}
 
-    public void setEventsEnabled(boolean eventsEnabled) {
-        this.eventsEnabled = eventsEnabled;
-    }
+	public void setSsoSessionMaxLifespan(int ssoSessionMaxLifespan) {
+		this.ssoSessionMaxLifespan = ssoSessionMaxLifespan;
+	}
 
-    public long getEventsExpiration() {
-        return eventsExpiration;
-    }
+	public int getAccessTokenLifespan() {
+		return accessTokenLifespan;
+	}
 
-    public void setEventsExpiration(long eventsExpiration) {
-        this.eventsExpiration = eventsExpiration;
-    }
+	public void setAccessTokenLifespan(int accessTokenLifespan) {
+		this.accessTokenLifespan = accessTokenLifespan;
+	}
 
-    public Set<String> getEventsListeners() {
-        return eventsListeners;
-    }
+	public int getAccessCodeLifespan() {
+		return accessCodeLifespan;
+	}
 
-    public void setEventsListeners(Set<String> eventsListeners) {
-        this.eventsListeners = eventsListeners;
-    }
+	public void setAccessCodeLifespan(int accessCodeLifespan) {
+		this.accessCodeLifespan = accessCodeLifespan;
+	}
 
-    public ApplicationEntity getMasterAdminApp() {
-        return masterAdminApp;
-    }
+	public int getAccessCodeLifespanUserAction() {
+		return accessCodeLifespanUserAction;
+	}
 
-    public void setMasterAdminApp(ApplicationEntity masterAdminApp) {
-        this.masterAdminApp = masterAdminApp;
-    }
+	public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+		this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
+	}
 
-    public List<UserFederationProviderEntity> getUserFederationProviders() {
-        return userFederationProviders;
-    }
+	public int getAccessCodeLifespanLogin() {
+		return accessCodeLifespanLogin;
+	}
 
-    public void setUserFederationProviders(List<UserFederationProviderEntity> userFederationProviders) {
-        this.userFederationProviders = userFederationProviders;
-    }
+	public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
+		this.accessCodeLifespanLogin = accessCodeLifespanLogin;
+	}
 
-    public Collection<RealmAttributeEntity> getAttributes() {
-        return attributes;
-    }
+	public String getPublicKeyPem() {
+		return publicKeyPem;
+	}
 
-    public void setAttributes(Collection<RealmAttributeEntity> attributes) {
-        this.attributes = attributes;
-    }
+	public void setPublicKeyPem(String publicKeyPem) {
+		this.publicKeyPem = publicKeyPem;
+	}
 
-    public String getCertificatePem() {
-        return certificatePem;
-    }
+	public String getPrivateKeyPem() {
+		return privateKeyPem;
+	}
 
-    public void setCertificatePem(String certificatePem) {
-        this.certificatePem = certificatePem;
-    }
+	public void setPrivateKeyPem(String privateKeyPem) {
+		this.privateKeyPem = privateKeyPem;
+	}
 
-    public List<IdentityProviderEntity> getIdentityProviders() {
-        return this.identityProviders;
-    }
+	public String getCodeSecret() {
+		return codeSecret;
+	}
 
-    public void setIdentityProviders(List<IdentityProviderEntity> identityProviders) {
-        this.identityProviders = identityProviders;
-    }
+	public void setCodeSecret(String codeSecret) {
+		this.codeSecret = codeSecret;
+	}
 
-    public void addIdentityProvider(IdentityProviderEntity entity) {
-        entity.setRealm(this);
-        getIdentityProviders().add(entity);
-    }
+	public Collection<RequiredCredentialEntity> getRequiredCredentials() {
+		return requiredCredentials;
+	}
 
-}
+	public void setRequiredCredentials(Collection<RequiredCredentialEntity> requiredCredentials) {
+		this.requiredCredentials = requiredCredentials;
+	}
+
+	public Collection<ApplicationEntity> getApplications() {
+		return applications;
+	}
+
+	public void setApplications(Collection<ApplicationEntity> applications) {
+		this.applications = applications;
+	}
+
+	public Collection<RoleEntity> getRoles() {
+		return roles;
+	}
+
+	public void setRoles(Collection<RoleEntity> roles) {
+		this.roles = roles;
+	}
+
+	public void addRole(RoleEntity role) {
+		if (roles == null) {
+			roles = new ArrayList<RoleEntity>();
+		}
+		roles.add(role);
+	}
+
+	public Map<String, String> getSmtpConfig() {
+		return smtpConfig;
+	}
+
+	public void setSmtpConfig(Map<String, String> smtpConfig) {
+		this.smtpConfig = smtpConfig;
+	}
+
+	public Collection<RoleEntity> getDefaultRoles() {
+		return defaultRoles;
+	}
+
+	public void setDefaultRoles(Collection<RoleEntity> defaultRoles) {
+		this.defaultRoles = defaultRoles;
+	}
+
+	public String getPasswordPolicy() {
+		return passwordPolicy;
+	}
+
+	public void setPasswordPolicy(String passwordPolicy) {
+		this.passwordPolicy = passwordPolicy;
+	}
 
+	public String getLoginTheme() {
+		return loginTheme;
+	}
+
+	public void setLoginTheme(String theme) {
+		this.loginTheme = theme;
+	}
+
+	public String getAccountTheme() {
+		return accountTheme;
+	}
+
+	public void setAccountTheme(String theme) {
+		this.accountTheme = theme;
+	}
+
+	public String getAdminTheme() {
+		return adminTheme;
+	}
+
+	public void setAdminTheme(String adminTheme) {
+		this.adminTheme = adminTheme;
+	}
+
+	public String getEmailTheme() {
+		return emailTheme;
+	}
+
+	public void setEmailTheme(String emailTheme) {
+		this.emailTheme = emailTheme;
+	}
+
+	public int getNotBefore() {
+		return notBefore;
+	}
+
+	public void setNotBefore(int notBefore) {
+		this.notBefore = notBefore;
+	}
+
+	public boolean isEventsEnabled() {
+		return eventsEnabled;
+	}
+
+	public void setEventsEnabled(boolean eventsEnabled) {
+		this.eventsEnabled = eventsEnabled;
+	}
+
+	public long getEventsExpiration() {
+		return eventsExpiration;
+	}
+
+	public void setEventsExpiration(long eventsExpiration) {
+		this.eventsExpiration = eventsExpiration;
+	}
+
+	public Set<String> getEventsListeners() {
+		return eventsListeners;
+	}
+
+	public void setEventsListeners(Set<String> eventsListeners) {
+		this.eventsListeners = eventsListeners;
+	}
+
+	public ApplicationEntity getMasterAdminApp() {
+		return masterAdminApp;
+	}
+
+	public void setMasterAdminApp(ApplicationEntity masterAdminApp) {
+		this.masterAdminApp = masterAdminApp;
+	}
+
+	public List<UserFederationProviderEntity> getUserFederationProviders() {
+		return userFederationProviders;
+	}
+
+	public void setUserFederationProviders(List<UserFederationProviderEntity> userFederationProviders) {
+		this.userFederationProviders = userFederationProviders;
+	}
+
+	public Collection<RealmAttributeEntity> getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(Collection<RealmAttributeEntity> attributes) {
+		this.attributes = attributes;
+	}
+
+	public String getCertificatePem() {
+		return certificatePem;
+	}
+
+	public void setCertificatePem(String certificatePem) {
+		this.certificatePem = certificatePem;
+	}
+
+	public List<IdentityProviderEntity> getIdentityProviders() {
+		return this.identityProviders;
+	}
+
+	public void setIdentityProviders(List<IdentityProviderEntity> identityProviders) {
+		this.identityProviders = identityProviders;
+	}
+
+	public void addIdentityProvider(IdentityProviderEntity entity) {
+		entity.setRealm(this);
+		getIdentityProviders().add(entity);
+	}
+
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 9c0e751..086256a 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -1,5 +1,24 @@
 package org.keycloak.models.jpa;
 
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
@@ -21,1210 +40,1233 @@ import org.keycloak.models.jpa.entities.RoleEntity;
 import org.keycloak.models.jpa.entities.UserFederationProviderEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
-import javax.persistence.EntityManager;
-import javax.persistence.TypedQuery;
-import java.security.Key;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class RealmAdapter implements RealmModel {
-    protected RealmEntity realm;
-    protected EntityManager em;
-    protected volatile transient PublicKey publicKey;
-    protected volatile transient PrivateKey privateKey;
-    protected volatile transient X509Certificate certificate;
-    protected volatile transient Key codeSecretKey;
-    protected KeycloakSession session;
-    private PasswordPolicy passwordPolicy;
-
-    public RealmAdapter(KeycloakSession session, EntityManager em, RealmEntity realm) {
-        this.session = session;
-        this.em = em;
-        this.realm = realm;
-    }
-
-    public RealmEntity getEntity() {
-        return realm;
-    }
-
-    @Override
-    public String getId() {
-        return realm.getId();
-    }
-
-    @Override
-    public String getName() {
-        return realm.getName();
-    }
-
-    @Override
-    public void setName(String name) {
-        realm.setName(name);
-        em.flush();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return realm.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        realm.setEnabled(enabled);
-        em.flush();
-    }
-
-    @Override
-    public SslRequired getSslRequired() {
-        return realm.getSslRequired() != null ? SslRequired.valueOf(realm.getSslRequired()) : null;
-    }
-
-    @Override
-    public void setSslRequired(SslRequired sslRequired) {
-        realm.setSslRequired(sslRequired.name());
-        em.flush();
-    }
-
-    @Override
-    public boolean isPasswordCredentialGrantAllowed() {
-        return realm.isPasswordCredentialGrantAllowed();
-    }
-
-    @Override
-    public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
-        realm.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
-        em.flush();
-    }
-
-    @Override
-    public boolean isRegistrationAllowed() {
-        return realm.isRegistrationAllowed();
-    }
-
-    @Override
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        realm.setRegistrationAllowed(registrationAllowed);
-        em.flush();
-    }
-
-    @Override
-    public boolean isRememberMe() {
-        return realm.isRememberMe();
-    }
-
-    @Override
-    public void setRememberMe(boolean rememberMe) {
-        realm.setRememberMe(rememberMe);
-        em.flush();
-    }
-
-    public void setAttribute(String name, String value) {
-        for (RealmAttributeEntity attr : realm.getAttributes()) {
-            if (attr.getName().equals(name)) {
-                attr.setValue(value);
-                return;
-            }
-        }
-        RealmAttributeEntity attr = new RealmAttributeEntity();
-        attr.setName(name);
-        attr.setValue(value);
-        attr.setRealm(realm);
-        em.persist(attr);
-        realm.getAttributes().add(attr);
-    }
-
-    public void setAttribute(String name, Boolean value) {
-        setAttribute(name, value.toString());
-    }
-
-    public void setAttribute(String name, Integer value) {
-        setAttribute(name, value.toString());
-    }
-
-    public void setAttribute(String name, Long value) {
-        setAttribute(name, value.toString());
-    }
-
-    public void removeAttribute(String name) {
-        Iterator<RealmAttributeEntity> it = realm.getAttributes().iterator();
-        while (it.hasNext()) {
-            RealmAttributeEntity attr = it.next();
-            if (attr.getName().equals(name)) {
-                it.remove();
-                em.remove(attr);
-            }
-        }
-    }
-
-    public String getAttribute(String name) {
-        for (RealmAttributeEntity attr : realm.getAttributes()) {
-            if (attr.getName().equals(name)) {
-                return attr.getValue();
-            }
-        }
-        return null;
-    }
-
-    public Integer getAttribute(String name, Integer defaultValue) {
-        String v = getAttribute(name);
-        return v != null ? Integer.parseInt(v) : defaultValue;
-
-    }
-
-    public Long getAttribute(String name, Long defaultValue) {
-        String v = getAttribute(name);
-        return v != null ? Long.parseLong(v) : defaultValue;
-
-    }
-
-    public Boolean getAttribute(String name, Boolean defaultValue) {
-        String v = getAttribute(name);
-        return v != null ? Boolean.parseBoolean(v) : defaultValue;
-
-    }
-
-    public Map<String, String> getAttributes() {
-        // should always return a copy
-        Map<String, String> result = new HashMap<String, String>();
-        for (RealmAttributeEntity attr : realm.getAttributes()) {
-            result.put(attr.getName(), attr.getValue());
-        }
-        return result;
-    }
-    @Override
-    public boolean isBruteForceProtected() {
-        return getAttribute("bruteForceProtected", false);
-    }
-
-    @Override
-    public void setBruteForceProtected(boolean value) {
-        setAttribute("bruteForceProtected", value);
-    }
-
-    @Override
-    public int getMaxFailureWaitSeconds() {
-        return getAttribute("maxFailureWaitSeconds", 0);
-    }
-
-    @Override
-    public void setMaxFailureWaitSeconds(int val) {
-        setAttribute("maxFailureWaitSeconds", val);
-    }
-
-    @Override
-    public int getWaitIncrementSeconds() {
-        return getAttribute("waitIncrementSeconds", 0);
-    }
-
-    @Override
-    public void setWaitIncrementSeconds(int val) {
-        setAttribute("waitIncrementSeconds", val);
-    }
-
-    @Override
-    public long getQuickLoginCheckMilliSeconds() {
-        return getAttribute("quickLoginCheckMilliSeconds", 0l);
-    }
-
-    @Override
-    public void setQuickLoginCheckMilliSeconds(long val) {
-        setAttribute("quickLoginCheckMilliSeconds", val);
-    }
-
-    @Override
-    public int getMinimumQuickLoginWaitSeconds() {
-        return getAttribute("minimumQuickLoginWaitSeconds", 0);
-    }
-
-    @Override
-    public void setMinimumQuickLoginWaitSeconds(int val) {
-        setAttribute("minimumQuickLoginWaitSeconds", val);
-    }
-
-    @Override
-    public int getMaxDeltaTimeSeconds() {
-        return getAttribute("maxDeltaTimeSeconds", 0);
-    }
-
-    @Override
-    public void setMaxDeltaTimeSeconds(int val) {
-        setAttribute("maxDeltaTimeSeconds", val);
-    }
-
-    @Override
-    public int getFailureFactor() {
-        return getAttribute("failureFactor", 0);
-    }
-
-    @Override
-    public void setFailureFactor(int failureFactor) {
-        setAttribute("failureFactor", failureFactor);
-    }
-
-    @Override
-    public boolean isVerifyEmail() {
-        return realm.isVerifyEmail();
-    }
-
-    @Override
-    public void setVerifyEmail(boolean verifyEmail) {
-        realm.setVerifyEmail(verifyEmail);
-        em.flush();
-    }
-
-    @Override
-    public boolean isResetPasswordAllowed() {
-        return realm.isResetPasswordAllowed();
-    }
-
-    @Override
-    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
-        realm.setResetPasswordAllowed(resetPasswordAllowed);
-        em.flush();
-    }
-
-    @Override
-    public int getNotBefore() {
-        return realm.getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        realm.setNotBefore(notBefore);
-    }
-
-    @Override
-    public int getAccessTokenLifespan() {
-        return realm.getAccessTokenLifespan();
-    }
-
-    @Override
-    public void setAccessTokenLifespan(int tokenLifespan) {
-        realm.setAccessTokenLifespan(tokenLifespan);
-        em.flush();
-    }
-
-    @Override
-    public int getSsoSessionIdleTimeout() {
-        return realm.getSsoSessionIdleTimeout();
-    }
-
-    @Override
-    public void setSsoSessionIdleTimeout(int seconds) {
-        realm.setSsoSessionIdleTimeout(seconds);
-    }
-
-    @Override
-    public int getSsoSessionMaxLifespan() {
-        return realm.getSsoSessionMaxLifespan();
-    }
-
-    @Override
-    public void setSsoSessionMaxLifespan(int seconds) {
-        realm.setSsoSessionMaxLifespan(seconds);
-    }
-
-    @Override
-    public int getAccessCodeLifespan() {
-        return realm.getAccessCodeLifespan();
-    }
-
-    @Override
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        realm.setAccessCodeLifespan(accessCodeLifespan);
-        em.flush();
-    }
-
-    @Override
-    public int getAccessCodeLifespanUserAction() {
-        return realm.getAccessCodeLifespanUserAction();
-    }
-
-    @Override
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
-        em.flush();
-    }
-
-    @Override
-    public int getAccessCodeLifespanLogin() {
-        return realm.getAccessCodeLifespanLogin();
-    }
-
-    @Override
-    public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
-        realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
-        em.flush();
-    }
-
-    @Override
-    public String getPublicKeyPem() {
-        return realm.getPublicKeyPem();
-    }
-
-    @Override
-    public void setPublicKeyPem(String publicKeyPem) {
-        realm.setPublicKeyPem(publicKeyPem);
-        em.flush();
-    }
-
-    @Override
-    public X509Certificate getCertificate() {
-        if (certificate != null) return certificate;
-        certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
-        return certificate;
-    }
-
-    @Override
-    public void setCertificate(X509Certificate certificate) {
-        this.certificate = certificate;
-        String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
-        setCertificatePem(certificatePem);
-
-    }
-
-    @Override
-    public String getCertificatePem() {
-        return realm.getCertificatePem();
-    }
-
-    @Override
-    public void setCertificatePem(String certificate) {
-        realm.setCertificatePem(certificate);
-
-    }
-
-    @Override
-    public String getPrivateKeyPem() {
-        return realm.getPrivateKeyPem();
-    }
-
-    @Override
-    public void setPrivateKeyPem(String privateKeyPem) {
-        realm.setPrivateKeyPem(privateKeyPem);
-        em.flush();
-    }
-
-    @Override
-    public PublicKey getPublicKey() {
-        if (publicKey != null) return publicKey;
-        publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
-        return publicKey;
-    }
-
-    @Override
-    public void setPublicKey(PublicKey publicKey) {
-        this.publicKey = publicKey;
-        String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
-        setPublicKeyPem(publicKeyPem);
-    }
-
-    @Override
-    public PrivateKey getPrivateKey() {
-        if (privateKey != null) return privateKey;
-        privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
-        return privateKey;
-    }
-
-    @Override
-    public void setPrivateKey(PrivateKey privateKey) {
-        this.privateKey = privateKey;
-        String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
-        setPrivateKeyPem(privateKeyPem);
-    }
-
-    @Override
-    public String getCodeSecret() {
-        return realm.getCodeSecret();
-    }
-
-    @Override
-    public Key getCodeSecretKey() {
-        if (codeSecretKey == null) {
-            codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
-        }
-        return codeSecretKey;
-    }
-
-    @Override
-    public void setCodeSecret(String codeSecret) {
-        realm.setCodeSecret(codeSecret);
-    }
-
-    protected RequiredCredentialModel initRequiredCredentialModel(String type) {
-        RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
-        if (model == null) {
-            throw new RuntimeException("Unknown credential type " + type);
-        }
-        return model;
-    }
-
-    @Override
-    public void addRequiredCredential(String type) {
-        RequiredCredentialModel model = initRequiredCredentialModel(type);
-        addRequiredCredential(model);
-        em.flush();
-    }
-
-    public void addRequiredCredential(RequiredCredentialModel model) {
-        RequiredCredentialEntity entity = new RequiredCredentialEntity();
-        entity.setRealm(realm);
-        entity.setInput(model.isInput());
-        entity.setSecret(model.isSecret());
-        entity.setType(model.getType());
-        entity.setFormLabel(model.getFormLabel());
-        em.persist(entity);
-        realm.getRequiredCredentials().add(entity);
-        em.flush();
-    }
-
-    @Override
-    public void updateRequiredCredentials(Set<String> creds) {
-        Collection<RequiredCredentialEntity> relationships = realm.getRequiredCredentials();
-        if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
-
-        Set<String> already = new HashSet<String>();
-        List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
-        for (RequiredCredentialEntity rel : relationships) {
-            if (!creds.contains(rel.getType())) {
-                remove.add(rel);
-            } else {
-                already.add(rel.getType());
-            }
-        }
-        for (RequiredCredentialEntity entity : remove) {
-            relationships.remove(entity);
-            em.remove(entity);
-        }
-        for (String cred : creds) {
-            if (!already.contains(cred)) {
-                addRequiredCredential(cred);
-            }
-        }
-        em.flush();
-    }
-
-
-    @Override
-    public List<RequiredCredentialModel> getRequiredCredentials() {
-        List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
-        Collection<RequiredCredentialEntity> entities = realm.getRequiredCredentials();
-        if (entities == null) return requiredCredentialModels;
-        for (RequiredCredentialEntity entity : entities) {
-            RequiredCredentialModel model = new RequiredCredentialModel();
-            model.setFormLabel(entity.getFormLabel());
-            model.setType(entity.getType());
-            model.setSecret(entity.isSecret());
-            model.setInput(entity.isInput());
-            requiredCredentialModels.add(model);
-        }
-        return requiredCredentialModels;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-
-    @Override
-    public List<String> getDefaultRoles() {
-        Collection<RoleEntity> entities = realm.getDefaultRoles();
-        List<String> roles = new ArrayList<String>();
-        if (entities == null) return roles;
-        for (RoleEntity entity : entities) {
-            roles.add(entity.getName());
-        }
-        return roles;
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        RoleModel role = getRole(name);
-        if (role == null) {
-            role = addRole(name);
-        }
-        Collection<RoleEntity> entities = realm.getDefaultRoles();
-        for (RoleEntity entity : entities) {
-            if (entity.getId().equals(role.getId())) {
-                return;
-            }
-        }
-        RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
-        entities.add(roleEntity);
-        em.flush();
-    }
-
-    public static boolean contains(String str, String[] array) {
-        for (String s : array) {
-            if (str.equals(s)) return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        Collection<RoleEntity> entities = realm.getDefaultRoles();
-        Set<String> already = new HashSet<String>();
-        List<RoleEntity> remove = new ArrayList<RoleEntity>();
-        for (RoleEntity rel : entities) {
-            if (!contains(rel.getName(), defaultRoles)) {
-                remove.add(rel);
-            } else {
-                already.add(rel.getName());
-            }
-        }
-        for (RoleEntity entity : remove) {
-            entities.remove(entity);
-        }
-        em.flush();
-        for (String roleName : defaultRoles) {
-            if (!already.contains(roleName)) {
-                addDefaultRole(roleName);
-            }
-        }
-        em.flush();
-    }
-
-    @Override
-    public ClientModel findClient(String clientId) {
-        ClientModel model = getApplicationByName(clientId);
-        if (model != null) return model;
-        return getOAuthClient(clientId);
-    }
-
-    @Override
-    public ClientModel findClientById(String id) {
-        ClientModel model = getApplicationById(id);
-        if (model != null) return model;
-        return getOAuthClientById(id);
-    }
-
-    @Override
-    public Map<String, ApplicationModel> getApplicationNameMap() {
-        Map<String, ApplicationModel> map = new HashMap<String, ApplicationModel>();
-        for (ApplicationModel app : getApplications()) {
-            map.put(app.getName(), app);
-        }
-        return map;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public List<ApplicationModel> getApplications() {
-        List<ApplicationModel> list = new ArrayList<ApplicationModel>();
-        if (realm.getApplications() == null) return list;
-        for (ApplicationEntity entity : realm.getApplications()) {
-            list.add(new ApplicationAdapter(this, em, session, entity));
-        }
-        return list;
-    }
-
-    @Override
-    public ApplicationModel addApplication(String name) {
-        return this.addApplication(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public ApplicationModel addApplication(String id, String name) {
-        ApplicationEntity applicationData = new ApplicationEntity();
-        applicationData.setId(id);
-        applicationData.setName(name);
-        applicationData.setEnabled(true);
-        applicationData.setRealm(realm);
-        realm.getApplications().add(applicationData);
-        em.persist(applicationData);
-        em.flush();
-        final ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
-        em.flush();
-        session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
-            @Override
-            public ApplicationModel getCreatedApplication() {
-                return resource;
-            }
-
-            @Override
-            public ClientModel getCreatedClient() {
-                return resource;
-            }
-        });
-        return resource;
-    }
-
-    @Override
-    public boolean removeApplication(String id) {
-        if (id == null) return false;
-        ApplicationModel application = getApplicationById(id);
-        if (application == null) return false;
-
-        for (RoleModel role : application.getRoles()) {
-            application.removeRole(role);
-        }
-
-        ApplicationEntity applicationEntity = null;
-        Iterator<ApplicationEntity> it = realm.getApplications().iterator();
-        while (it.hasNext()) {
-            ApplicationEntity ae = it.next();
-            if (ae.getId().equals(id)) {
-                applicationEntity = ae;
-                it.remove();
-                break;
-            }
-        }
-        for (ApplicationEntity a : realm.getApplications()) {
-            if (a.getId().equals(id)) {
-                applicationEntity = a;
-            }
-        }
-        if (application == null) {
-            return false;
-        }
-        em.remove(applicationEntity);
-        em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", applicationEntity).executeUpdate();
-        em.flush();
-
-        return true;
-    }
-
-    @Override
-    public ApplicationModel getApplicationById(String id) {
-        return session.realms().getApplicationById(id, this);
-    }
-
-    @Override
-    public ApplicationModel getApplicationByName(String name) {
-        return getApplicationNameMap().get(name);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String name) {
-        return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String id, String name) {
-        OAuthClientEntity data = new OAuthClientEntity();
-        data.setId(id);
-        data.setEnabled(true);
-        data.setName(name);
-        data.setRealm(realm);
-        em.persist(data);
-        em.flush();
-        final OAuthClientModel model = new OAuthClientAdapter(this, data, em);
-        em.flush();
-        session.getKeycloakSessionFactory().publish(new OAuthClientCreationEvent() {
-            @Override
-            public OAuthClientModel getCreatedOAuthClient() {
-                return model;
-            }
-
-            @Override
-            public ClientModel getCreatedClient() {
-                return model;
-            }
-        });
-        return model;
-    }
-
-    @Override
-    public boolean removeOAuthClient(String id) {
-        OAuthClientModel oauth = getOAuthClientById(id);
-        if (oauth == null) return false;
-        OAuthClientEntity client = em.getReference(OAuthClientEntity.class, oauth.getId());
-        em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", client).executeUpdate();
-        em.remove(client);
-        return true;
-    }
-
-
-    @Override
-    public OAuthClientModel getOAuthClient(String name) {
-        TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByName", OAuthClientEntity.class);
-        query.setParameter("name", name);
-        query.setParameter("realm", realm);
-        List<OAuthClientEntity> entities = query.getResultList();
-        if (entities.size() == 0) return null;
-        return new OAuthClientAdapter(this, entities.get(0), em);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id) {
-        return session.realms().getOAuthClientById(id, this);
-    }
-
-
-    @Override
-    public List<OAuthClientModel> getOAuthClients() {
-        TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByRealm", OAuthClientEntity.class);
-        query.setParameter("realm", realm);
-        List<OAuthClientEntity> entities = query.getResultList();
-        List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
-        for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(this, entity, em));
-        return list;
-    }
-
-    private static final String BROWSER_HEADER_PREFIX = "_browser_header.";
-
-    @Override
-    public Map<String, String> getBrowserSecurityHeaders() {
-        Map<String, String> attributes = getAttributes();
-        Map<String, String> headers = new HashMap<String, String>();
-        for (Map.Entry<String, String> entry : attributes.entrySet()) {
-            if (entry.getKey().startsWith(BROWSER_HEADER_PREFIX)) {
-                headers.put(entry.getKey().substring(BROWSER_HEADER_PREFIX.length()), entry.getValue());
-            }
-        }
-        return headers;
-    }
-
-    @Override
-    public void setBrowserSecurityHeaders(Map<String, String> headers) {
-        for (Map.Entry<String, String> entry : headers.entrySet()) {
-            setAttribute(BROWSER_HEADER_PREFIX + entry.getKey(), entry.getValue());
-        }
-    }
-
-    @Override
-    public Map<String, String> getSmtpConfig() {
-        return realm.getSmtpConfig();
-    }
-
-    @Override
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        realm.setSmtpConfig(smtpConfig);
-        em.flush();
-    }
-
-    @Override
-    public List<UserFederationProviderModel> getUserFederationProviders() {
-        List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();
-        List<UserFederationProviderEntity> copy = new ArrayList<UserFederationProviderEntity>();
-        for (UserFederationProviderEntity entity : entities) {
-            copy.add(entity);
-
-        }
-        Collections.sort(copy, new Comparator<UserFederationProviderEntity>() {
-
-            @Override
-            public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) {
-                return o1.getPriority() - o2.getPriority();
-            }
-
-        });
-        List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
-        for (UserFederationProviderEntity entity : copy) {
-            result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
-                    entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-        }
-
-        return result;
-    }
-
-    @Override
-    public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
-        String id = KeycloakModelUtils.generateId();
-        UserFederationProviderEntity entity = new UserFederationProviderEntity();
-        entity.setId(id);
-        entity.setRealm(realm);
-        entity.setProviderName(providerName);
-        entity.setConfig(config);
-        entity.setPriority(priority);
-        if (displayName == null) {
-            displayName = id;
-        }
-        entity.setDisplayName(displayName);
-        entity.setFullSyncPeriod(fullSyncPeriod);
-        entity.setChangedSyncPeriod(changedSyncPeriod);
-        entity.setLastSync(lastSync);
-        em.persist(entity);
-        realm.getUserFederationProviders().add(entity);
-        em.flush();
-        return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
-    }
-
-    @Override
-    public void removeUserFederationProvider(UserFederationProviderModel provider) {
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            if (entity.getId().equals(provider.getId())) {
-                session.users().preRemove(this, provider);
-                it.remove();
-                em.remove(entity);
-                return;
-            }
-        }
-    }
-    @Override
-    public void updateUserFederationProvider(UserFederationProviderModel model) {
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            if (entity.getId().equals(model.getId())) {
-                String displayName = model.getDisplayName();
-                if (displayName != null) {
-                    entity.setDisplayName(model.getDisplayName());
-                }
-                entity.setConfig(model.getConfig());
-                entity.setPriority(model.getPriority());
-                entity.setProviderName(model.getProviderName());
-                entity.setPriority(model.getPriority());
-                entity.setFullSyncPeriod(model.getFullSyncPeriod());
-                entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-                entity.setLastSync(model.getLastSync());
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
-
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            boolean found = false;
-            for (UserFederationProviderModel model : providers) {
-                if (entity.getId().equals(model.getId())) {
-                    entity.setConfig(model.getConfig());
-                    entity.setPriority(model.getPriority());
-                    entity.setProviderName(model.getProviderName());
-                    entity.setPriority(model.getPriority());
-                    String displayName = model.getDisplayName();
-                    if (displayName != null) {
-                        entity.setDisplayName(model.getDisplayName());
-                    }
-                    entity.setFullSyncPeriod(model.getFullSyncPeriod());
-                    entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-                    entity.setLastSync(model.getLastSync());
-                    found = true;
-                    break;
-                }
-
-            }
-            if (found) continue;
-            session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
-                    entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-            it.remove();
-            em.remove(entity);
-        }
-
-        List<UserFederationProviderModel> add = new LinkedList<UserFederationProviderModel>();
-        for (UserFederationProviderModel model : providers) {
-            boolean found = false;
-            for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) {
-                if (entity.getId().equals(model.getId())) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) add.add(model);
-        }
-
-        for (UserFederationProviderModel model : add) {
-            UserFederationProviderEntity entity = new UserFederationProviderEntity();
-            if (model.getId() != null) entity.setId(model.getId());
-            else entity.setId(KeycloakModelUtils.generateId());
-            entity.setConfig(model.getConfig());
-            entity.setPriority(model.getPriority());
-            entity.setProviderName(model.getProviderName());
-            entity.setPriority(model.getPriority());
-            String displayName = model.getDisplayName();
-            if (displayName == null) {
-                displayName = entity.getId();
-            }
-            entity.setDisplayName(displayName);
-            entity.setFullSyncPeriod(model.getFullSyncPeriod());
-            entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-            entity.setLastSync(model.getLastSync());
-            em.persist(entity);
-            realm.getUserFederationProviders().add(entity);
-
-        }
-    }
-
-    @Override
-    public RoleModel getRole(String name) {
-        TypedQuery<RoleEntity> query = em.createNamedQuery("getRealmRoleByName", RoleEntity.class);
-        query.setParameter("name", name);
-        query.setParameter("realm", realm);
-        List<RoleEntity> roles = query.getResultList();
-        if (roles.size() == 0) return null;
-        return new RoleAdapter(this, em, roles.get(0));
-    }
-
-    @Override
-    public RoleModel addRole(String name) {
-        return this.addRole(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public RoleModel addRole(String id, String name) {
-        RoleEntity entity = new RoleEntity();
-        entity.setId(id);
-        entity.setName(name);
-        entity.setRealm(realm);
-        entity.setRealmId(realm.getId());
-        realm.getRoles().add(entity);
-        em.persist(entity);
-        em.flush();
-        return new RoleAdapter(this, em, entity);
-    }
-
-    @Override
-    public boolean removeRole(RoleModel role) {
-        if (role == null) {
-            return false;
-        }
-        if (!role.getContainer().equals(this)) return false;
-        session.users().preRemove(this, role);
-        RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
-        realm.getRoles().remove(role);
-        realm.getDefaultRoles().remove(role);
-
-        em.createNativeQuery("delete from COMPOSITE_ROLE where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
-        em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
-
-        em.remove(roleEntity);
-
-        return true;
-    }
-
-    @Override
-    public Set<RoleModel> getRoles() {
-        Set<RoleModel> list = new HashSet<RoleModel>();
-        Collection<RoleEntity> roles = realm.getRoles();
-        if (roles == null) return list;
-        for (RoleEntity entity : roles) {
-            list.add(new RoleAdapter(this, em, entity));
-        }
-        return list;
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        return session.realms().getRoleById(id, this);
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        RoleModel role = getRoleById(id);
-        if (role == null) return false;
-        return role.getContainer().removeRole(role);
-    }
-
-    @Override
-    public PasswordPolicy getPasswordPolicy() {
-        if (passwordPolicy == null) {
-            passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
-        }
-        return passwordPolicy;
-    }
-
-    @Override
-    public void setPasswordPolicy(PasswordPolicy policy) {
-        this.passwordPolicy = policy;
-        realm.setPasswordPolicy(policy.toString());
-        em.flush();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || !(o instanceof RealmModel)) return false;
-
-        RealmModel that = (RealmModel) o;
-        return that.getId().equals(getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return getId().hashCode();
-    }
-
-    @Override
-    public String getLoginTheme() {
-        return realm.getLoginTheme();
-    }
-
-    @Override
-    public void setLoginTheme(String name) {
-        realm.setLoginTheme(name);
-        em.flush();
-    }
-
-    @Override
-    public String getAccountTheme() {
-        return realm.getAccountTheme();
-    }
-
-    @Override
-    public void setAccountTheme(String name) {
-        realm.setAccountTheme(name);
-        em.flush();
-    }
-
-    @Override
-    public String getAdminTheme() {
-        return realm.getAdminTheme();
-    }
-
-    @Override
-    public void setAdminTheme(String name) {
-        realm.setAdminTheme(name);
-        em.flush();
-    }
-
-    @Override
-    public String getEmailTheme() {
-        return realm.getEmailTheme();
-    }
-
-    @Override
-    public void setEmailTheme(String name) {
-        realm.setEmailTheme(name);
-        em.flush();
-    }
-
-    @Override
-    public boolean isEventsEnabled() {
-        return realm.isEventsEnabled();
-    }
-
-    @Override
-    public void setEventsEnabled(boolean enabled) {
-        realm.setEventsEnabled(enabled);
-        em.flush();
-    }
-
-    @Override
-    public long getEventsExpiration() {
-        return realm.getEventsExpiration();
-    }
-
-    @Override
-    public void setEventsExpiration(long expiration) {
-        realm.setEventsExpiration(expiration);
-        em.flush();
-    }
-
-    @Override
-    public Set<String> getEventsListeners() {
-        return realm.getEventsListeners();
-    }
-
-    @Override
-    public void setEventsListeners(Set<String> listeners) {
-        realm.setEventsListeners(listeners);
-        em.flush();
-    }
-
-    @Override
-    public ApplicationModel getMasterAdminApp() {
-        return new ApplicationAdapter(this, em, session, realm.getMasterAdminApp());
-    }
-
-    @Override
-    public void setMasterAdminApp(ApplicationModel app) {
-        ApplicationEntity appEntity = app!=null ? em.getReference(ApplicationEntity.class, app.getId()) : null;
-        realm.setMasterAdminApp(appEntity);
-        em.flush();
-    }
-
-    @Override
-    public List<IdentityProviderModel> getIdentityProviders() {
-        List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
-
-        for (IdentityProviderEntity entity: realm.getIdentityProviders()) {
-            IdentityProviderModel identityProviderModel = new IdentityProviderModel();
-
-            identityProviderModel.setProviderId(entity.getProviderId());
-            identityProviderModel.setId(entity.getId());
-            identityProviderModel.setInternalId(entity.getInternalId());
-            identityProviderModel.setName(entity.getName());
-            identityProviderModel.setConfig(entity.getConfig());
-            identityProviderModel.setEnabled(entity.isEnabled());
-            identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
-            identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
-            identityProviderModel.setStoreToken(entity.isStoreToken());
-
-            identityProviders.add(identityProviderModel);
-        }
-
-        return identityProviders;
-    }
-
-    @Override
-    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
-        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
-            if (identityProviderModel.getId().equals(identityProviderId)) {
-                return identityProviderModel;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public void addIdentityProvider(IdentityProviderModel identityProvider) {
-        IdentityProviderEntity entity = new IdentityProviderEntity();
-
-        entity.setInternalId(KeycloakModelUtils.generateId());
-        entity.setId(identityProvider.getId());
-        entity.setProviderId(identityProvider.getProviderId());
-        entity.setName(identityProvider.getName());
-        entity.setEnabled(identityProvider.isEnabled());
-        entity.setStoreToken(identityProvider.isStoreToken());
-        entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
-        entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
-        entity.setConfig(identityProvider.getConfig());
-
-        realm.addIdentityProvider(entity);
-
-        em.persist(entity);
-        em.flush();
-    }
-
-    @Override
-    public void removeIdentityProviderById(String providerId) {
-        for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
-            if (entity.getId().equals(providerId)) {
-                em.remove(entity);
-                em.flush();
-            }
-        }
-    }
-
-    @Override
-    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
-        for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
-            if (entity.getInternalId().equals(identityProvider.getInternalId())) {
-                entity.setId(identityProvider.getId());
-                entity.setName(identityProvider.getName());
-                entity.setEnabled(identityProvider.isEnabled());
-                entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
-                entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
-                entity.setStoreToken(identityProvider.isStoreToken());
-                entity.setConfig(identityProvider.getConfig());
-            }
-        }
-
-        em.flush();
-    }
-
-    @Override
-    public boolean isIdentityFederationEnabled() {
-        return !this.realm.getIdentityProviders().isEmpty();
-    }
+	protected RealmEntity realm;
+	protected EntityManager em;
+	protected volatile transient PublicKey publicKey;
+	protected volatile transient PrivateKey privateKey;
+	protected volatile transient X509Certificate certificate;
+	protected volatile transient Key codeSecretKey;
+	protected KeycloakSession session;
+	private PasswordPolicy passwordPolicy;
+
+	public RealmAdapter(KeycloakSession session, EntityManager em, RealmEntity realm) {
+		this.session = session;
+		this.em = em;
+		this.realm = realm;
+	}
+
+	public RealmEntity getEntity() {
+		return realm;
+	}
+
+	@Override
+	public String getId() {
+		return realm.getId();
+	}
+
+	@Override
+	public String getName() {
+		return realm.getName();
+	}
+
+	@Override
+	public void setName(String name) {
+		realm.setName(name);
+		em.flush();
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return realm.isEnabled();
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		realm.setEnabled(enabled);
+		em.flush();
+	}
+
+	@Override
+	public SslRequired getSslRequired() {
+		return realm.getSslRequired() != null ? SslRequired.valueOf(realm.getSslRequired()) : null;
+	}
+
+	@Override
+	public void setSslRequired(SslRequired sslRequired) {
+		realm.setSslRequired(sslRequired.name());
+		em.flush();
+	}
+
+	@Override
+	public boolean isPasswordCredentialGrantAllowed() {
+		return realm.isPasswordCredentialGrantAllowed();
+	}
+
+	@Override
+	public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
+		realm.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
+		em.flush();
+	}
+
+	@Override
+	public boolean isRegistrationAllowed() {
+		return realm.isRegistrationAllowed();
+	}
+
+	@Override
+	public void setRegistrationAllowed(boolean registrationAllowed) {
+		realm.setRegistrationAllowed(registrationAllowed);
+		em.flush();
+	}
+
+	@Override
+	public boolean isRegistrationEmailAsUsername() {
+		return realm.isRegistrationEmailAsUsername();
+	}
+
+	@Override
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		realm.setRegistrationEmailAsUsername(registrationEmailAsUsername);
+		em.flush();
+	}
+
+	@Override
+	public boolean isRememberMe() {
+		return realm.isRememberMe();
+	}
+
+	@Override
+	public void setRememberMe(boolean rememberMe) {
+		realm.setRememberMe(rememberMe);
+		em.flush();
+	}
+
+	public void setAttribute(String name, String value) {
+		for (RealmAttributeEntity attr : realm.getAttributes()) {
+			if (attr.getName().equals(name)) {
+				attr.setValue(value);
+				return;
+			}
+		}
+		RealmAttributeEntity attr = new RealmAttributeEntity();
+		attr.setName(name);
+		attr.setValue(value);
+		attr.setRealm(realm);
+		em.persist(attr);
+		realm.getAttributes().add(attr);
+	}
+
+	public void setAttribute(String name, Boolean value) {
+		setAttribute(name, value.toString());
+	}
+
+	public void setAttribute(String name, Integer value) {
+		setAttribute(name, value.toString());
+	}
+
+	public void setAttribute(String name, Long value) {
+		setAttribute(name, value.toString());
+	}
+
+	public void removeAttribute(String name) {
+		Iterator<RealmAttributeEntity> it = realm.getAttributes().iterator();
+		while (it.hasNext()) {
+			RealmAttributeEntity attr = it.next();
+			if (attr.getName().equals(name)) {
+				it.remove();
+				em.remove(attr);
+			}
+		}
+	}
+
+	public String getAttribute(String name) {
+		for (RealmAttributeEntity attr : realm.getAttributes()) {
+			if (attr.getName().equals(name)) {
+				return attr.getValue();
+			}
+		}
+		return null;
+	}
+
+	public Integer getAttribute(String name, Integer defaultValue) {
+		String v = getAttribute(name);
+		return v != null ? Integer.parseInt(v) : defaultValue;
+
+	}
+
+	public Long getAttribute(String name, Long defaultValue) {
+		String v = getAttribute(name);
+		return v != null ? Long.parseLong(v) : defaultValue;
+
+	}
+
+	public Boolean getAttribute(String name, Boolean defaultValue) {
+		String v = getAttribute(name);
+		return v != null ? Boolean.parseBoolean(v) : defaultValue;
+
+	}
+
+	public Map<String, String> getAttributes() {
+		// should always return a copy
+		Map<String, String> result = new HashMap<String, String>();
+		for (RealmAttributeEntity attr : realm.getAttributes()) {
+			result.put(attr.getName(), attr.getValue());
+		}
+		return result;
+	}
+
+	@Override
+	public boolean isBruteForceProtected() {
+		return getAttribute("bruteForceProtected", false);
+	}
+
+	@Override
+	public void setBruteForceProtected(boolean value) {
+		setAttribute("bruteForceProtected", value);
+	}
+
+	@Override
+	public int getMaxFailureWaitSeconds() {
+		return getAttribute("maxFailureWaitSeconds", 0);
+	}
+
+	@Override
+	public void setMaxFailureWaitSeconds(int val) {
+		setAttribute("maxFailureWaitSeconds", val);
+	}
+
+	@Override
+	public int getWaitIncrementSeconds() {
+		return getAttribute("waitIncrementSeconds", 0);
+	}
+
+	@Override
+	public void setWaitIncrementSeconds(int val) {
+		setAttribute("waitIncrementSeconds", val);
+	}
+
+	@Override
+	public long getQuickLoginCheckMilliSeconds() {
+		return getAttribute("quickLoginCheckMilliSeconds", 0l);
+	}
+
+	@Override
+	public void setQuickLoginCheckMilliSeconds(long val) {
+		setAttribute("quickLoginCheckMilliSeconds", val);
+	}
+
+	@Override
+	public int getMinimumQuickLoginWaitSeconds() {
+		return getAttribute("minimumQuickLoginWaitSeconds", 0);
+	}
+
+	@Override
+	public void setMinimumQuickLoginWaitSeconds(int val) {
+		setAttribute("minimumQuickLoginWaitSeconds", val);
+	}
+
+	@Override
+	public int getMaxDeltaTimeSeconds() {
+		return getAttribute("maxDeltaTimeSeconds", 0);
+	}
+
+	@Override
+	public void setMaxDeltaTimeSeconds(int val) {
+		setAttribute("maxDeltaTimeSeconds", val);
+	}
+
+	@Override
+	public int getFailureFactor() {
+		return getAttribute("failureFactor", 0);
+	}
+
+	@Override
+	public void setFailureFactor(int failureFactor) {
+		setAttribute("failureFactor", failureFactor);
+	}
+
+	@Override
+	public boolean isVerifyEmail() {
+		return realm.isVerifyEmail();
+	}
+
+	@Override
+	public void setVerifyEmail(boolean verifyEmail) {
+		realm.setVerifyEmail(verifyEmail);
+		em.flush();
+	}
+
+	@Override
+	public boolean isResetPasswordAllowed() {
+		return realm.isResetPasswordAllowed();
+	}
+
+	@Override
+	public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+		realm.setResetPasswordAllowed(resetPasswordAllowed);
+		em.flush();
+	}
+
+	@Override
+	public int getNotBefore() {
+		return realm.getNotBefore();
+	}
+
+	@Override
+	public void setNotBefore(int notBefore) {
+		realm.setNotBefore(notBefore);
+	}
+
+	@Override
+	public int getAccessTokenLifespan() {
+		return realm.getAccessTokenLifespan();
+	}
+
+	@Override
+	public void setAccessTokenLifespan(int tokenLifespan) {
+		realm.setAccessTokenLifespan(tokenLifespan);
+		em.flush();
+	}
+
+	@Override
+	public int getSsoSessionIdleTimeout() {
+		return realm.getSsoSessionIdleTimeout();
+	}
+
+	@Override
+	public void setSsoSessionIdleTimeout(int seconds) {
+		realm.setSsoSessionIdleTimeout(seconds);
+	}
+
+	@Override
+	public int getSsoSessionMaxLifespan() {
+		return realm.getSsoSessionMaxLifespan();
+	}
+
+	@Override
+	public void setSsoSessionMaxLifespan(int seconds) {
+		realm.setSsoSessionMaxLifespan(seconds);
+	}
+
+	@Override
+	public int getAccessCodeLifespan() {
+		return realm.getAccessCodeLifespan();
+	}
+
+	@Override
+	public void setAccessCodeLifespan(int accessCodeLifespan) {
+		realm.setAccessCodeLifespan(accessCodeLifespan);
+		em.flush();
+	}
+
+	@Override
+	public int getAccessCodeLifespanUserAction() {
+		return realm.getAccessCodeLifespanUserAction();
+	}
+
+	@Override
+	public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+		realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
+		em.flush();
+	}
+
+	@Override
+	public int getAccessCodeLifespanLogin() {
+		return realm.getAccessCodeLifespanLogin();
+	}
+
+	@Override
+	public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
+		realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
+		em.flush();
+	}
+
+	@Override
+	public String getPublicKeyPem() {
+		return realm.getPublicKeyPem();
+	}
+
+	@Override
+	public void setPublicKeyPem(String publicKeyPem) {
+		realm.setPublicKeyPem(publicKeyPem);
+		em.flush();
+	}
+
+	@Override
+	public X509Certificate getCertificate() {
+		if (certificate != null)
+			return certificate;
+		certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
+		return certificate;
+	}
+
+	@Override
+	public void setCertificate(X509Certificate certificate) {
+		this.certificate = certificate;
+		String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
+		setCertificatePem(certificatePem);
+
+	}
+
+	@Override
+	public String getCertificatePem() {
+		return realm.getCertificatePem();
+	}
+
+	@Override
+	public void setCertificatePem(String certificate) {
+		realm.setCertificatePem(certificate);
+
+	}
+
+	@Override
+	public String getPrivateKeyPem() {
+		return realm.getPrivateKeyPem();
+	}
+
+	@Override
+	public void setPrivateKeyPem(String privateKeyPem) {
+		realm.setPrivateKeyPem(privateKeyPem);
+		em.flush();
+	}
+
+	@Override
+	public PublicKey getPublicKey() {
+		if (publicKey != null)
+			return publicKey;
+		publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
+		return publicKey;
+	}
+
+	@Override
+	public void setPublicKey(PublicKey publicKey) {
+		this.publicKey = publicKey;
+		String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
+		setPublicKeyPem(publicKeyPem);
+	}
+
+	@Override
+	public PrivateKey getPrivateKey() {
+		if (privateKey != null)
+			return privateKey;
+		privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
+		return privateKey;
+	}
+
+	@Override
+	public void setPrivateKey(PrivateKey privateKey) {
+		this.privateKey = privateKey;
+		String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
+		setPrivateKeyPem(privateKeyPem);
+	}
+
+	@Override
+	public String getCodeSecret() {
+		return realm.getCodeSecret();
+	}
+
+	@Override
+	public Key getCodeSecretKey() {
+		if (codeSecretKey == null) {
+			codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
+		}
+		return codeSecretKey;
+	}
+
+	@Override
+	public void setCodeSecret(String codeSecret) {
+		realm.setCodeSecret(codeSecret);
+	}
+
+	protected RequiredCredentialModel initRequiredCredentialModel(String type) {
+		RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
+		if (model == null) {
+			throw new RuntimeException("Unknown credential type " + type);
+		}
+		return model;
+	}
+
+	@Override
+	public void addRequiredCredential(String type) {
+		RequiredCredentialModel model = initRequiredCredentialModel(type);
+		addRequiredCredential(model);
+		em.flush();
+	}
+
+	public void addRequiredCredential(RequiredCredentialModel model) {
+		RequiredCredentialEntity entity = new RequiredCredentialEntity();
+		entity.setRealm(realm);
+		entity.setInput(model.isInput());
+		entity.setSecret(model.isSecret());
+		entity.setType(model.getType());
+		entity.setFormLabel(model.getFormLabel());
+		em.persist(entity);
+		realm.getRequiredCredentials().add(entity);
+		em.flush();
+	}
+
+	@Override
+	public void updateRequiredCredentials(Set<String> creds) {
+		Collection<RequiredCredentialEntity> relationships = realm.getRequiredCredentials();
+		if (relationships == null)
+			relationships = new ArrayList<RequiredCredentialEntity>();
+
+		Set<String> already = new HashSet<String>();
+		List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
+		for (RequiredCredentialEntity rel : relationships) {
+			if (!creds.contains(rel.getType())) {
+				remove.add(rel);
+			} else {
+				already.add(rel.getType());
+			}
+		}
+		for (RequiredCredentialEntity entity : remove) {
+			relationships.remove(entity);
+			em.remove(entity);
+		}
+		for (String cred : creds) {
+			if (!already.contains(cred)) {
+				addRequiredCredential(cred);
+			}
+		}
+		em.flush();
+	}
+
+	@Override
+	public List<RequiredCredentialModel> getRequiredCredentials() {
+		List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
+		Collection<RequiredCredentialEntity> entities = realm.getRequiredCredentials();
+		if (entities == null)
+			return requiredCredentialModels;
+		for (RequiredCredentialEntity entity : entities) {
+			RequiredCredentialModel model = new RequiredCredentialModel();
+			model.setFormLabel(entity.getFormLabel());
+			model.setType(entity.getType());
+			model.setSecret(entity.isSecret());
+			model.setInput(entity.isInput());
+			requiredCredentialModels.add(model);
+		}
+		return requiredCredentialModels; // To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	@Override
+	public List<String> getDefaultRoles() {
+		Collection<RoleEntity> entities = realm.getDefaultRoles();
+		List<String> roles = new ArrayList<String>();
+		if (entities == null)
+			return roles;
+		for (RoleEntity entity : entities) {
+			roles.add(entity.getName());
+		}
+		return roles;
+	}
+
+	@Override
+	public void addDefaultRole(String name) {
+		RoleModel role = getRole(name);
+		if (role == null) {
+			role = addRole(name);
+		}
+		Collection<RoleEntity> entities = realm.getDefaultRoles();
+		for (RoleEntity entity : entities) {
+			if (entity.getId().equals(role.getId())) {
+				return;
+			}
+		}
+		RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
+		entities.add(roleEntity);
+		em.flush();
+	}
+
+	public static boolean contains(String str, String[] array) {
+		for (String s : array) {
+			if (str.equals(s))
+				return true;
+		}
+		return false;
+	}
+
+	@Override
+	public void updateDefaultRoles(String[] defaultRoles) {
+		Collection<RoleEntity> entities = realm.getDefaultRoles();
+		Set<String> already = new HashSet<String>();
+		List<RoleEntity> remove = new ArrayList<RoleEntity>();
+		for (RoleEntity rel : entities) {
+			if (!contains(rel.getName(), defaultRoles)) {
+				remove.add(rel);
+			} else {
+				already.add(rel.getName());
+			}
+		}
+		for (RoleEntity entity : remove) {
+			entities.remove(entity);
+		}
+		em.flush();
+		for (String roleName : defaultRoles) {
+			if (!already.contains(roleName)) {
+				addDefaultRole(roleName);
+			}
+		}
+		em.flush();
+	}
+
+	@Override
+	public ClientModel findClient(String clientId) {
+		ClientModel model = getApplicationByName(clientId);
+		if (model != null)
+			return model;
+		return getOAuthClient(clientId);
+	}
+
+	@Override
+	public ClientModel findClientById(String id) {
+		ClientModel model = getApplicationById(id);
+		if (model != null)
+			return model;
+		return getOAuthClientById(id);
+	}
+
+	@Override
+	public Map<String, ApplicationModel> getApplicationNameMap() {
+		Map<String, ApplicationModel> map = new HashMap<String, ApplicationModel>();
+		for (ApplicationModel app : getApplications()) {
+			map.put(app.getName(), app);
+		}
+		return map; // To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	@Override
+	public List<ApplicationModel> getApplications() {
+		List<ApplicationModel> list = new ArrayList<ApplicationModel>();
+		if (realm.getApplications() == null)
+			return list;
+		for (ApplicationEntity entity : realm.getApplications()) {
+			list.add(new ApplicationAdapter(this, em, session, entity));
+		}
+		return list;
+	}
+
+	@Override
+	public ApplicationModel addApplication(String name) {
+		return this.addApplication(KeycloakModelUtils.generateId(), name);
+	}
+
+	@Override
+	public ApplicationModel addApplication(String id, String name) {
+		ApplicationEntity applicationData = new ApplicationEntity();
+		applicationData.setId(id);
+		applicationData.setName(name);
+		applicationData.setEnabled(true);
+		applicationData.setRealm(realm);
+		realm.getApplications().add(applicationData);
+		em.persist(applicationData);
+		em.flush();
+		final ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
+		em.flush();
+		session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
+			@Override
+			public ApplicationModel getCreatedApplication() {
+				return resource;
+			}
+
+			@Override
+			public ClientModel getCreatedClient() {
+				return resource;
+			}
+		});
+		return resource;
+	}
+
+	@Override
+	public boolean removeApplication(String id) {
+		if (id == null)
+			return false;
+		ApplicationModel application = getApplicationById(id);
+		if (application == null)
+			return false;
+
+		for (RoleModel role : application.getRoles()) {
+			application.removeRole(role);
+		}
+
+		ApplicationEntity applicationEntity = null;
+		Iterator<ApplicationEntity> it = realm.getApplications().iterator();
+		while (it.hasNext()) {
+			ApplicationEntity ae = it.next();
+			if (ae.getId().equals(id)) {
+				applicationEntity = ae;
+				it.remove();
+				break;
+			}
+		}
+		for (ApplicationEntity a : realm.getApplications()) {
+			if (a.getId().equals(id)) {
+				applicationEntity = a;
+			}
+		}
+		if (application == null) {
+			return false;
+		}
+		em.remove(applicationEntity);
+		em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", applicationEntity).executeUpdate();
+		em.flush();
+
+		return true;
+	}
+
+	@Override
+	public ApplicationModel getApplicationById(String id) {
+		return session.realms().getApplicationById(id, this);
+	}
+
+	@Override
+	public ApplicationModel getApplicationByName(String name) {
+		return getApplicationNameMap().get(name);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String name) {
+		return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String id, String name) {
+		OAuthClientEntity data = new OAuthClientEntity();
+		data.setId(id);
+		data.setEnabled(true);
+		data.setName(name);
+		data.setRealm(realm);
+		em.persist(data);
+		em.flush();
+		final OAuthClientModel model = new OAuthClientAdapter(this, data, em);
+		em.flush();
+		session.getKeycloakSessionFactory().publish(new OAuthClientCreationEvent() {
+			@Override
+			public OAuthClientModel getCreatedOAuthClient() {
+				return model;
+			}
+
+			@Override
+			public ClientModel getCreatedClient() {
+				return model;
+			}
+		});
+		return model;
+	}
+
+	@Override
+	public boolean removeOAuthClient(String id) {
+		OAuthClientModel oauth = getOAuthClientById(id);
+		if (oauth == null)
+			return false;
+		OAuthClientEntity client = em.getReference(OAuthClientEntity.class, oauth.getId());
+		em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", client).executeUpdate();
+		em.remove(client);
+		return true;
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClient(String name) {
+		TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByName", OAuthClientEntity.class);
+		query.setParameter("name", name);
+		query.setParameter("realm", realm);
+		List<OAuthClientEntity> entities = query.getResultList();
+		if (entities.size() == 0)
+			return null;
+		return new OAuthClientAdapter(this, entities.get(0), em);
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClientById(String id) {
+		return session.realms().getOAuthClientById(id, this);
+	}
+
+	@Override
+	public List<OAuthClientModel> getOAuthClients() {
+		TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByRealm", OAuthClientEntity.class);
+		query.setParameter("realm", realm);
+		List<OAuthClientEntity> entities = query.getResultList();
+		List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
+		for (OAuthClientEntity entity : entities)
+			list.add(new OAuthClientAdapter(this, entity, em));
+		return list;
+	}
+
+	private static final String BROWSER_HEADER_PREFIX = "_browser_header.";
+
+	@Override
+	public Map<String, String> getBrowserSecurityHeaders() {
+		Map<String, String> attributes = getAttributes();
+		Map<String, String> headers = new HashMap<String, String>();
+		for (Map.Entry<String, String> entry : attributes.entrySet()) {
+			if (entry.getKey().startsWith(BROWSER_HEADER_PREFIX)) {
+				headers.put(entry.getKey().substring(BROWSER_HEADER_PREFIX.length()), entry.getValue());
+			}
+		}
+		return headers;
+	}
+
+	@Override
+	public void setBrowserSecurityHeaders(Map<String, String> headers) {
+		for (Map.Entry<String, String> entry : headers.entrySet()) {
+			setAttribute(BROWSER_HEADER_PREFIX + entry.getKey(), entry.getValue());
+		}
+	}
+
+	@Override
+	public Map<String, String> getSmtpConfig() {
+		return realm.getSmtpConfig();
+	}
+
+	@Override
+	public void setSmtpConfig(Map<String, String> smtpConfig) {
+		realm.setSmtpConfig(smtpConfig);
+		em.flush();
+	}
+
+	@Override
+	public List<UserFederationProviderModel> getUserFederationProviders() {
+		List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();
+		List<UserFederationProviderEntity> copy = new ArrayList<UserFederationProviderEntity>();
+		for (UserFederationProviderEntity entity : entities) {
+			copy.add(entity);
+
+		}
+		Collections.sort(copy, new Comparator<UserFederationProviderEntity>() {
+
+			@Override
+			public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) {
+				return o1.getPriority() - o2.getPriority();
+			}
+
+		});
+		List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
+		for (UserFederationProviderEntity entity : copy) {
+			result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity
+					.getPriority(), entity.getDisplayName(), entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity
+					.getLastSync()));
+		}
+
+		return result;
+	}
+
+	@Override
+	public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config,
+			int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
+		String id = KeycloakModelUtils.generateId();
+		UserFederationProviderEntity entity = new UserFederationProviderEntity();
+		entity.setId(id);
+		entity.setRealm(realm);
+		entity.setProviderName(providerName);
+		entity.setConfig(config);
+		entity.setPriority(priority);
+		if (displayName == null) {
+			displayName = id;
+		}
+		entity.setDisplayName(displayName);
+		entity.setFullSyncPeriod(fullSyncPeriod);
+		entity.setChangedSyncPeriod(changedSyncPeriod);
+		entity.setLastSync(lastSync);
+		em.persist(entity);
+		realm.getUserFederationProviders().add(entity);
+		em.flush();
+		return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod,
+				changedSyncPeriod, lastSync);
+	}
+
+	@Override
+	public void removeUserFederationProvider(UserFederationProviderModel provider) {
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			if (entity.getId().equals(provider.getId())) {
+				session.users().preRemove(this, provider);
+				it.remove();
+				em.remove(entity);
+				return;
+			}
+		}
+	}
+
+	@Override
+	public void updateUserFederationProvider(UserFederationProviderModel model) {
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			if (entity.getId().equals(model.getId())) {
+				String displayName = model.getDisplayName();
+				if (displayName != null) {
+					entity.setDisplayName(model.getDisplayName());
+				}
+				entity.setConfig(model.getConfig());
+				entity.setPriority(model.getPriority());
+				entity.setProviderName(model.getProviderName());
+				entity.setPriority(model.getPriority());
+				entity.setFullSyncPeriod(model.getFullSyncPeriod());
+				entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+				entity.setLastSync(model.getLastSync());
+				break;
+			}
+		}
+	}
+
+	@Override
+	public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
+
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			boolean found = false;
+			for (UserFederationProviderModel model : providers) {
+				if (entity.getId().equals(model.getId())) {
+					entity.setConfig(model.getConfig());
+					entity.setPriority(model.getPriority());
+					entity.setProviderName(model.getProviderName());
+					entity.setPriority(model.getPriority());
+					String displayName = model.getDisplayName();
+					if (displayName != null) {
+						entity.setDisplayName(model.getDisplayName());
+					}
+					entity.setFullSyncPeriod(model.getFullSyncPeriod());
+					entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+					entity.setLastSync(model.getLastSync());
+					found = true;
+					break;
+				}
+
+			}
+			if (found)
+				continue;
+			session.users().preRemove(
+					this,
+					new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity
+							.getPriority(), entity.getDisplayName(), entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(),
+							entity.getLastSync()));
+			it.remove();
+			em.remove(entity);
+		}
+
+		List<UserFederationProviderModel> add = new LinkedList<UserFederationProviderModel>();
+		for (UserFederationProviderModel model : providers) {
+			boolean found = false;
+			for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) {
+				if (entity.getId().equals(model.getId())) {
+					found = true;
+					break;
+				}
+			}
+			if (!found)
+				add.add(model);
+		}
+
+		for (UserFederationProviderModel model : add) {
+			UserFederationProviderEntity entity = new UserFederationProviderEntity();
+			if (model.getId() != null)
+				entity.setId(model.getId());
+			else
+				entity.setId(KeycloakModelUtils.generateId());
+			entity.setConfig(model.getConfig());
+			entity.setPriority(model.getPriority());
+			entity.setProviderName(model.getProviderName());
+			entity.setPriority(model.getPriority());
+			String displayName = model.getDisplayName();
+			if (displayName == null) {
+				displayName = entity.getId();
+			}
+			entity.setDisplayName(displayName);
+			entity.setFullSyncPeriod(model.getFullSyncPeriod());
+			entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+			entity.setLastSync(model.getLastSync());
+			em.persist(entity);
+			realm.getUserFederationProviders().add(entity);
+
+		}
+	}
+
+	@Override
+	public RoleModel getRole(String name) {
+		TypedQuery<RoleEntity> query = em.createNamedQuery("getRealmRoleByName", RoleEntity.class);
+		query.setParameter("name", name);
+		query.setParameter("realm", realm);
+		List<RoleEntity> roles = query.getResultList();
+		if (roles.size() == 0)
+			return null;
+		return new RoleAdapter(this, em, roles.get(0));
+	}
+
+	@Override
+	public RoleModel addRole(String name) {
+		return this.addRole(KeycloakModelUtils.generateId(), name);
+	}
+
+	@Override
+	public RoleModel addRole(String id, String name) {
+		RoleEntity entity = new RoleEntity();
+		entity.setId(id);
+		entity.setName(name);
+		entity.setRealm(realm);
+		entity.setRealmId(realm.getId());
+		realm.getRoles().add(entity);
+		em.persist(entity);
+		em.flush();
+		return new RoleAdapter(this, em, entity);
+	}
+
+	@Override
+	public boolean removeRole(RoleModel role) {
+		if (role == null) {
+			return false;
+		}
+		if (!role.getContainer().equals(this))
+			return false;
+		session.users().preRemove(this, role);
+		RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
+		realm.getRoles().remove(role);
+		realm.getDefaultRoles().remove(role);
+
+		em.createNativeQuery("delete from COMPOSITE_ROLE where CHILD_ROLE = :role").setParameter("role", roleEntity)
+				.executeUpdate();
+		em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
+
+		em.remove(roleEntity);
+
+		return true;
+	}
+
+	@Override
+	public Set<RoleModel> getRoles() {
+		Set<RoleModel> list = new HashSet<RoleModel>();
+		Collection<RoleEntity> roles = realm.getRoles();
+		if (roles == null)
+			return list;
+		for (RoleEntity entity : roles) {
+			list.add(new RoleAdapter(this, em, entity));
+		}
+		return list;
+	}
+
+	@Override
+	public RoleModel getRoleById(String id) {
+		return session.realms().getRoleById(id, this);
+	}
+
+	@Override
+	public boolean removeRoleById(String id) {
+		RoleModel role = getRoleById(id);
+		if (role == null)
+			return false;
+		return role.getContainer().removeRole(role);
+	}
+
+	@Override
+	public PasswordPolicy getPasswordPolicy() {
+		if (passwordPolicy == null) {
+			passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
+		}
+		return passwordPolicy;
+	}
+
+	@Override
+	public void setPasswordPolicy(PasswordPolicy policy) {
+		this.passwordPolicy = policy;
+		realm.setPasswordPolicy(policy.toString());
+		em.flush();
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o == null || !(o instanceof RealmModel))
+			return false;
+
+		RealmModel that = (RealmModel) o;
+		return that.getId().equals(getId());
+	}
+
+	@Override
+	public int hashCode() {
+		return getId().hashCode();
+	}
+
+	@Override
+	public String getLoginTheme() {
+		return realm.getLoginTheme();
+	}
+
+	@Override
+	public void setLoginTheme(String name) {
+		realm.setLoginTheme(name);
+		em.flush();
+	}
+
+	@Override
+	public String getAccountTheme() {
+		return realm.getAccountTheme();
+	}
+
+	@Override
+	public void setAccountTheme(String name) {
+		realm.setAccountTheme(name);
+		em.flush();
+	}
+
+	@Override
+	public String getAdminTheme() {
+		return realm.getAdminTheme();
+	}
+
+	@Override
+	public void setAdminTheme(String name) {
+		realm.setAdminTheme(name);
+		em.flush();
+	}
+
+	@Override
+	public String getEmailTheme() {
+		return realm.getEmailTheme();
+	}
+
+	@Override
+	public void setEmailTheme(String name) {
+		realm.setEmailTheme(name);
+		em.flush();
+	}
+
+	@Override
+	public boolean isEventsEnabled() {
+		return realm.isEventsEnabled();
+	}
+
+	@Override
+	public void setEventsEnabled(boolean enabled) {
+		realm.setEventsEnabled(enabled);
+		em.flush();
+	}
+
+	@Override
+	public long getEventsExpiration() {
+		return realm.getEventsExpiration();
+	}
+
+	@Override
+	public void setEventsExpiration(long expiration) {
+		realm.setEventsExpiration(expiration);
+		em.flush();
+	}
+
+	@Override
+	public Set<String> getEventsListeners() {
+		return realm.getEventsListeners();
+	}
+
+	@Override
+	public void setEventsListeners(Set<String> listeners) {
+		realm.setEventsListeners(listeners);
+		em.flush();
+	}
+
+	@Override
+	public ApplicationModel getMasterAdminApp() {
+		return new ApplicationAdapter(this, em, session, realm.getMasterAdminApp());
+	}
+
+	@Override
+	public void setMasterAdminApp(ApplicationModel app) {
+		ApplicationEntity appEntity = app != null ? em.getReference(ApplicationEntity.class, app.getId()) : null;
+		realm.setMasterAdminApp(appEntity);
+		em.flush();
+	}
+
+	@Override
+	public List<IdentityProviderModel> getIdentityProviders() {
+		List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
+
+		for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
+			IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+			identityProviderModel.setProviderId(entity.getProviderId());
+			identityProviderModel.setId(entity.getId());
+			identityProviderModel.setInternalId(entity.getInternalId());
+			identityProviderModel.setName(entity.getName());
+			identityProviderModel.setConfig(entity.getConfig());
+			identityProviderModel.setEnabled(entity.isEnabled());
+			identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
+			identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
+			identityProviderModel.setStoreToken(entity.isStoreToken());
+
+			identityProviders.add(identityProviderModel);
+		}
+
+		return identityProviders;
+	}
+
+	@Override
+	public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+		for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+			if (identityProviderModel.getId().equals(identityProviderId)) {
+				return identityProviderModel;
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public void addIdentityProvider(IdentityProviderModel identityProvider) {
+		IdentityProviderEntity entity = new IdentityProviderEntity();
+
+		entity.setInternalId(KeycloakModelUtils.generateId());
+		entity.setId(identityProvider.getId());
+		entity.setProviderId(identityProvider.getProviderId());
+		entity.setName(identityProvider.getName());
+		entity.setEnabled(identityProvider.isEnabled());
+		entity.setStoreToken(identityProvider.isStoreToken());
+		entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+		entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
+		entity.setConfig(identityProvider.getConfig());
+
+		realm.addIdentityProvider(entity);
+
+		em.persist(entity);
+		em.flush();
+	}
+
+	@Override
+	public void removeIdentityProviderById(String providerId) {
+		for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
+			if (entity.getId().equals(providerId)) {
+				em.remove(entity);
+				em.flush();
+			}
+		}
+	}
+
+	@Override
+	public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+		for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
+			if (entity.getInternalId().equals(identityProvider.getInternalId())) {
+				entity.setId(identityProvider.getId());
+				entity.setName(identityProvider.getName());
+				entity.setEnabled(identityProvider.isEnabled());
+				entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+				entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
+				entity.setStoreToken(identityProvider.isStoreToken());
+				entity.setConfig(identityProvider.getConfig());
+			}
+		}
+
+		em.flush();
+	}
+
+	@Override
+	public boolean isIdentityFederationEnabled() {
+		return !this.realm.getIdentityProviders().isEmpty();
+	}
 
 }
\ No newline at end of file
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 897ac6f..4543afa 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -1,7 +1,21 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.ApplicationModel;
@@ -24,1057 +38,1055 @@ import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
-import java.security.Key;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
 public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> implements RealmModel {
 
-    private final MongoRealmEntity realm;
-    private final RealmProvider model;
-
-    protected volatile transient PublicKey publicKey;
-    protected volatile transient PrivateKey privateKey;
-    protected volatile transient X509Certificate certificate;
-    protected volatile transient Key codeSecretKey;
-
-    private volatile transient PasswordPolicy passwordPolicy;
-    private volatile transient KeycloakSession session;
-
-    public RealmAdapter(KeycloakSession session, MongoRealmEntity realmEntity, MongoStoreInvocationContext invocationContext) {
-        super(invocationContext);
-        this.realm = realmEntity;
-        this.session = session;
-        this.model = session.realms();
-    }
-
-    @Override
-    public String getId() {
-        return realm.getId();
-    }
-
-    @Override
-    public String getName() {
-        return realm.getName();
-    }
-
-    @Override
-    public void setName(String name) {
-        realm.setName(name);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return realm.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        realm.setEnabled(enabled);
-        updateRealm();
-    }
-
-    @Override
-    public SslRequired getSslRequired() {
-        return SslRequired.valueOf(realm.getSslRequired());
-    }
-
-    @Override
-    public void setSslRequired(SslRequired sslRequired) {
-        realm.setSslRequired(sslRequired.name());
-        updateRealm();
-    }
-
-    @Override
-    public boolean isPasswordCredentialGrantAllowed() {
-        return realm.isPasswordCredentialGrantAllowed();
-    }
-
-    @Override
-    public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
-        realm.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isRegistrationAllowed() {
-        return realm.isRegistrationAllowed();
-    }
-
-    @Override
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        realm.setRegistrationAllowed(registrationAllowed);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isRememberMe() {
-        return realm.isRememberMe();
-    }
-
-    @Override
-    public void setRememberMe(boolean rememberMe) {
-        realm.setRememberMe(rememberMe);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isBruteForceProtected() {
-        return realm.isBruteForceProtected();
-    }
-
-    @Override
-    public void setBruteForceProtected(boolean value) {
-        realm.setBruteForceProtected(value);
-        updateRealm();
-    }
-
-    @Override
-    public int getMaxFailureWaitSeconds() {
-        return realm.getMaxFailureWaitSeconds();
-    }
-
-    @Override
-    public void setMaxFailureWaitSeconds(int val) {
-        realm.setMaxFailureWaitSeconds(val);
-        updateRealm();
-    }
-
-    @Override
-    public int getWaitIncrementSeconds() {
-        return realm.getWaitIncrementSeconds();
-    }
-
-    @Override
-    public void setWaitIncrementSeconds(int val) {
-        realm.setWaitIncrementSeconds(val);
-        updateRealm();
-    }
-
-    @Override
-    public long getQuickLoginCheckMilliSeconds() {
-        return realm.getQuickLoginCheckMilliSeconds();
-    }
-
-    @Override
-    public void setQuickLoginCheckMilliSeconds(long val) {
-        realm.setQuickLoginCheckMilliSeconds(val);
-        updateRealm();
-    }
-
-    @Override
-    public int getMinimumQuickLoginWaitSeconds() {
-        return realm.getMinimumQuickLoginWaitSeconds();
-    }
-
-    @Override
-    public void setMinimumQuickLoginWaitSeconds(int val) {
-        realm.setMinimumQuickLoginWaitSeconds(val);
-        updateRealm();
-    }
-
-
-    @Override
-    public int getMaxDeltaTimeSeconds() {
-        return realm.getMaxDeltaTimeSeconds();
-    }
-
-    @Override
-    public void setMaxDeltaTimeSeconds(int val) {
-        realm.setMaxDeltaTimeSeconds(val);
-        updateRealm();
-    }
-
-    @Override
-    public int getFailureFactor() {
-        return realm.getFailureFactor();
-    }
-
-    @Override
-    public void setFailureFactor(int failureFactor) {
-        realm.setFailureFactor(failureFactor);
-        updateRealm();
-    }
-
-
-    @Override
-    public boolean isVerifyEmail() {
-        return realm.isVerifyEmail();
-    }
-
-    @Override
-    public void setVerifyEmail(boolean verifyEmail) {
-        realm.setVerifyEmail(verifyEmail);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isResetPasswordAllowed() {
-        return realm.isResetPasswordAllowed();
-    }
-
-    @Override
-    public void setResetPasswordAllowed(boolean resetPassword) {
-        realm.setResetPasswordAllowed(resetPassword);
-        updateRealm();
-    }
-
-    @Override
-    public PasswordPolicy getPasswordPolicy() {
-        if (passwordPolicy == null) {
-            passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
-        }
-        return passwordPolicy;
-    }
-
-    @Override
-    public void setPasswordPolicy(PasswordPolicy policy) {
-        this.passwordPolicy = policy;
-        realm.setPasswordPolicy(policy.toString());
-        updateRealm();
-    }
-
-    @Override
-    public int getNotBefore() {
-        return realm.getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        realm.setNotBefore(notBefore);
-        updateRealm();
-    }
-
-
-    @Override
-    public int getSsoSessionIdleTimeout() {
-        return realm.getSsoSessionIdleTimeout();
-    }
-
-    @Override
-    public void setSsoSessionIdleTimeout(int seconds) {
-        realm.setSsoSessionIdleTimeout(seconds);
-        updateRealm();
-    }
-
-    @Override
-    public int getSsoSessionMaxLifespan() {
-        return realm.getSsoSessionMaxLifespan();
-    }
-
-    @Override
-    public void setSsoSessionMaxLifespan(int seconds) {
-        realm.setSsoSessionMaxLifespan(seconds);
-        updateRealm();
-    }
-
-    @Override
-    public int getAccessTokenLifespan() {
-        return realm.getAccessTokenLifespan();
-    }
-
-    @Override
-    public void setAccessTokenLifespan(int tokenLifespan) {
-        realm.setAccessTokenLifespan(tokenLifespan);
-        updateRealm();
-    }
-
-    @Override
-    public int getAccessCodeLifespan() {
-        return realm.getAccessCodeLifespan();
-    }
-
-    @Override
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        realm.setAccessCodeLifespan(accessCodeLifespan);
-        updateRealm();
-    }
-
-    @Override
-    public int getAccessCodeLifespanUserAction() {
-        return realm.getAccessCodeLifespanUserAction();
-    }
-
-    @Override
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
-        updateRealm();
-    }
-
-    @Override
-    public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
-        realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
-        updateRealm();
-    }
-
-    @Override
-    public int getAccessCodeLifespanLogin() {
-        return realm.getAccessCodeLifespanLogin();
-    }
-
-    @Override
-    public String getPublicKeyPem() {
-        return realm.getPublicKeyPem();
-    }
-
-    @Override
-    public void setPublicKeyPem(String publicKeyPem) {
-        realm.setPublicKeyPem(publicKeyPem);
-        this.publicKey = null;
-        updateRealm();
-    }
-
-    @Override
-    public X509Certificate getCertificate() {
-        if (certificate != null) return certificate;
-        certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
-        return certificate;
-    }
-
-    @Override
-    public void setCertificate(X509Certificate certificate) {
-        this.certificate = certificate;
-        String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
-        setCertificatePem(certificatePem);
-
-    }
-
-    @Override
-    public String getCertificatePem() {
-        return realm.getCertificatePem();
-    }
-
-    @Override
-    public void setCertificatePem(String certificate) {
-        realm.setCertificatePem(certificate);
-
-    }
-
-
-    @Override
-    public String getPrivateKeyPem() {
-        return realm.getPrivateKeyPem();
-    }
-
-    @Override
-    public void setPrivateKeyPem(String privateKeyPem) {
-        realm.setPrivateKeyPem(privateKeyPem);
-        this.privateKey = null;
-        updateRealm();
-    }
-
-    @Override
-    public PublicKey getPublicKey() {
-        if (publicKey != null) return publicKey;
-        publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
-        return publicKey;
-    }
-
-    @Override
-    public void setPublicKey(PublicKey publicKey) {
-        this.publicKey = publicKey;
-        String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
-        setPublicKeyPem(publicKeyPem);
-    }
-
-    @Override
-    public PrivateKey getPrivateKey() {
-        if (privateKey != null) return privateKey;
-        privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
-        return privateKey;
-    }
-
-    @Override
-    public void setPrivateKey(PrivateKey privateKey) {
-        this.privateKey = privateKey;
-        String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
-        setPrivateKeyPem(privateKeyPem);
-    }
-
-    @Override
-    public String getCodeSecret() {
-        return realm.getCodeSecret();
-    }
-
-    @Override
-    public Key getCodeSecretKey() {
-        if (codeSecretKey == null) {
-            codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
-        }
-        return codeSecretKey;
-    }
-
-    @Override
-    public void setCodeSecret(String codeSecret) {
-        realm.setCodeSecret(codeSecret);
-        updateRealm();
-    }
-
-    @Override
-    public String getLoginTheme() {
-        return realm.getLoginTheme();
-    }
-
-    @Override
-    public void setLoginTheme(String name) {
-        realm.setLoginTheme(name);
-        updateRealm();
-    }
-
-    @Override
-    public String getAccountTheme() {
-        return realm.getAccountTheme();
-    }
-
-    @Override
-    public void setAccountTheme(String name) {
-        realm.setAccountTheme(name);
-        updateRealm();
-    }
-
-    @Override
-    public String getAdminTheme() {
-        return realm.getAdminTheme();
-    }
-
-    @Override
-    public void setAdminTheme(String name) {
-        realm.setAdminTheme(name);
-        updateRealm();
-    }
-
-    @Override
-    public String getEmailTheme() {
-        return realm.getEmailTheme();
-    }
-
-    @Override
-    public void setEmailTheme(String name) {
-        realm.setEmailTheme(name);
-        updateRealm();
-    }
-
-    @Override
-    public RoleAdapter getRole(String name) {
-        DBObject query = new QueryBuilder()
-                .and("name").is(name)
-                .and("realmId").is(getId())
-                .get();
-        MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
-        if (role == null) {
-            return null;
-        } else {
-            return new RoleAdapter(session, this, role, this, invocationContext);
-        }
-    }
-
-    @Override
-    public RoleModel addRole(String name) {
-        return this.addRole(null, name);
-    }
-
-    @Override
-    public RoleModel addRole(String id, String name) {
-        MongoRoleEntity roleEntity = new MongoRoleEntity();
-        roleEntity.setId(id);
-        roleEntity.setName(name);
-        roleEntity.setRealmId(getId());
-
-        getMongoStore().insertEntity(roleEntity, invocationContext);
-
-        return new RoleAdapter(session, this, roleEntity, this, invocationContext);
-    }
-
-    @Override
-    public boolean removeRole(RoleModel role) {
-        return removeRoleById(role.getId());
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        RoleModel role = getRoleById(id);
-        if (role == null) return false;
-        session.users().preRemove(this, role);
-        return getMongoStore().removeEntity(MongoRoleEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public Set<RoleModel> getRoles() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<MongoRoleEntity> roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext);
-
-        Set<RoleModel> result = new HashSet<RoleModel>();
-
-        if (roles == null) return result;
-        for (MongoRoleEntity role : roles) {
-            result.add(new RoleAdapter(session, this, role, this, invocationContext));
-        }
-
-        return result;
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        return model.getRoleById(id, this);
-    }
-
-    @Override
-    public List<String> getDefaultRoles() {
-        return realm.getDefaultRoles();
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        RoleModel role = getRole(name);
-        if (role == null) {
-            addRole(name);
-        }
-
-        getMongoStore().pushItemToList(realm, "defaultRoles", name, true, invocationContext);
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        List<String> roleNames = new ArrayList<String>();
-        for (String roleName : defaultRoles) {
-            RoleModel role = getRole(roleName);
-            if (role == null) {
-                addRole(roleName);
-            }
-
-            roleNames.add(roleName);
-        }
-
-        realm.setDefaultRoles(roleNames);
-        updateRealm();
-    }
-
-    @Override
-    public ClientModel findClient(String clientId) {
-        ClientModel model = getApplicationByName(clientId);
-        if (model != null) return model;
-        return getOAuthClient(clientId);
-    }
-
-    @Override
-    public ClientModel findClientById(String id) {
-        ClientModel model = getApplicationById(id);
-        if (model != null) return model;
-        return getOAuthClientById(id);
-    }
-
-
-
-    @Override
-    public ApplicationModel getApplicationById(String id) {
-        return model.getApplicationById(id, this);
-    }
-
-    @Override
-    public ApplicationModel getApplicationByName(String name) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .and("name").is(name)
-                .get();
-        MongoApplicationEntity appEntity = getMongoStore().loadSingleEntity(MongoApplicationEntity.class, query, invocationContext);
-        return appEntity == null ? null : new ApplicationAdapter(session, this, appEntity, invocationContext);
-    }
-
-    @Override
-    public Map<String, ApplicationModel> getApplicationNameMap() {
-        Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
-        for (ApplicationModel resource : getApplications()) {
-            resourceMap.put(resource.getName(), resource);
-        }
-        return resourceMap;
-    }
-
-    @Override
-    public List<ApplicationModel> getApplications() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<MongoApplicationEntity> appDatas = getMongoStore().loadEntities(MongoApplicationEntity.class, query, invocationContext);
-
-        List<ApplicationModel> result = new ArrayList<ApplicationModel>();
-        for (MongoApplicationEntity appData : appDatas) {
-            result.add(new ApplicationAdapter(session, this, appData, invocationContext));
-        }
-        return result;
-    }
-
-    @Override
-    public ApplicationModel addApplication(String name) {
-        return this.addApplication(null, name);
-    }
-
-    @Override
-    public ApplicationModel addApplication(String id, String name) {
-        MongoApplicationEntity appData = new MongoApplicationEntity();
-        appData.setId(id);
-        appData.setName(name);
-        appData.setRealmId(getId());
-        appData.setEnabled(true);
-        getMongoStore().insertEntity(appData, invocationContext);
-
-        final ApplicationModel model = new ApplicationAdapter(session, this, appData, invocationContext);
-        session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
-            @Override
-            public ApplicationModel getCreatedApplication() {
-                return model;
-            }
-
-            @Override
-            public ClientModel getCreatedClient() {
-                return model;
-            }
-        });
-        return model;
-    }
-
-    @Override
-    public boolean removeApplication(String id) {
-        return getMongoStore().removeEntity(MongoApplicationEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String name) {
-        return this.addOAuthClient(null, name);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String id, String name) {
-        MongoOAuthClientEntity oauthClient = new MongoOAuthClientEntity();
-        oauthClient.setId(id);
-        oauthClient.setRealmId(getId());
-        oauthClient.setName(name);
-        getMongoStore().insertEntity(oauthClient, invocationContext);
-
-        final OAuthClientAdapter model = new OAuthClientAdapter(session, this, oauthClient, invocationContext);
-        session.getKeycloakSessionFactory().publish(new OAuthClientCreationEvent() {
-            @Override
-            public OAuthClientModel getCreatedOAuthClient() {
-                return model;
-            }
-
-            @Override
-            public ClientModel getCreatedClient() {
-                return model;
-            }
-        });
-        return model;
-    }
-
-    @Override
-    public boolean removeOAuthClient(String id) {
-        return getMongoStore().removeEntity(MongoOAuthClientEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClient(String name) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .and("name").is(name)
-                .get();
-        MongoOAuthClientEntity oauthClient = getMongoStore().loadSingleEntity(MongoOAuthClientEntity.class, query, invocationContext);
-        return oauthClient == null ? null : new OAuthClientAdapter(session, this, oauthClient, invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id) {
-        return model.getOAuthClientById(id, this);
-    }
-
-    @Override
-    public List<OAuthClientModel> getOAuthClients() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<MongoOAuthClientEntity> results = getMongoStore().loadEntities(MongoOAuthClientEntity.class, query, invocationContext);
-        List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
-        for (MongoOAuthClientEntity data : results) {
-            list.add(new OAuthClientAdapter(session, this, data, invocationContext));
-        }
-        return list;
-    }
-
-    @Override
-    public void addRequiredCredential(String type) {
-        RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
-        addRequiredCredential(credentialModel, realm.getRequiredCredentials());
-    }
-
-    protected void addRequiredCredential(RequiredCredentialModel credentialModel, List<RequiredCredentialEntity> persistentCollection) {
-        RequiredCredentialEntity credEntity = new RequiredCredentialEntity();
-        credEntity.setType(credentialModel.getType());
-        credEntity.setFormLabel(credentialModel.getFormLabel());
-        credEntity.setInput(credentialModel.isInput());
-        credEntity.setSecret(credentialModel.isSecret());
-
-        persistentCollection.add(credEntity);
-
-        updateRealm();
-    }
-
-    @Override
-    public void updateRequiredCredentials(Set<String> creds) {
-        updateRequiredCredentials(creds, realm.getRequiredCredentials());
-    }
-
-    protected void updateRequiredCredentials(Set<String> creds, List<RequiredCredentialEntity> credsEntities) {
-        Set<String> already = new HashSet<String>();
-        Set<RequiredCredentialEntity> toRemove = new HashSet<RequiredCredentialEntity>();
-        for (RequiredCredentialEntity entity : credsEntities) {
-            if (!creds.contains(entity.getType())) {
-                toRemove.add(entity);
-            } else {
-                already.add(entity.getType());
-            }
-        }
-        for (RequiredCredentialEntity entity : toRemove) {
-            credsEntities.remove(entity);
-        }
-        for (String cred : creds) {
-            if (!already.contains(cred)) {
-                RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred);
-                addRequiredCredential(credentialModel, credsEntities);
-            }
-        }
-        updateRealm();
-    }
-
-    @Override
-    public List<RequiredCredentialModel> getRequiredCredentials() {
-        return convertRequiredCredentialEntities(realm.getRequiredCredentials());
-    }
-
-    protected List<RequiredCredentialModel> convertRequiredCredentialEntities(Collection<RequiredCredentialEntity> credEntities) {
-
-        List<RequiredCredentialModel> result = new ArrayList<RequiredCredentialModel>();
-        for (RequiredCredentialEntity entity : credEntities) {
-            RequiredCredentialModel model = new RequiredCredentialModel();
-            model.setFormLabel(entity.getFormLabel());
-            model.setInput(entity.isInput());
-            model.setSecret(entity.isSecret());
-            model.setType(entity.getType());
-
-            result.add(model);
-        }
-        return result;
-    }
-
-    protected void updateRealm() {
-        super.updateMongoEntity();
-    }
-
-    protected RequiredCredentialModel initRequiredCredentialModel(String type) {
-        RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
-        if (model == null) {
-            throw new RuntimeException("Unknown credential type " + type);
-        }
-        return model;
-    }
-
-    @Override
-    public Map<String, String> getBrowserSecurityHeaders() {
-        return realm.getBrowserSecurityHeaders();
-    }
-
-    @Override
-    public void setBrowserSecurityHeaders(Map<String, String> headers) {
-        realm.setBrowserSecurityHeaders(headers);
-        updateRealm();
-    }
-
-    @Override
-    public Map<String, String> getSmtpConfig() {
-        return realm.getSmtpConfig();
-    }
-
-    @Override
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        realm.setSmtpConfig(smtpConfig);
-        updateRealm();
-    }
-
-
-    @Override
-    public List<IdentityProviderModel> getIdentityProviders() {
-        List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
-
-        for (IdentityProviderEntity entity: realm.getIdentityProviders()) {
-            IdentityProviderModel identityProviderModel = new IdentityProviderModel();
-
-            identityProviderModel.setProviderId(entity.getProviderId());
-            identityProviderModel.setId(entity.getId());
-            identityProviderModel.setInternalId(entity.getInternalId());
-            identityProviderModel.setName(entity.getName());
-            identityProviderModel.setConfig(entity.getConfig());
-            identityProviderModel.setEnabled(entity.isEnabled());
-            identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
-            identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
-            identityProviderModel.setStoreToken(entity.isStoreToken());
-
-            identityProviders.add(identityProviderModel);
-        }
-
-        return identityProviders;
-    }
-
-    @Override
-    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
-        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
-            if (identityProviderModel.getId().equals(identityProviderId)) {
-                return identityProviderModel;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public void addIdentityProvider(IdentityProviderModel identityProvider) {
-        IdentityProviderEntity entity = new IdentityProviderEntity();
-
-        entity.setInternalId(KeycloakModelUtils.generateId());
-        entity.setId(identityProvider.getId());
-        entity.setProviderId(identityProvider.getProviderId());
-        entity.setName(identityProvider.getName());
-        entity.setEnabled(identityProvider.isEnabled());
-        entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
-        entity.setStoreToken(identityProvider.isStoreToken());
-        entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
-        entity.setConfig(identityProvider.getConfig());
-
-        realm.getIdentityProviders().add(entity);
-        updateRealm();
-    }
-
-    @Override
-    public void removeIdentityProviderById(String providerId) {
-        IdentityProviderEntity toRemove;
-        for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
-            if (entity.getId().equals(providerId)) {
-                realm.getIdentityProviders().remove(entity);
-                updateRealm();
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
-        for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
-            if (entity.getInternalId().equals(identityProvider.getInternalId())) {
-                entity.setId(identityProvider.getId());
-                entity.setName(identityProvider.getName());
-                entity.setEnabled(identityProvider.isEnabled());
-                entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
-                entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
-                entity.setStoreToken(identityProvider.isStoreToken());
-                entity.setConfig(identityProvider.getConfig());
-            }
-        }
-
-        updateRealm();
-    }
-
-    @Override
-    public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
-        UserFederationProviderEntity entity = new UserFederationProviderEntity();
-        entity.setId(KeycloakModelUtils.generateId());
-        entity.setPriority(priority);
-        entity.setProviderName(providerName);
-        entity.setConfig(config);
-        if (displayName == null) {
-            displayName = entity.getId();
-        }
-        entity.setDisplayName(displayName);
-        entity.setFullSyncPeriod(fullSyncPeriod);
-        entity.setChangedSyncPeriod(changedSyncPeriod);
-        entity.setLastSync(lastSync);
-        realm.getUserFederationProviders().add(entity);
-        updateRealm();
-
-        return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
-    }
-
-    @Override
-    public void removeUserFederationProvider(UserFederationProviderModel provider) {
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            if (entity.getId().equals(provider.getId())) {
-                session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
-                        entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-                it.remove();
-            }
-        }
-        updateRealm();
-    }
-
-    @Override
-    public void updateUserFederationProvider(UserFederationProviderModel model) {
-        Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
-        while (it.hasNext()) {
-            UserFederationProviderEntity entity = it.next();
-            if (entity.getId().equals(model.getId())) {
-                entity.setProviderName(model.getProviderName());
-                entity.setConfig(model.getConfig());
-                entity.setPriority(model.getPriority());
-                String displayName = model.getDisplayName();
-                if (displayName != null) {
-                    entity.setDisplayName(model.getDisplayName());
-                }
-                entity.setFullSyncPeriod(model.getFullSyncPeriod());
-                entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-                entity.setLastSync(model.getLastSync());
-            }
-        }
-        updateRealm();
-    }
-
-    @Override
-    public List<UserFederationProviderModel> getUserFederationProviders() {
-        List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();
-        List<UserFederationProviderEntity> copy = new LinkedList<UserFederationProviderEntity>();
-        for (UserFederationProviderEntity entity : entities) {
-            copy.add(entity);
-
-        }
-        Collections.sort(copy, new Comparator<UserFederationProviderEntity>() {
-
-            @Override
-            public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) {
-                return o1.getPriority() - o2.getPriority();
-            }
-
-        });
-        List<UserFederationProviderModel> result = new LinkedList<UserFederationProviderModel>();
-        for (UserFederationProviderEntity entity : copy) {
-            result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
-                    entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
-        }
-
-        return result;
-    }
-
-    @Override
-    public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
-        List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
-        for (UserFederationProviderModel model : providers) {
-            UserFederationProviderEntity entity = new UserFederationProviderEntity();
-            if (model.getId() != null) entity.setId(model.getId());
-            else entity.setId(KeycloakModelUtils.generateId());
-            entity.setProviderName(model.getProviderName());
-            entity.setConfig(model.getConfig());
-            entity.setPriority(model.getPriority());
-            String displayName = model.getDisplayName();
-            if (displayName == null) {
-                entity.setDisplayName(entity.getId());
-            }
-            entity.setDisplayName(displayName);
-            entity.setFullSyncPeriod(model.getFullSyncPeriod());
-            entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
-            entity.setLastSync(model.getLastSync());
-            entities.add(entity);
-        }
-
-        realm.setUserFederationProviders(entities);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isEventsEnabled() {
-        return realm.isEventsEnabled();
-    }
-
-    @Override
-    public void setEventsEnabled(boolean enabled) {
-        realm.setEventsEnabled(enabled);
-        updateRealm();
-    }
-
-    @Override
-    public long getEventsExpiration() {
-        return realm.getEventsExpiration();
-    }
-
-    @Override
-    public void setEventsExpiration(long expiration) {
-        realm.setEventsExpiration(expiration);
-        updateRealm();
-    }
-
-    @Override
-    public Set<String> getEventsListeners() {
-        return new HashSet<String>(realm.getEventsListeners());
-    }
-
-    @Override
-    public void setEventsListeners(Set<String> listeners) {
-        if (listeners != null) {
-            realm.setEventsListeners(new ArrayList<String>(listeners));
-        } else {
-            realm.setEventsListeners(Collections.EMPTY_LIST);
-        }
-        updateRealm();
-    }
-
-    @Override
-    public ApplicationModel getMasterAdminApp() {
-        MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(), invocationContext);
-        return appData != null ? new ApplicationAdapter(session, this, appData, invocationContext) : null;
-    }
-
-    @Override
-    public void setMasterAdminApp(ApplicationModel app) {
-        String adminAppId = app != null ? app.getId() : null;
-        realm.setAdminAppId(adminAppId);
-        updateRealm();
-    }
-
-    @Override
-    public MongoRealmEntity getMongoEntity() {
-        return realm;
-    }
-
-    @Override
-    public boolean isIdentityFederationEnabled() {
-        return this.realm.getIdentityProviders() != null && !this.realm.getIdentityProviders().isEmpty();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || !(o instanceof RealmModel)) return false;
-
-        RealmModel that = (RealmModel) o;
-        return that.getId().equals(getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return getId().hashCode();
-    }
-
+	private final MongoRealmEntity realm;
+	private final RealmProvider model;
+
+	protected volatile transient PublicKey publicKey;
+	protected volatile transient PrivateKey privateKey;
+	protected volatile transient X509Certificate certificate;
+	protected volatile transient Key codeSecretKey;
+
+	private volatile transient PasswordPolicy passwordPolicy;
+	private volatile transient KeycloakSession session;
+
+	public RealmAdapter(KeycloakSession session, MongoRealmEntity realmEntity,
+			MongoStoreInvocationContext invocationContext) {
+		super(invocationContext);
+		this.realm = realmEntity;
+		this.session = session;
+		this.model = session.realms();
+	}
+
+	@Override
+	public String getId() {
+		return realm.getId();
+	}
+
+	@Override
+	public String getName() {
+		return realm.getName();
+	}
+
+	@Override
+	public void setName(String name) {
+		realm.setName(name);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return realm.isEnabled();
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		realm.setEnabled(enabled);
+		updateRealm();
+	}
+
+	@Override
+	public SslRequired getSslRequired() {
+		return SslRequired.valueOf(realm.getSslRequired());
+	}
+
+	@Override
+	public void setSslRequired(SslRequired sslRequired) {
+		realm.setSslRequired(sslRequired.name());
+		updateRealm();
+	}
+
+	@Override
+	public boolean isPasswordCredentialGrantAllowed() {
+		return realm.isPasswordCredentialGrantAllowed();
+	}
+
+	@Override
+	public void setPasswordCredentialGrantAllowed(boolean passwordCredentialGrantAllowed) {
+		realm.setPasswordCredentialGrantAllowed(passwordCredentialGrantAllowed);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isRegistrationAllowed() {
+		return realm.isRegistrationAllowed();
+	}
+
+	@Override
+	public void setRegistrationAllowed(boolean registrationAllowed) {
+		realm.setRegistrationAllowed(registrationAllowed);
+		updateRealm();
+	}
+
+	public boolean isRegistrationEmailAsUsername() {
+		return realm.isRegistrationEmailAsUsername();
+	}
+
+	public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+		realm.setRegistrationEmailAsUsername(registrationEmailAsUsername);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isRememberMe() {
+		return realm.isRememberMe();
+	}
+
+	@Override
+	public void setRememberMe(boolean rememberMe) {
+		realm.setRememberMe(rememberMe);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isBruteForceProtected() {
+		return realm.isBruteForceProtected();
+	}
+
+	@Override
+	public void setBruteForceProtected(boolean value) {
+		realm.setBruteForceProtected(value);
+		updateRealm();
+	}
+
+	@Override
+	public int getMaxFailureWaitSeconds() {
+		return realm.getMaxFailureWaitSeconds();
+	}
+
+	@Override
+	public void setMaxFailureWaitSeconds(int val) {
+		realm.setMaxFailureWaitSeconds(val);
+		updateRealm();
+	}
+
+	@Override
+	public int getWaitIncrementSeconds() {
+		return realm.getWaitIncrementSeconds();
+	}
+
+	@Override
+	public void setWaitIncrementSeconds(int val) {
+		realm.setWaitIncrementSeconds(val);
+		updateRealm();
+	}
+
+	@Override
+	public long getQuickLoginCheckMilliSeconds() {
+		return realm.getQuickLoginCheckMilliSeconds();
+	}
+
+	@Override
+	public void setQuickLoginCheckMilliSeconds(long val) {
+		realm.setQuickLoginCheckMilliSeconds(val);
+		updateRealm();
+	}
+
+	@Override
+	public int getMinimumQuickLoginWaitSeconds() {
+		return realm.getMinimumQuickLoginWaitSeconds();
+	}
+
+	@Override
+	public void setMinimumQuickLoginWaitSeconds(int val) {
+		realm.setMinimumQuickLoginWaitSeconds(val);
+		updateRealm();
+	}
+
+	@Override
+	public int getMaxDeltaTimeSeconds() {
+		return realm.getMaxDeltaTimeSeconds();
+	}
+
+	@Override
+	public void setMaxDeltaTimeSeconds(int val) {
+		realm.setMaxDeltaTimeSeconds(val);
+		updateRealm();
+	}
+
+	@Override
+	public int getFailureFactor() {
+		return realm.getFailureFactor();
+	}
+
+	@Override
+	public void setFailureFactor(int failureFactor) {
+		realm.setFailureFactor(failureFactor);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isVerifyEmail() {
+		return realm.isVerifyEmail();
+	}
+
+	@Override
+	public void setVerifyEmail(boolean verifyEmail) {
+		realm.setVerifyEmail(verifyEmail);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isResetPasswordAllowed() {
+		return realm.isResetPasswordAllowed();
+	}
+
+	@Override
+	public void setResetPasswordAllowed(boolean resetPassword) {
+		realm.setResetPasswordAllowed(resetPassword);
+		updateRealm();
+	}
+
+	@Override
+	public PasswordPolicy getPasswordPolicy() {
+		if (passwordPolicy == null) {
+			passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
+		}
+		return passwordPolicy;
+	}
+
+	@Override
+	public void setPasswordPolicy(PasswordPolicy policy) {
+		this.passwordPolicy = policy;
+		realm.setPasswordPolicy(policy.toString());
+		updateRealm();
+	}
+
+	@Override
+	public int getNotBefore() {
+		return realm.getNotBefore();
+	}
+
+	@Override
+	public void setNotBefore(int notBefore) {
+		realm.setNotBefore(notBefore);
+		updateRealm();
+	}
+
+	@Override
+	public int getSsoSessionIdleTimeout() {
+		return realm.getSsoSessionIdleTimeout();
+	}
+
+	@Override
+	public void setSsoSessionIdleTimeout(int seconds) {
+		realm.setSsoSessionIdleTimeout(seconds);
+		updateRealm();
+	}
+
+	@Override
+	public int getSsoSessionMaxLifespan() {
+		return realm.getSsoSessionMaxLifespan();
+	}
+
+	@Override
+	public void setSsoSessionMaxLifespan(int seconds) {
+		realm.setSsoSessionMaxLifespan(seconds);
+		updateRealm();
+	}
+
+	@Override
+	public int getAccessTokenLifespan() {
+		return realm.getAccessTokenLifespan();
+	}
+
+	@Override
+	public void setAccessTokenLifespan(int tokenLifespan) {
+		realm.setAccessTokenLifespan(tokenLifespan);
+		updateRealm();
+	}
+
+	@Override
+	public int getAccessCodeLifespan() {
+		return realm.getAccessCodeLifespan();
+	}
+
+	@Override
+	public void setAccessCodeLifespan(int accessCodeLifespan) {
+		realm.setAccessCodeLifespan(accessCodeLifespan);
+		updateRealm();
+	}
+
+	@Override
+	public int getAccessCodeLifespanUserAction() {
+		return realm.getAccessCodeLifespanUserAction();
+	}
+
+	@Override
+	public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+		realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
+		updateRealm();
+	}
+
+	@Override
+	public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
+		realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
+		updateRealm();
+	}
+
+	@Override
+	public int getAccessCodeLifespanLogin() {
+		return realm.getAccessCodeLifespanLogin();
+	}
+
+	@Override
+	public String getPublicKeyPem() {
+		return realm.getPublicKeyPem();
+	}
+
+	@Override
+	public void setPublicKeyPem(String publicKeyPem) {
+		realm.setPublicKeyPem(publicKeyPem);
+		this.publicKey = null;
+		updateRealm();
+	}
+
+	@Override
+	public X509Certificate getCertificate() {
+		if (certificate != null)
+			return certificate;
+		certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
+		return certificate;
+	}
+
+	@Override
+	public void setCertificate(X509Certificate certificate) {
+		this.certificate = certificate;
+		String certificatePem = KeycloakModelUtils.getPemFromCertificate(certificate);
+		setCertificatePem(certificatePem);
+
+	}
+
+	@Override
+	public String getCertificatePem() {
+		return realm.getCertificatePem();
+	}
+
+	@Override
+	public void setCertificatePem(String certificate) {
+		realm.setCertificatePem(certificate);
+
+	}
+
+	@Override
+	public String getPrivateKeyPem() {
+		return realm.getPrivateKeyPem();
+	}
+
+	@Override
+	public void setPrivateKeyPem(String privateKeyPem) {
+		realm.setPrivateKeyPem(privateKeyPem);
+		this.privateKey = null;
+		updateRealm();
+	}
+
+	@Override
+	public PublicKey getPublicKey() {
+		if (publicKey != null)
+			return publicKey;
+		publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
+		return publicKey;
+	}
+
+	@Override
+	public void setPublicKey(PublicKey publicKey) {
+		this.publicKey = publicKey;
+		String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
+		setPublicKeyPem(publicKeyPem);
+	}
+
+	@Override
+	public PrivateKey getPrivateKey() {
+		if (privateKey != null)
+			return privateKey;
+		privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
+		return privateKey;
+	}
+
+	@Override
+	public void setPrivateKey(PrivateKey privateKey) {
+		this.privateKey = privateKey;
+		String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
+		setPrivateKeyPem(privateKeyPem);
+	}
+
+	@Override
+	public String getCodeSecret() {
+		return realm.getCodeSecret();
+	}
+
+	@Override
+	public Key getCodeSecretKey() {
+		if (codeSecretKey == null) {
+			codeSecretKey = KeycloakModelUtils.getSecretKey(getCodeSecret());
+		}
+		return codeSecretKey;
+	}
+
+	@Override
+	public void setCodeSecret(String codeSecret) {
+		realm.setCodeSecret(codeSecret);
+		updateRealm();
+	}
+
+	@Override
+	public String getLoginTheme() {
+		return realm.getLoginTheme();
+	}
+
+	@Override
+	public void setLoginTheme(String name) {
+		realm.setLoginTheme(name);
+		updateRealm();
+	}
+
+	@Override
+	public String getAccountTheme() {
+		return realm.getAccountTheme();
+	}
+
+	@Override
+	public void setAccountTheme(String name) {
+		realm.setAccountTheme(name);
+		updateRealm();
+	}
+
+	@Override
+	public String getAdminTheme() {
+		return realm.getAdminTheme();
+	}
+
+	@Override
+	public void setAdminTheme(String name) {
+		realm.setAdminTheme(name);
+		updateRealm();
+	}
+
+	@Override
+	public String getEmailTheme() {
+		return realm.getEmailTheme();
+	}
+
+	@Override
+	public void setEmailTheme(String name) {
+		realm.setEmailTheme(name);
+		updateRealm();
+	}
+
+	@Override
+	public RoleAdapter getRole(String name) {
+		DBObject query = new QueryBuilder().and("name").is(name).and("realmId").is(getId()).get();
+		MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
+		if (role == null) {
+			return null;
+		} else {
+			return new RoleAdapter(session, this, role, this, invocationContext);
+		}
+	}
+
+	@Override
+	public RoleModel addRole(String name) {
+		return this.addRole(null, name);
+	}
+
+	@Override
+	public RoleModel addRole(String id, String name) {
+		MongoRoleEntity roleEntity = new MongoRoleEntity();
+		roleEntity.setId(id);
+		roleEntity.setName(name);
+		roleEntity.setRealmId(getId());
+
+		getMongoStore().insertEntity(roleEntity, invocationContext);
+
+		return new RoleAdapter(session, this, roleEntity, this, invocationContext);
+	}
+
+	@Override
+	public boolean removeRole(RoleModel role) {
+		return removeRoleById(role.getId());
+	}
+
+	@Override
+	public boolean removeRoleById(String id) {
+		RoleModel role = getRoleById(id);
+		if (role == null)
+			return false;
+		session.users().preRemove(this, role);
+		return getMongoStore().removeEntity(MongoRoleEntity.class, id, invocationContext);
+	}
+
+	@Override
+	public Set<RoleModel> getRoles() {
+		DBObject query = new QueryBuilder().and("realmId").is(getId()).get();
+		List<MongoRoleEntity> roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext);
+
+		Set<RoleModel> result = new HashSet<RoleModel>();
+
+		if (roles == null)
+			return result;
+		for (MongoRoleEntity role : roles) {
+			result.add(new RoleAdapter(session, this, role, this, invocationContext));
+		}
+
+		return result;
+	}
+
+	@Override
+	public RoleModel getRoleById(String id) {
+		return model.getRoleById(id, this);
+	}
+
+	@Override
+	public List<String> getDefaultRoles() {
+		return realm.getDefaultRoles();
+	}
+
+	@Override
+	public void addDefaultRole(String name) {
+		RoleModel role = getRole(name);
+		if (role == null) {
+			addRole(name);
+		}
+
+		getMongoStore().pushItemToList(realm, "defaultRoles", name, true, invocationContext);
+	}
+
+	@Override
+	public void updateDefaultRoles(String[] defaultRoles) {
+		List<String> roleNames = new ArrayList<String>();
+		for (String roleName : defaultRoles) {
+			RoleModel role = getRole(roleName);
+			if (role == null) {
+				addRole(roleName);
+			}
+
+			roleNames.add(roleName);
+		}
+
+		realm.setDefaultRoles(roleNames);
+		updateRealm();
+	}
+
+	@Override
+	public ClientModel findClient(String clientId) {
+		ClientModel model = getApplicationByName(clientId);
+		if (model != null)
+			return model;
+		return getOAuthClient(clientId);
+	}
+
+	@Override
+	public ClientModel findClientById(String id) {
+		ClientModel model = getApplicationById(id);
+		if (model != null)
+			return model;
+		return getOAuthClientById(id);
+	}
+
+	@Override
+	public ApplicationModel getApplicationById(String id) {
+		return model.getApplicationById(id, this);
+	}
+
+	@Override
+	public ApplicationModel getApplicationByName(String name) {
+		DBObject query = new QueryBuilder().and("realmId").is(getId()).and("name").is(name).get();
+		MongoApplicationEntity appEntity = getMongoStore().loadSingleEntity(MongoApplicationEntity.class, query,
+				invocationContext);
+		return appEntity == null ? null : new ApplicationAdapter(session, this, appEntity, invocationContext);
+	}
+
+	@Override
+	public Map<String, ApplicationModel> getApplicationNameMap() {
+		Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
+		for (ApplicationModel resource : getApplications()) {
+			resourceMap.put(resource.getName(), resource);
+		}
+		return resourceMap;
+	}
+
+	@Override
+	public List<ApplicationModel> getApplications() {
+		DBObject query = new QueryBuilder().and("realmId").is(getId()).get();
+		List<MongoApplicationEntity> appDatas = getMongoStore().loadEntities(MongoApplicationEntity.class, query,
+				invocationContext);
+
+		List<ApplicationModel> result = new ArrayList<ApplicationModel>();
+		for (MongoApplicationEntity appData : appDatas) {
+			result.add(new ApplicationAdapter(session, this, appData, invocationContext));
+		}
+		return result;
+	}
+
+	@Override
+	public ApplicationModel addApplication(String name) {
+		return this.addApplication(null, name);
+	}
+
+	@Override
+	public ApplicationModel addApplication(String id, String name) {
+		MongoApplicationEntity appData = new MongoApplicationEntity();
+		appData.setId(id);
+		appData.setName(name);
+		appData.setRealmId(getId());
+		appData.setEnabled(true);
+		getMongoStore().insertEntity(appData, invocationContext);
+
+		final ApplicationModel model = new ApplicationAdapter(session, this, appData, invocationContext);
+		session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
+			@Override
+			public ApplicationModel getCreatedApplication() {
+				return model;
+			}
+
+			@Override
+			public ClientModel getCreatedClient() {
+				return model;
+			}
+		});
+		return model;
+	}
+
+	@Override
+	public boolean removeApplication(String id) {
+		return getMongoStore().removeEntity(MongoApplicationEntity.class, id, invocationContext);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String name) {
+		return this.addOAuthClient(null, name);
+	}
+
+	@Override
+	public OAuthClientModel addOAuthClient(String id, String name) {
+		MongoOAuthClientEntity oauthClient = new MongoOAuthClientEntity();
+		oauthClient.setId(id);
+		oauthClient.setRealmId(getId());
+		oauthClient.setName(name);
+		getMongoStore().insertEntity(oauthClient, invocationContext);
+
+		final OAuthClientAdapter model = new OAuthClientAdapter(session, this, oauthClient, invocationContext);
+		session.getKeycloakSessionFactory().publish(new OAuthClientCreationEvent() {
+			@Override
+			public OAuthClientModel getCreatedOAuthClient() {
+				return model;
+			}
+
+			@Override
+			public ClientModel getCreatedClient() {
+				return model;
+			}
+		});
+		return model;
+	}
+
+	@Override
+	public boolean removeOAuthClient(String id) {
+		return getMongoStore().removeEntity(MongoOAuthClientEntity.class, id, invocationContext);
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClient(String name) {
+		DBObject query = new QueryBuilder().and("realmId").is(getId()).and("name").is(name).get();
+		MongoOAuthClientEntity oauthClient = getMongoStore().loadSingleEntity(MongoOAuthClientEntity.class, query,
+				invocationContext);
+		return oauthClient == null ? null : new OAuthClientAdapter(session, this, oauthClient, invocationContext);
+	}
+
+	@Override
+	public OAuthClientModel getOAuthClientById(String id) {
+		return model.getOAuthClientById(id, this);
+	}
+
+	@Override
+	public List<OAuthClientModel> getOAuthClients() {
+		DBObject query = new QueryBuilder().and("realmId").is(getId()).get();
+		List<MongoOAuthClientEntity> results = getMongoStore().loadEntities(MongoOAuthClientEntity.class, query,
+				invocationContext);
+		List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
+		for (MongoOAuthClientEntity data : results) {
+			list.add(new OAuthClientAdapter(session, this, data, invocationContext));
+		}
+		return list;
+	}
+
+	@Override
+	public void addRequiredCredential(String type) {
+		RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
+		addRequiredCredential(credentialModel, realm.getRequiredCredentials());
+	}
+
+	protected void addRequiredCredential(RequiredCredentialModel credentialModel,
+			List<RequiredCredentialEntity> persistentCollection) {
+		RequiredCredentialEntity credEntity = new RequiredCredentialEntity();
+		credEntity.setType(credentialModel.getType());
+		credEntity.setFormLabel(credentialModel.getFormLabel());
+		credEntity.setInput(credentialModel.isInput());
+		credEntity.setSecret(credentialModel.isSecret());
+
+		persistentCollection.add(credEntity);
+
+		updateRealm();
+	}
+
+	@Override
+	public void updateRequiredCredentials(Set<String> creds) {
+		updateRequiredCredentials(creds, realm.getRequiredCredentials());
+	}
+
+	protected void updateRequiredCredentials(Set<String> creds, List<RequiredCredentialEntity> credsEntities) {
+		Set<String> already = new HashSet<String>();
+		Set<RequiredCredentialEntity> toRemove = new HashSet<RequiredCredentialEntity>();
+		for (RequiredCredentialEntity entity : credsEntities) {
+			if (!creds.contains(entity.getType())) {
+				toRemove.add(entity);
+			} else {
+				already.add(entity.getType());
+			}
+		}
+		for (RequiredCredentialEntity entity : toRemove) {
+			credsEntities.remove(entity);
+		}
+		for (String cred : creds) {
+			if (!already.contains(cred)) {
+				RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred);
+				addRequiredCredential(credentialModel, credsEntities);
+			}
+		}
+		updateRealm();
+	}
+
+	@Override
+	public List<RequiredCredentialModel> getRequiredCredentials() {
+		return convertRequiredCredentialEntities(realm.getRequiredCredentials());
+	}
+
+	protected List<RequiredCredentialModel> convertRequiredCredentialEntities(
+			Collection<RequiredCredentialEntity> credEntities) {
+
+		List<RequiredCredentialModel> result = new ArrayList<RequiredCredentialModel>();
+		for (RequiredCredentialEntity entity : credEntities) {
+			RequiredCredentialModel model = new RequiredCredentialModel();
+			model.setFormLabel(entity.getFormLabel());
+			model.setInput(entity.isInput());
+			model.setSecret(entity.isSecret());
+			model.setType(entity.getType());
+
+			result.add(model);
+		}
+		return result;
+	}
+
+	protected void updateRealm() {
+		super.updateMongoEntity();
+	}
+
+	protected RequiredCredentialModel initRequiredCredentialModel(String type) {
+		RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
+		if (model == null) {
+			throw new RuntimeException("Unknown credential type " + type);
+		}
+		return model;
+	}
+
+	@Override
+	public Map<String, String> getBrowserSecurityHeaders() {
+		return realm.getBrowserSecurityHeaders();
+	}
+
+	@Override
+	public void setBrowserSecurityHeaders(Map<String, String> headers) {
+		realm.setBrowserSecurityHeaders(headers);
+		updateRealm();
+	}
+
+	@Override
+	public Map<String, String> getSmtpConfig() {
+		return realm.getSmtpConfig();
+	}
+
+	@Override
+	public void setSmtpConfig(Map<String, String> smtpConfig) {
+		realm.setSmtpConfig(smtpConfig);
+		updateRealm();
+	}
+
+	@Override
+	public List<IdentityProviderModel> getIdentityProviders() {
+		List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
+
+		for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
+			IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+			identityProviderModel.setProviderId(entity.getProviderId());
+			identityProviderModel.setId(entity.getId());
+			identityProviderModel.setInternalId(entity.getInternalId());
+			identityProviderModel.setName(entity.getName());
+			identityProviderModel.setConfig(entity.getConfig());
+			identityProviderModel.setEnabled(entity.isEnabled());
+			identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
+			identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
+			identityProviderModel.setStoreToken(entity.isStoreToken());
+
+			identityProviders.add(identityProviderModel);
+		}
+
+		return identityProviders;
+	}
+
+	@Override
+	public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+		for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+			if (identityProviderModel.getId().equals(identityProviderId)) {
+				return identityProviderModel;
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public void addIdentityProvider(IdentityProviderModel identityProvider) {
+		IdentityProviderEntity entity = new IdentityProviderEntity();
+
+		entity.setInternalId(KeycloakModelUtils.generateId());
+		entity.setId(identityProvider.getId());
+		entity.setProviderId(identityProvider.getProviderId());
+		entity.setName(identityProvider.getName());
+		entity.setEnabled(identityProvider.isEnabled());
+		entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+		entity.setStoreToken(identityProvider.isStoreToken());
+		entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
+		entity.setConfig(identityProvider.getConfig());
+
+		realm.getIdentityProviders().add(entity);
+		updateRealm();
+	}
+
+	@Override
+	public void removeIdentityProviderById(String providerId) {
+		IdentityProviderEntity toRemove;
+		for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
+			if (entity.getId().equals(providerId)) {
+				realm.getIdentityProviders().remove(entity);
+				updateRealm();
+				break;
+			}
+		}
+	}
+
+	@Override
+	public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+		for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
+			if (entity.getInternalId().equals(identityProvider.getInternalId())) {
+				entity.setId(identityProvider.getId());
+				entity.setName(identityProvider.getName());
+				entity.setEnabled(identityProvider.isEnabled());
+				entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+				entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
+				entity.setStoreToken(identityProvider.isStoreToken());
+				entity.setConfig(identityProvider.getConfig());
+			}
+		}
+
+		updateRealm();
+	}
+
+	@Override
+	public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config,
+			int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
+		UserFederationProviderEntity entity = new UserFederationProviderEntity();
+		entity.setId(KeycloakModelUtils.generateId());
+		entity.setPriority(priority);
+		entity.setProviderName(providerName);
+		entity.setConfig(config);
+		if (displayName == null) {
+			displayName = entity.getId();
+		}
+		entity.setDisplayName(displayName);
+		entity.setFullSyncPeriod(fullSyncPeriod);
+		entity.setChangedSyncPeriod(changedSyncPeriod);
+		entity.setLastSync(lastSync);
+		realm.getUserFederationProviders().add(entity);
+		updateRealm();
+
+		return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod,
+				changedSyncPeriod, lastSync);
+	}
+
+	@Override
+	public void removeUserFederationProvider(UserFederationProviderModel provider) {
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			if (entity.getId().equals(provider.getId())) {
+				session.users().preRemove(
+						this,
+						new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity
+								.getPriority(), entity.getDisplayName(), entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(),
+								entity.getLastSync()));
+				it.remove();
+			}
+		}
+		updateRealm();
+	}
+
+	@Override
+	public void updateUserFederationProvider(UserFederationProviderModel model) {
+		Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
+		while (it.hasNext()) {
+			UserFederationProviderEntity entity = it.next();
+			if (entity.getId().equals(model.getId())) {
+				entity.setProviderName(model.getProviderName());
+				entity.setConfig(model.getConfig());
+				entity.setPriority(model.getPriority());
+				String displayName = model.getDisplayName();
+				if (displayName != null) {
+					entity.setDisplayName(model.getDisplayName());
+				}
+				entity.setFullSyncPeriod(model.getFullSyncPeriod());
+				entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+				entity.setLastSync(model.getLastSync());
+			}
+		}
+		updateRealm();
+	}
+
+	@Override
+	public List<UserFederationProviderModel> getUserFederationProviders() {
+		List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();
+		List<UserFederationProviderEntity> copy = new LinkedList<UserFederationProviderEntity>();
+		for (UserFederationProviderEntity entity : entities) {
+			copy.add(entity);
+
+		}
+		Collections.sort(copy, new Comparator<UserFederationProviderEntity>() {
+
+			@Override
+			public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) {
+				return o1.getPriority() - o2.getPriority();
+			}
+
+		});
+		List<UserFederationProviderModel> result = new LinkedList<UserFederationProviderModel>();
+		for (UserFederationProviderEntity entity : copy) {
+			result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity
+					.getPriority(), entity.getDisplayName(), entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity
+					.getLastSync()));
+		}
+
+		return result;
+	}
+
+	@Override
+	public void setUserFederationProviders(List<UserFederationProviderModel> providers) {
+		List<UserFederationProviderEntity> entities = new LinkedList<UserFederationProviderEntity>();
+		for (UserFederationProviderModel model : providers) {
+			UserFederationProviderEntity entity = new UserFederationProviderEntity();
+			if (model.getId() != null)
+				entity.setId(model.getId());
+			else
+				entity.setId(KeycloakModelUtils.generateId());
+			entity.setProviderName(model.getProviderName());
+			entity.setConfig(model.getConfig());
+			entity.setPriority(model.getPriority());
+			String displayName = model.getDisplayName();
+			if (displayName == null) {
+				entity.setDisplayName(entity.getId());
+			}
+			entity.setDisplayName(displayName);
+			entity.setFullSyncPeriod(model.getFullSyncPeriod());
+			entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
+			entity.setLastSync(model.getLastSync());
+			entities.add(entity);
+		}
+
+		realm.setUserFederationProviders(entities);
+		updateRealm();
+	}
+
+	@Override
+	public boolean isEventsEnabled() {
+		return realm.isEventsEnabled();
+	}
+
+	@Override
+	public void setEventsEnabled(boolean enabled) {
+		realm.setEventsEnabled(enabled);
+		updateRealm();
+	}
+
+	@Override
+	public long getEventsExpiration() {
+		return realm.getEventsExpiration();
+	}
+
+	@Override
+	public void setEventsExpiration(long expiration) {
+		realm.setEventsExpiration(expiration);
+		updateRealm();
+	}
+
+	@Override
+	public Set<String> getEventsListeners() {
+		return new HashSet<String>(realm.getEventsListeners());
+	}
+
+	@Override
+	public void setEventsListeners(Set<String> listeners) {
+		if (listeners != null) {
+			realm.setEventsListeners(new ArrayList<String>(listeners));
+		} else {
+			realm.setEventsListeners(Collections.EMPTY_LIST);
+		}
+		updateRealm();
+	}
+
+	@Override
+	public ApplicationModel getMasterAdminApp() {
+		MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(),
+				invocationContext);
+		return appData != null ? new ApplicationAdapter(session, this, appData, invocationContext) : null;
+	}
+
+	@Override
+	public void setMasterAdminApp(ApplicationModel app) {
+		String adminAppId = app != null ? app.getId() : null;
+		realm.setAdminAppId(adminAppId);
+		updateRealm();
+	}
+
+	@Override
+	public MongoRealmEntity getMongoEntity() {
+		return realm;
+	}
+
+	@Override
+	public boolean isIdentityFederationEnabled() {
+		return this.realm.getIdentityProviders() != null && !this.realm.getIdentityProviders().isEmpty();
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o == null || !(o instanceof RealmModel))
+			return false;
+
+		RealmModel that = (RealmModel) o;
+		return that.getId().equals(getId());
+	}
+
+	@Override
+	public int hashCode() {
+		return getId().hashCode();
+	}
 
 }
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index 655b148..dfaa14f 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -21,58 +21,59 @@ import org.keycloak.representations.idm.CredentialRepresentation;
  */
 public class ApplianceBootstrap {
 
-    private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class);
+	private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class);
 
-    public void bootstrap(KeycloakSessionFactory sessionFactory, String contextPath) {
-        KeycloakSession session = sessionFactory.create();
-        session.getTransaction().begin();
+	public void bootstrap(KeycloakSessionFactory sessionFactory, String contextPath) {
+		KeycloakSession session = sessionFactory.create();
+		session.getTransaction().begin();
 
-        try {
-            bootstrap(session, contextPath);
-            session.getTransaction().commit();
-        } finally {
-            session.close();
-        }
-    }
+		try {
+			bootstrap(session, contextPath);
+			session.getTransaction().commit();
+		} finally {
+			session.close();
+		}
+	}
 
-    public void bootstrap(KeycloakSession session, String contextPath) {
-        String adminRealmName = Config.getAdminRealm();
-        if (session.realms().getRealm(adminRealmName) != null) {
-            return;
-        }
+	public void bootstrap(KeycloakSession session, String contextPath) {
+		String adminRealmName = Config.getAdminRealm();
+		if (session.realms().getRealm(adminRealmName) != null) {
+			return;
+		}
 
-        logger.info("Initializing " + adminRealmName + " realm");
+		logger.info("Initializing " + adminRealmName + " realm");
 
-        RealmManager manager = new RealmManager(session);
-        manager.setContextPath(contextPath);
-        RealmModel realm = manager.createRealm(adminRealmName, adminRealmName);
-        realm.setName(adminRealmName);
-        realm.setEnabled(true);
-        realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
-        realm.setSsoSessionIdleTimeout(1800);
-        realm.setAccessTokenLifespan(60);
-        realm.setSsoSessionMaxLifespan(36000);
-        realm.setAccessCodeLifespan(60);
-        realm.setAccessCodeLifespanUserAction(300);
-        realm.setSslRequired(SslRequired.EXTERNAL);
-        realm.setRegistrationAllowed(false);
-        KeycloakModelUtils.generateRealmKeys(realm);
+		RealmManager manager = new RealmManager(session);
+		manager.setContextPath(contextPath);
+		RealmModel realm = manager.createRealm(adminRealmName, adminRealmName);
+		realm.setName(adminRealmName);
+		realm.setEnabled(true);
+		realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
+		realm.setSsoSessionIdleTimeout(1800);
+		realm.setAccessTokenLifespan(60);
+		realm.setSsoSessionMaxLifespan(36000);
+		realm.setAccessCodeLifespan(60);
+		realm.setAccessCodeLifespanUserAction(300);
+		realm.setSslRequired(SslRequired.EXTERNAL);
+		realm.setRegistrationAllowed(false);
+		realm.setRegistrationEmailAsUsername(false);
+		KeycloakModelUtils.generateRealmKeys(realm);
 
-        UserModel adminUser = session.users().addUser(realm, "admin");
-        adminUser.setEnabled(true);
-        UserCredentialModel password = new UserCredentialModel();
-        password.setType(UserCredentialModel.PASSWORD);
-        password.setValue("admin");
-        session.users().updateCredential(realm, adminUser, password);
-        adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+		UserModel adminUser = session.users().addUser(realm, "admin");
+		adminUser.setEnabled(true);
+		UserCredentialModel password = new UserCredentialModel();
+		password.setType(UserCredentialModel.PASSWORD);
+		password.setValue("admin");
+		session.users().updateCredential(realm, adminUser, password);
+		adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
 
-        RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
-        adminUser.grantRole(adminRole);
+		RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
+		adminUser.grantRole(adminRole);
 
-        ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
-        for (String r : accountApp.getDefaultRoles()) {
-            adminUser.grantRole(accountApp.getRole(r));
-        }
-    }
+		ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
+		for (String r : accountApp.getDefaultRoles()) {
+			adminUser.grantRole(accountApp.getRole(r));
+		}
+	}
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index d26f695..1b10621 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -538,7 +538,17 @@ public class IdentityBrokerService {
             throw new IdentityBrokerException("federatedIdentityEmailExists");
         }
 
-        existingUser = this.session.users().getUserByUsername(updatedIdentity.getUsername(), this.realmModel);
+        String username = updatedIdentity.getUsername();
+        if (this.realmModel.isRegistrationEmailAsUsername()) {
+          username = updatedIdentity.getEmail();
+          if (username == null) {
+            fireErrorEvent(Errors.FEDERATED_IDENTITY_REGISTRATION_EMAIL_MISSING);
+            throw new IdentityBrokerException("federatedIdentityRegistrationEmailMissing");
+				    // TODO KEYCLOAK-1053 (ask user to enter email address) should be implemented instead of plain exception as better solution for this case
+          }
+        }
+
+        existingUser = this.session.users().getUserByUsername(username, this.realmModel);
 
         if (existingUser != null) {
             fireErrorEvent(Errors.FEDERATED_IDENTITY_USERNAME_EXISTS);
@@ -549,7 +559,7 @@ public class IdentityBrokerService {
             LOGGER.debugf("Creating account from identity [%s].", federatedIdentityModel);
         }
 
-        UserModel federatedUser = this.session.users().addUser(this.realmModel, updatedIdentity.getUsername());
+        UserModel federatedUser = this.session.users().addUser(this.realmModel, username);
 
         if (isDebugEnabled()) {
             LOGGER.debugf("Account [%s] created.", federatedUser);
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index f62bd5c..4ee3169 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -21,6 +21,25 @@
  */
 package org.keycloak.services.resources;
 
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.Providers;
+
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.ClientConnection;
@@ -56,887 +75,825 @@ import org.keycloak.services.resources.flows.Urls;
 import org.keycloak.services.util.CookieHelper;
 import org.keycloak.services.validation.Validation;
 
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Cookie;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import javax.ws.rs.ext.Providers;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class LoginActionsService {
 
-    protected static final Logger logger = Logger.getLogger(LoginActionsService.class);
-
-    public static final String ACTION_COOKIE = "KEYCLOAK_ACTION";
-
-    private RealmModel realm;
-
-    @Context
-    private HttpRequest request;
-
-    @Context
-    protected HttpHeaders headers;
-
-    @Context
-    private UriInfo uriInfo;
-
-    @Context
-    private ClientConnection clientConnection;
-
-    @Context
-    protected Providers providers;
-
-    @Context
-    protected KeycloakSession session;
-
-    private AuthenticationManager authManager;
-
-    private EventBuilder event;
-
-    public static UriBuilder loginActionsBaseUrl(UriInfo uriInfo) {
-        UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
-        return loginActionsBaseUrl(baseUriBuilder);
-    }
-
-    public static UriBuilder loginActionsBaseUrl(UriBuilder baseUriBuilder) {
-        return baseUriBuilder.path(RealmsResource.class).path(RealmsResource.class, "getLoginActionsService");
-    }
-
-    public static UriBuilder processLoginUrl(UriInfo uriInfo) {
-        UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
-        return processLoginUrl(baseUriBuilder);
-    }
-
-    public static UriBuilder processLoginUrl(UriBuilder baseUriBuilder) {
-        UriBuilder uriBuilder = loginActionsBaseUrl(baseUriBuilder);
-        return uriBuilder.path(OIDCLoginProtocolService.class, "processLogin");
-    }
-
-    public static UriBuilder processOAuthUrl(UriInfo uriInfo) {
-        UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
-        return processOAuthUrl(baseUriBuilder);
-    }
-
-    public static UriBuilder processOAuthUrl(UriBuilder baseUriBuilder) {
-        UriBuilder uriBuilder = loginActionsBaseUrl(baseUriBuilder);
-        return uriBuilder.path(OIDCLoginProtocolService.class, "processOAuth");
-    }
-
-    public LoginActionsService(RealmModel realm, AuthenticationManager authManager, EventBuilder event) {
-        this.realm = realm;
-        this.authManager = authManager;
-        this.event = event;
-    }
-
-    private boolean checkSsl() {
-        if (uriInfo.getBaseUri().getScheme().equals("https")) {
-            return true;
-        } else {
-            return !realm.getSslRequired().isRequired(clientConnection);
-        }
-    }
-
-
-    private class Checks {
-        ClientSessionCode clientCode;
-        Response response;
-
-        boolean check(String code, ClientSessionModel.Action requiredAction) {
-            if (!check(code)) {
-                return false;
-            } else if (!clientCode.isValid(requiredAction)) {
-                event.error(Errors.INVALID_CODE);
-                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
-                return false;
-            } else {
-                return true;
-            }
-        }
-
-        boolean check(String code, ClientSessionModel.Action requiredAction, ClientSessionModel.Action alternativeRequiredAction) {
-            if (!check(code)) {
-                return false;
-            } else if (!(clientCode.isValid(requiredAction) || clientCode.isValid(alternativeRequiredAction))) {
-                event.error(Errors.INVALID_CODE);
-                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
-                return false;
-            } else {
-                return true;
-            }
-        }
-
-        public boolean check(String code) {
-            if (!checkSsl()) {
-                event.error(Errors.SSL_REQUIRED);
-                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
-                return false;
-            }
-            if (!realm.isEnabled()) {
-                event.error(Errors.REALM_DISABLED);
-                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
-                return false;
-            }
-            clientCode = ClientSessionCode.parse(code, session, realm);
-            if (clientCode == null) {
-                event.error(Errors.INVALID_CODE);
-                response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
-                return false;
-            }
-            return true;
-        }
-    }
-
-    /**
-     * protocol independent login page entry point
-     *
-     *
-     * @param code
-     * @return
-     */
-    @Path("login")
-    @GET
-    public Response loginPage(@QueryParam("code") String code) {
-        event.event(EventType.LOGIN);
-        Checks checks = new Checks();
-        if (!checks.check(code)) {
-            return checks.response;
-        }
-        event.detail(Details.CODE_ID, code);
-        ClientSessionCode clientSessionCode = checks.clientCode;
-        ClientSessionModel clientSession = clientSessionCode.getClientSession();
-
-        if (clientSession.getAction().equals(ClientSessionModel.Action.RECOVER_PASSWORD)) {
-            TokenManager.dettachClientSession(session.sessions(), realm, clientSession);
-            clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
-        }
-
-        LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo)
-                .setClientSessionCode(clientSessionCode.getCode());
-
-        return forms.createLogin();
-    }
-
-    /**
-     * protocol independent registration page entry point
-     *
-     * @param code
-     * @return
-     */
-    @Path("registration")
-    @GET
-    public Response registerPage(@QueryParam("code") String code) {
-        event.event(EventType.REGISTER);
-        if (!realm.isRegistrationAllowed()) {
-            event.error(Errors.REGISTRATION_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
-        }
-
-        Checks checks = new Checks();
-        if (!checks.check(code)) {
-            return checks.response;
-        }
-        event.detail(Details.CODE_ID, code);
-        ClientSessionCode clientSessionCode = checks.clientCode;
-        ClientSessionModel clientSession = clientSessionCode.getClientSession();
-
-
-        authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
-
-        return Flows.forms(session, realm, clientSession.getClient(), uriInfo)
-                .setClientSessionCode(clientSessionCode.getCode())
-                .createRegistration();
-    }
-
-    /**
-     * URL called after login page.  YOU SHOULD NEVER INVOKE THIS DIRECTLY!
-     *
-     * @param code
-     * @param formData
-     * @return
-     */
-    @Path("request/login")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response processLogin(@QueryParam("code") String code,
-                                 final MultivaluedMap<String, String> formData) {
-        event.event(EventType.LOGIN);
-        if (!checkSsl()) {
-            event.error(Errors.SSL_REQUIRED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
-        }
-
-        if (!realm.isEnabled()) {
-            event.error(Errors.REALM_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
-        }
-        ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
-        if (clientCode == null) {
-            event.error(Errors.INVALID_CODE);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
-        }
-
-        ClientSessionModel clientSession = clientCode.getClientSession();
-        event.detail(Details.CODE_ID, clientSession.getId());
-
-        if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE) || clientSession.getUserSession() != null) {
-            clientCode.setAction(ClientSessionModel.Action.AUTHENTICATE);
-            event.client(clientSession.getClient()).error(Errors.EXPIRED_CODE);
-            return Flows.forms(this.session, realm, clientSession.getClient(), uriInfo).setError(Messages.EXPIRED_CODE)
-                    .setClientSessionCode(clientCode.getCode())
-                    .createLogin();
-        }
-
-        String username = formData.getFirst(AuthenticationManager.FORM_USERNAME);
-
-        String rememberMe = formData.getFirst("rememberMe");
-        boolean remember = rememberMe != null && rememberMe.equalsIgnoreCase("on");
-
-        event.client(clientSession.getClient().getClientId())
-                .detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
-                .detail(Details.RESPONSE_TYPE, "code")
-                .detail(Details.AUTH_METHOD, "form")
-                .detail(Details.USERNAME, username);
-
-        if (remember) {
-            event.detail(Details.REMEMBER_ME, "true");
-        }
-
-
-        ClientModel client = clientSession.getClient();
-        if (client == null) {
-            event.error(Errors.CLIENT_NOT_FOUND);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
-        }
-        if (!client.isEnabled()) {
-            event.error(Errors.CLIENT_NOT_FOUND);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
-        }
-
-        if (formData.containsKey("cancel")) {
-            event.error(Errors.REJECTED_BY_USER);
-            LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
-            protocol.setRealm(realm)
-                    .setUriInfo(uriInfo);
-            return protocol.cancelLogin(clientSession);
-        }
-
-        AuthenticationManager.AuthenticationStatus status = authManager.authenticateForm(session, clientConnection, realm, formData);
-
-        if (remember) {
-            authManager.createRememberMeCookie(realm, username, uriInfo, clientConnection);
-        } else {
-            authManager.expireRememberMeCookie(realm, uriInfo, clientConnection);
-        }
-
-        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
-        if (user != null) {
-            event.user(user);
-        }
-
-        switch (status) {
-            case SUCCESS:
-            case ACTIONS_REQUIRED:
-                UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", remember);
-                TokenManager.attachClientSession(userSession, clientSession);
-                event.session(userSession);
-                return authManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
-            case ACCOUNT_TEMPORARILY_DISABLED:
-                event.error(Errors.USER_TEMPORARILY_DISABLED);
-                return Flows.forms(this.session, realm, client, uriInfo)
-                        .setError(Messages.ACCOUNT_TEMPORARILY_DISABLED)
-                        .setFormData(formData)
-                        .setClientSessionCode(clientCode.getCode())
-                        .createLogin();
-            case ACCOUNT_DISABLED:
-                event.error(Errors.USER_DISABLED);
-                return Flows.forms(this.session, realm, client, uriInfo)
-                        .setError(Messages.ACCOUNT_DISABLED)
-                        .setClientSessionCode(clientCode.getCode())
-                        .setFormData(formData).createLogin();
-            case MISSING_TOTP:
-                formData.remove(CredentialRepresentation.PASSWORD);
-
-                String passwordToken = new JWSBuilder().jsonContent(new PasswordToken(realm.getName(), user.getId())).rsa256(realm.getPrivateKey());
-                formData.add(CredentialRepresentation.PASSWORD_TOKEN, passwordToken);
-
-                return Flows.forms(this.session, realm, client, uriInfo)
-                        .setFormData(formData)
-                        .setClientSessionCode(clientCode.getCode())
-                        .createLoginTotp();
-            case INVALID_USER:
-                event.error(Errors.USER_NOT_FOUND);
-                return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER)
-                        .setFormData(formData)
-                        .setClientSessionCode(clientCode.getCode())
-                        .createLogin();
-            default:
-                event.error(Errors.INVALID_USER_CREDENTIALS);
-                return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER)
-                        .setFormData(formData)
-                        .setClientSessionCode(clientCode.getCode())
-                        .createLogin();
-        }
-    }
-
-    /**
-     * Registration
-     *
-     * @param code
-     * @param formData
-     * @return
-     */
-    @Path("request/registration")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response processRegister(@QueryParam("code") String code,
-                                    final MultivaluedMap<String, String> formData) {
-        event.event(EventType.REGISTER);
-        if (!checkSsl()) {
-            event.error(Errors.SSL_REQUIRED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
-        }
-
-        if (!realm.isEnabled()) {
-            event.error(Errors.REALM_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
-        }
-        if (!realm.isRegistrationAllowed()) {
-            event.error(Errors.REGISTRATION_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
-        }
-        ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
-        if (clientCode == null) {
-            event.error(Errors.INVALID_CODE);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
-        }
-        if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
-            event.error(Errors.INVALID_CODE);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
-        }
-
-        String username = formData.getFirst("username");
-        String email = formData.getFirst("email");
-        ClientSessionModel clientSession = clientCode.getClientSession();
-        event.client(clientSession.getClient())
-                .detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
-                .detail(Details.RESPONSE_TYPE, "code")
-                .detail(Details.USERNAME, username)
-                .detail(Details.EMAIL, email)
-                .detail(Details.REGISTER_METHOD, "form");
-
-        if (!realm.isEnabled()) {
-            event.error(Errors.REALM_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled");
-        }
-        ClientModel client = clientSession.getClient();
-        if (client == null) {
-            event.error(Errors.CLIENT_NOT_FOUND);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
-        }
-
-        if (!client.isEnabled()) {
-            event.error(Errors.CLIENT_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
-        }
-
-
-        List<String> requiredCredentialTypes = new LinkedList<String>();
-        for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
-            requiredCredentialTypes.add(m.getType());
-        }
-
-        // Validate here, so user is not created if password doesn't validate to passwordPolicy of current realm
-        String error = Validation.validateRegistrationForm(formData, requiredCredentialTypes);
-        if (error == null) {
-            error = Validation.validatePassword(formData, realm.getPasswordPolicy());
-        }
-
-        if (error != null) {
-            event.error(Errors.INVALID_REGISTRATION);
-            return Flows.forms(session, realm, client, uriInfo)
-                    .setError(error)
-                    .setFormData(formData)
-                    .setClientSessionCode(clientCode.getCode())
-                    .createRegistration();
-        }
-
-        // Validate that user with this username doesn't exist in realm or any federation provider
-        if (session.users().getUserByUsername(username, realm) != null) {
-            event.error(Errors.USERNAME_IN_USE);
-            return Flows.forms(session, realm, client, uriInfo)
-                    .setError(Messages.USERNAME_EXISTS)
-                    .setFormData(formData)
-                    .setClientSessionCode(clientCode.getCode())
-                    .createRegistration();
-        }
-
-        // Validate that user with this email doesn't exist in realm or any federation provider
-        if (session.users().getUserByEmail(email, realm) != null) {
-            event.error(Errors.EMAIL_IN_USE);
-            return Flows.forms(session, realm, client, uriInfo)
-                    .setError(Messages.EMAIL_EXISTS)
-                    .setFormData(formData)
-                    .setClientSessionCode(clientCode.getCode())
-                    .createRegistration();
-        }
-
-        UserModel user = session.users().addUser(realm, username);
-        user.setEnabled(true);
-        user.setFirstName(formData.getFirst("firstName"));
-        user.setLastName(formData.getFirst("lastName"));
-
-        user.setEmail(email);
-
-        if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) {
-            UserCredentialModel credentials = new UserCredentialModel();
-            credentials.setType(CredentialRepresentation.PASSWORD);
-            credentials.setValue(formData.getFirst("password"));
-
-            boolean passwordUpdateSuccessful;
-            String passwordUpdateError = null;
-            try {
-                session.users().updateCredential(realm, user, UserCredentialModel.password(formData.getFirst("password")));
-                passwordUpdateSuccessful = true;
-            } catch (Exception ape) {
-                passwordUpdateSuccessful = false;
-                passwordUpdateError = ape.getMessage();
-            }
-
-            // User already registered, but force him to update password
-            if (!passwordUpdateSuccessful) {
-                user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
-                return Flows.forms(session, realm, client, uriInfo)
-                        .setError(passwordUpdateError)
-                        .setClientSessionCode(clientCode.getCode())
-                        .createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
-            }
-        }
-
-        AttributeFormDataProcessor.process(formData, realm, user);
-
-        event.user(user).success();
-        event.reset();
-
-        return processLogin(code, formData);
-    }
-
-    /**
-     * OAuth grant page.  You should not invoked this directly!
-     *
-     * @param formData
-     * @return
-     */
-    @Path("consent")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response processConsent(final MultivaluedMap<String, String> formData) {
-        event.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code");
-
-
-        if (!checkSsl()) {
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
-        }
-
-        String code = formData.getFirst("code");
-
-        ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
-        if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) {
-            event.error(Errors.INVALID_CODE);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid access code.");
-        }
-        ClientSessionModel clientSession = accessCode.getClientSession();
-        event.detail(Details.CODE_ID, clientSession.getId());
-
-        String redirect = clientSession.getRedirectUri();
-
-        event.client(clientSession.getClient())
-                .user(clientSession.getUserSession().getUser())
-                .detail(Details.RESPONSE_TYPE, "code")
-                .detail(Details.REDIRECT_URI, redirect);
-
-        UserSessionModel userSession = clientSession.getUserSession();
-        if (userSession != null) {
-            event.detail(Details.AUTH_METHOD, userSession.getAuthMethod());
-            event.detail(Details.USERNAME, userSession.getLoginUsername());
-            if (userSession.isRememberMe()) {
-                event.detail(Details.REMEMBER_ME, "true");
-            }
-        }
-
-        if (!AuthenticationManager.isSessionValid(realm, userSession)) {
-            AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
-            event.error(Errors.INVALID_CODE);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Session not active");
-        }
-        event.session(userSession);
-
-        LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
-        protocol.setRealm(realm)
-                .setUriInfo(uriInfo);
-        if (formData.containsKey("cancel")) {
-            event.error(Errors.REJECTED_BY_USER);
-            return protocol.consentDenied(clientSession);
-        }
-
-        event.success();
-
-        return authManager.redirectAfterSuccessfulFlow(session, realm, userSession, clientSession, request, uriInfo, clientConnection);
-    }
-
-
-
-
-    @Path("profile")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response updateProfile(@QueryParam("code") String code,
-                                  final MultivaluedMap<String, String> formData) {
-        event.event(EventType.UPDATE_PROFILE);
-        Checks checks = new Checks();
-        if (!checks.check(code, ClientSessionModel.Action.UPDATE_PROFILE)) {
-            return checks.response;
-        }
-        ClientSessionCode accessCode = checks.clientCode;
-        ClientSessionModel clientSession = accessCode.getClientSession();
-        UserSessionModel userSession = clientSession.getUserSession();
-        UserModel user = userSession.getUser();
-
-        initEvent(clientSession);
-
-        String error = Validation.validateUpdateProfileForm(formData);
-        if (error != null) {
-            return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(error)
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.UPDATE_PROFILE);
-        }
-
-        user.setFirstName(formData.getFirst("firstName"));
-        user.setLastName(formData.getFirst("lastName"));
-
-        String email = formData.getFirst("email");
-
-        String oldEmail = user.getEmail();
-        boolean emailChanged = oldEmail != null ? !oldEmail.equals(email) : email != null;
-
-        if (emailChanged) {
-            UserModel userByEmail = session.users().getUserByEmail(email, realm);
-
-            // check for duplicated email
-            if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
-                return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(Messages.EMAIL_EXISTS)
-                        .setClientSessionCode(accessCode.getCode())
-                        .createResponse(RequiredAction.UPDATE_PROFILE);
-            }
-
-            user.setEmail(email);
-            user.setEmailVerified(false);
-        }
-
-        user.removeRequiredAction(RequiredAction.UPDATE_PROFILE);
-        event.clone().event(EventType.UPDATE_PROFILE).success();
-
-        if (emailChanged) {
-            event.clone().event(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, oldEmail).detail(Details.UPDATED_EMAIL, email).success();
-        }
-
-        return redirectOauth(user, accessCode, clientSession, userSession);
-    }
-
-    @Path("totp")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response updateTotp(@QueryParam("code") String code,
-                               final MultivaluedMap<String, String> formData) {
-        event.event(EventType.UPDATE_TOTP);
-        Checks checks = new Checks();
-        if (!checks.check(code, ClientSessionModel.Action.CONFIGURE_TOTP)) {
-            return checks.response;
-        }
-        ClientSessionCode accessCode = checks.clientCode;
-        ClientSessionModel clientSession = accessCode.getClientSession();
-        UserSessionModel userSession = clientSession.getUserSession();
-        UserModel user = userSession.getUser();
-
-        initEvent(clientSession);
-
-        String totp = formData.getFirst("totp");
-        String totpSecret = formData.getFirst("totpSecret");
-
-        LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
-        if (Validation.isEmpty(totp)) {
-            return loginForms.setError(Messages.MISSING_TOTP)
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.CONFIGURE_TOTP);
-        } else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) {
-            return loginForms.setError(Messages.INVALID_TOTP)
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.CONFIGURE_TOTP);
-        }
-
-        UserCredentialModel credentials = new UserCredentialModel();
-        credentials.setType(CredentialRepresentation.TOTP);
-        credentials.setValue(totpSecret);
-        session.users().updateCredential(realm, user, credentials);
-
-        user.setTotp(true);
-
-        user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP);
-
-        event.clone().event(EventType.UPDATE_TOTP).success();
-
-        return redirectOauth(user, accessCode, clientSession, userSession);
-    }
-
-    @Path("password")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response updatePassword(@QueryParam("code") String code,
-                                   final MultivaluedMap<String, String> formData) {
-        event.event(EventType.UPDATE_PASSWORD);
-        Checks checks = new Checks();
-        if (!checks.check(code, ClientSessionModel.Action.UPDATE_PASSWORD, ClientSessionModel.Action.RECOVER_PASSWORD)) {
-            return checks.response;
-        }
-        ClientSessionCode accessCode = checks.clientCode;
-        ClientSessionModel clientSession = accessCode.getClientSession();
-        UserSessionModel userSession = clientSession.getUserSession();
-        UserModel user = userSession.getUser();
-
-        initEvent(clientSession);
-
-        String passwordNew = formData.getFirst("password-new");
-        String passwordConfirm = formData.getFirst("password-confirm");
-
-        LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
-        if (Validation.isEmpty(passwordNew)) {
-            return loginForms.setError(Messages.MISSING_PASSWORD)
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.UPDATE_PASSWORD);
-        } else if (!passwordNew.equals(passwordConfirm)) {
-            return loginForms.setError(Messages.NOTMATCH_PASSWORD)
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.UPDATE_PASSWORD);
-        }
-
-        try {
-            session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew));
-        } catch (Exception ape) {
-            return loginForms.setError(ape.getMessage())
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.UPDATE_PASSWORD);
-        }
-
-        user.removeRequiredAction(RequiredAction.UPDATE_PASSWORD);
-
-        event.event(EventType.UPDATE_PASSWORD).success();
-
-        if (clientSession.getAction().equals(ClientSessionModel.Action.RECOVER_PASSWORD)) {
-            String actionCookieValue = getActionCookie();
-            if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
-                return Flows.forms(session, realm, clientSession.getClient(), uriInfo).setSuccess("passwordUpdated").createInfoPage();
-            }
-        }
-
-        event = event.clone().event(EventType.LOGIN);
-
-        return redirectOauth(user, accessCode, clientSession, userSession);
-    }
-
-
-    @Path("email-verification")
-    @GET
-    public Response emailVerification(@QueryParam("code") String code, @QueryParam("key") String key) {
-        event.event(EventType.VERIFY_EMAIL);
-        if (key != null) {
-            Checks checks = new Checks();
-            if (!checks.check(key, ClientSessionModel.Action.VERIFY_EMAIL)) {
-                return checks.response;
-            }
-            ClientSessionCode accessCode = checks.clientCode;
-            ClientSessionModel clientSession = accessCode.getClientSession();
-            UserSessionModel userSession = clientSession.getUserSession();
-            UserModel user = userSession.getUser();
-            initEvent(clientSession);
-            user.setEmailVerified(true);
-
-            user.removeRequiredAction(RequiredAction.VERIFY_EMAIL);
-
-            event.event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();
-
-            String actionCookieValue = getActionCookie();
-            if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
-                return Flows.forms(session, realm, clientSession.getClient(), uriInfo).setSuccess("emailVerified").createInfoPage();
-            }
-
-            event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN);
-
-            return redirectOauth(user, accessCode, clientSession, userSession);
-        } else {
-            Checks checks = new Checks();
-            if (!checks.check(code, ClientSessionModel.Action.VERIFY_EMAIL)) {
-                return checks.response;
-            }
-            ClientSessionCode accessCode = checks.clientCode;
-            ClientSessionModel clientSession = accessCode.getClientSession();
-            UserSessionModel userSession = clientSession.getUserSession();
-            initEvent(clientSession);
-
-            createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
-
-            return Flows.forms(session, realm, null, uriInfo)
-                    .setClientSessionCode(accessCode.getCode())
-                    .setUser(userSession.getUser())
-                    .createResponse(RequiredAction.VERIFY_EMAIL);
-        }
-    }
-
-    @Path("password-reset")
-    @GET
-    public Response passwordReset(@QueryParam("code") String code, @QueryParam("key") String key) {
-        event.event(EventType.RESET_PASSWORD);
-        if (key != null) {
-            Checks checks = new Checks();
-            if (!checks.check(key, ClientSessionModel.Action.RECOVER_PASSWORD)) {
-                return checks.response;
-            }
-            ClientSessionCode accessCode = checks.clientCode;
-            return Flows.forms(session, realm, null, uriInfo)
-                    .setClientSessionCode(accessCode.getCode())
-                    .createResponse(RequiredAction.UPDATE_PASSWORD);
-        } else {
-            return Flows.forms(session, realm, null, uriInfo)
-                    .setClientSessionCode(code)
-                    .createPasswordReset();
-        }
-    }
-
-    @Path("password-reset")
-    @POST
-    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response sendPasswordReset(@QueryParam("code") String code,
-                                      final MultivaluedMap<String, String> formData) {
-        event.event(EventType.SEND_RESET_PASSWORD);
-        if (!checkSsl()) {
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
-        }
-        if (!realm.isEnabled()) {
-            event.error(Errors.REALM_DISABLED);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
-        }
-        ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
-        if (accessCode == null) {
-            event.error(Errors.INVALID_CODE);
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
-        }
-        ClientSessionModel clientSession = accessCode.getClientSession();
-
-        String username = formData.getFirst("username");
-
-        ClientModel client = clientSession.getClient();
-        if (client == null) {
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
-                    "Unknown login requester.");
-        }
-        if (!client.isEnabled()) {
-            return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
-                    "Login requester not enabled.");
-        }
-
-        event.client(client.getClientId())
-                .detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
-                .detail(Details.RESPONSE_TYPE, "code")
-                .detail(Details.AUTH_METHOD, "form")
-                .detail(Details.USERNAME, username);
-
-        UserModel user = session.users().getUserByUsername(username, realm);
-        if (user == null && username.contains("@")) {
-            user = session.users().getUserByEmail(username, realm);
-        }
-
-        if (user == null) {
-            event.error(Errors.USER_NOT_FOUND);
-        } else if(!user.isEnabled()) {
-            event.user(user).error(Errors.USER_DISABLED);
-        }
-        else if(user.getEmail() == null || user.getEmail().trim().length() == 0) {
-            event.user(user).error(Errors.INVALID_EMAIL);
-        } else{
-            event.user(user);
-
-            UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", false);
-            event.session(userSession);
-            TokenManager.attachClientSession(userSession, clientSession);
-
-            accessCode.setAction(ClientSessionModel.Action.RECOVER_PASSWORD);
-
-            try {
-                UriBuilder builder = Urls.loginPasswordResetBuilder(uriInfo.getBaseUri());
-                builder.queryParam("key", accessCode.getCode());
-
-                String link = builder.build(realm.getName()).toString();
-                long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());
-
-                this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendPasswordReset(link, expiration);
-
-                event.detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, clientSession.getId()).success();
-            } catch (EmailException e) {
-                event.error(Errors.EMAIL_SEND_FAILED);
-                logger.error("Failed to send password reset email", e);
-                return Flows.forms(this.session, realm, client, uriInfo).setError("emailSendError")
-                        .setClientSessionCode(accessCode.getCode())
-                        .createErrorPage();
-            }
-
-            createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
-        }
-
-        return Flows.forms(session, realm, client,  uriInfo).setSuccess("emailSent").setClientSessionCode(accessCode.getCode()).createPasswordReset();
-    }
-
-    private String getActionCookie() {
-        Cookie cookie = headers.getCookies().get(ACTION_COOKIE);
-        AuthenticationManager.expireCookie(realm, ACTION_COOKIE, AuthenticationManager.getRealmCookiePath(realm, uriInfo), realm.getSslRequired().isRequired(clientConnection), clientConnection);
-        return cookie != null ? cookie.getValue() : null;
-    }
-
-    public static void createActionCookie(RealmModel realm, UriInfo uriInfo, ClientConnection clientConnection, String sessionId) {
-        CookieHelper.addCookie(ACTION_COOKIE, sessionId, AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, null, -1, realm.getSslRequired().isRequired(clientConnection), true);
-    }
-
-    private Response redirectOauth(UserModel user, ClientSessionCode accessCode, ClientSessionModel clientSession, UserSessionModel userSession) {
-        return AuthenticationManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
-    }
-
-    private void initEvent(ClientSessionModel clientSession) {
-        event.event(EventType.LOGIN).client(clientSession.getClient())
-                .user(clientSession.getUserSession().getUser())
-                .session(clientSession.getUserSession().getId())
-                .detail(Details.CODE_ID, clientSession.getId())
-                .detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
-                .detail(Details.RESPONSE_TYPE, "code");
-
-        UserSessionModel userSession = clientSession.getUserSession();
-
-        if (userSession != null) {
-            event.detail(Details.AUTH_METHOD, userSession.getAuthMethod());
-            event.detail(Details.USERNAME, userSession.getLoginUsername());
-            if (userSession.isRememberMe()) {
-                event.detail(Details.REMEMBER_ME, "true");
-            }
-        }
-    }
+	protected static final Logger logger = Logger.getLogger(LoginActionsService.class);
+
+	public static final String ACTION_COOKIE = "KEYCLOAK_ACTION";
+
+	private RealmModel realm;
+
+	@Context
+	private HttpRequest request;
+
+	@Context
+	protected HttpHeaders headers;
+
+	@Context
+	private UriInfo uriInfo;
+
+	@Context
+	private ClientConnection clientConnection;
+
+	@Context
+	protected Providers providers;
+
+	@Context
+	protected KeycloakSession session;
+
+	private AuthenticationManager authManager;
+
+	private EventBuilder event;
+
+	public static UriBuilder loginActionsBaseUrl(UriInfo uriInfo) {
+		UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
+		return loginActionsBaseUrl(baseUriBuilder);
+	}
+
+	public static UriBuilder loginActionsBaseUrl(UriBuilder baseUriBuilder) {
+		return baseUriBuilder.path(RealmsResource.class).path(RealmsResource.class, "getLoginActionsService");
+	}
+
+	public static UriBuilder processLoginUrl(UriInfo uriInfo) {
+		UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
+		return processLoginUrl(baseUriBuilder);
+	}
+
+	public static UriBuilder processLoginUrl(UriBuilder baseUriBuilder) {
+		UriBuilder uriBuilder = loginActionsBaseUrl(baseUriBuilder);
+		return uriBuilder.path(OIDCLoginProtocolService.class, "processLogin");
+	}
+
+	public static UriBuilder processOAuthUrl(UriInfo uriInfo) {
+		UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
+		return processOAuthUrl(baseUriBuilder);
+	}
+
+	public static UriBuilder processOAuthUrl(UriBuilder baseUriBuilder) {
+		UriBuilder uriBuilder = loginActionsBaseUrl(baseUriBuilder);
+		return uriBuilder.path(OIDCLoginProtocolService.class, "processOAuth");
+	}
+
+	public LoginActionsService(RealmModel realm, AuthenticationManager authManager, EventBuilder event) {
+		this.realm = realm;
+		this.authManager = authManager;
+		this.event = event;
+	}
+
+	private boolean checkSsl() {
+		if (uriInfo.getBaseUri().getScheme().equals("https")) {
+			return true;
+		} else {
+			return !realm.getSslRequired().isRequired(clientConnection);
+		}
+	}
+
+	private class Checks {
+		ClientSessionCode clientCode;
+		Response response;
+
+		boolean check(String code, ClientSessionModel.Action requiredAction) {
+			if (!check(code)) {
+				return false;
+			} else if (!clientCode.isValid(requiredAction)) {
+				event.error(Errors.INVALID_CODE);
+				response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+						"Invalid code, please login again through your application.");
+				return false;
+			} else {
+				return true;
+			}
+		}
+
+		boolean check(String code, ClientSessionModel.Action requiredAction,
+				ClientSessionModel.Action alternativeRequiredAction) {
+			if (!check(code)) {
+				return false;
+			} else if (!(clientCode.isValid(requiredAction) || clientCode.isValid(alternativeRequiredAction))) {
+				event.error(Errors.INVALID_CODE);
+				response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+						"Invalid code, please login again through your application.");
+				return false;
+			} else {
+				return true;
+			}
+		}
+
+		public boolean check(String code) {
+			if (!checkSsl()) {
+				event.error(Errors.SSL_REQUIRED);
+				response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
+				return false;
+			}
+			if (!realm.isEnabled()) {
+				event.error(Errors.REALM_DISABLED);
+				response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
+				return false;
+			}
+			clientCode = ClientSessionCode.parse(code, session, realm);
+			if (clientCode == null) {
+				event.error(Errors.INVALID_CODE);
+				response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+						"Unknown code, please login again through your application.");
+				return false;
+			}
+			return true;
+		}
+	}
+
+	/**
+	 * protocol independent login page entry point
+	 * 
+	 * 
+	 * @param code
+	 * @return
+	 */
+	@Path("login")
+	@GET
+	public Response loginPage(@QueryParam("code") String code) {
+		event.event(EventType.LOGIN);
+		Checks checks = new Checks();
+		if (!checks.check(code)) {
+			return checks.response;
+		}
+		event.detail(Details.CODE_ID, code);
+		ClientSessionCode clientSessionCode = checks.clientCode;
+		ClientSessionModel clientSession = clientSessionCode.getClientSession();
+
+		if (clientSession.getAction().equals(ClientSessionModel.Action.RECOVER_PASSWORD)) {
+			TokenManager.dettachClientSession(session.sessions(), realm, clientSession);
+			clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
+		}
+
+		LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo).setClientSessionCode(
+				clientSessionCode.getCode());
+
+		return forms.createLogin();
+	}
+
+	/**
+	 * protocol independent registration page entry point
+	 * 
+	 * @param code
+	 * @return
+	 */
+	@Path("registration")
+	@GET
+	public Response registerPage(@QueryParam("code") String code) {
+		event.event(EventType.REGISTER);
+		if (!realm.isRegistrationAllowed()) {
+			event.error(Errors.REGISTRATION_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
+		}
+
+		Checks checks = new Checks();
+		if (!checks.check(code)) {
+			return checks.response;
+		}
+		event.detail(Details.CODE_ID, code);
+		ClientSessionCode clientSessionCode = checks.clientCode;
+		ClientSessionModel clientSession = clientSessionCode.getClientSession();
+
+		authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
+
+		return Flows.forms(session, realm, clientSession.getClient(), uriInfo)
+				.setClientSessionCode(clientSessionCode.getCode()).createRegistration();
+	}
+
+	/**
+	 * URL called after login page. YOU SHOULD NEVER INVOKE THIS DIRECTLY!
+	 * 
+	 * @param code
+	 * @param formData
+	 * @return
+	 */
+	@Path("request/login")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response processLogin(@QueryParam("code") String code, final MultivaluedMap<String, String> formData) {
+		event.event(EventType.LOGIN);
+		if (!checkSsl()) {
+			event.error(Errors.SSL_REQUIRED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
+		}
+
+		if (!realm.isEnabled()) {
+			event.error(Errors.REALM_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
+		}
+		ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
+		if (clientCode == null) {
+			event.error(Errors.INVALID_CODE);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+					"Unknown code, please login again through your application.");
+		}
+
+		ClientSessionModel clientSession = clientCode.getClientSession();
+		event.detail(Details.CODE_ID, clientSession.getId());
+
+		if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE) || clientSession.getUserSession() != null) {
+			clientCode.setAction(ClientSessionModel.Action.AUTHENTICATE);
+			event.client(clientSession.getClient()).error(Errors.EXPIRED_CODE);
+			return Flows.forms(this.session, realm, clientSession.getClient(), uriInfo).setError(Messages.EXPIRED_CODE)
+					.setClientSessionCode(clientCode.getCode()).createLogin();
+		}
+
+		String username = formData.getFirst(AuthenticationManager.FORM_USERNAME);
+
+		String rememberMe = formData.getFirst("rememberMe");
+		boolean remember = rememberMe != null && rememberMe.equalsIgnoreCase("on");
+
+		event.client(clientSession.getClient().getClientId()).detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
+				.detail(Details.RESPONSE_TYPE, "code").detail(Details.AUTH_METHOD, "form").detail(Details.USERNAME, username);
+
+		if (remember) {
+			event.detail(Details.REMEMBER_ME, "true");
+		}
+
+		ClientModel client = clientSession.getClient();
+		if (client == null) {
+			event.error(Errors.CLIENT_NOT_FOUND);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
+		}
+		if (!client.isEnabled()) {
+			event.error(Errors.CLIENT_NOT_FOUND);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
+		}
+
+		if (formData.containsKey("cancel")) {
+			event.error(Errors.REJECTED_BY_USER);
+			LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
+			protocol.setRealm(realm).setUriInfo(uriInfo);
+			return protocol.cancelLogin(clientSession);
+		}
+
+		AuthenticationManager.AuthenticationStatus status = authManager.authenticateForm(session, clientConnection, realm,
+				formData);
+
+		if (remember) {
+			authManager.createRememberMeCookie(realm, username, uriInfo, clientConnection);
+		} else {
+			authManager.expireRememberMeCookie(realm, uriInfo, clientConnection);
+		}
+
+		UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
+		if (user != null) {
+			event.user(user);
+		}
+
+		switch (status) {
+		case SUCCESS:
+		case ACTIONS_REQUIRED:
+			UserSessionModel userSession = session.sessions().createUserSession(realm, user, username,
+					clientConnection.getRemoteAddr(), "form", remember);
+			TokenManager.attachClientSession(userSession, clientSession);
+			event.session(userSession);
+			return authManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request,
+					uriInfo, event);
+		case ACCOUNT_TEMPORARILY_DISABLED:
+			event.error(Errors.USER_TEMPORARILY_DISABLED);
+			return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.ACCOUNT_TEMPORARILY_DISABLED)
+					.setFormData(formData).setClientSessionCode(clientCode.getCode()).createLogin();
+		case ACCOUNT_DISABLED:
+			event.error(Errors.USER_DISABLED);
+			return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.ACCOUNT_DISABLED)
+					.setClientSessionCode(clientCode.getCode()).setFormData(formData).createLogin();
+		case MISSING_TOTP:
+			formData.remove(CredentialRepresentation.PASSWORD);
+
+			String passwordToken = new JWSBuilder().jsonContent(new PasswordToken(realm.getName(), user.getId())).rsa256(
+					realm.getPrivateKey());
+			formData.add(CredentialRepresentation.PASSWORD_TOKEN, passwordToken);
+
+			return Flows.forms(this.session, realm, client, uriInfo).setFormData(formData)
+					.setClientSessionCode(clientCode.getCode()).createLoginTotp();
+		case INVALID_USER:
+			event.error(Errors.USER_NOT_FOUND);
+			return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER).setFormData(formData)
+					.setClientSessionCode(clientCode.getCode()).createLogin();
+		default:
+			event.error(Errors.INVALID_USER_CREDENTIALS);
+			return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER).setFormData(formData)
+					.setClientSessionCode(clientCode.getCode()).createLogin();
+		}
+	}
+
+	/**
+	 * Registration
+	 * 
+	 * @param code
+	 * @param formData
+	 * @return
+	 */
+	@Path("request/registration")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response processRegister(@QueryParam("code") String code, final MultivaluedMap<String, String> formData) {
+		event.event(EventType.REGISTER);
+		if (!checkSsl()) {
+			event.error(Errors.SSL_REQUIRED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
+		}
+
+		if (!realm.isEnabled()) {
+			event.error(Errors.REALM_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
+		}
+		if (!realm.isRegistrationAllowed()) {
+			event.error(Errors.REGISTRATION_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
+		}
+		ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
+		if (clientCode == null) {
+			event.error(Errors.INVALID_CODE);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+					"Unknown code, please login again through your application.");
+		}
+		if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
+			event.error(Errors.INVALID_CODE);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+					"Invalid code, please login again through your application.");
+		}
+
+		String username = formData.getFirst("username");
+		String email = formData.getFirst("email");
+		if (realm.isRegistrationEmailAsUsername()) {
+			username = email;
+			formData.putSingle(AuthenticationManager.FORM_USERNAME, username);
+		}
+		ClientSessionModel clientSession = clientCode.getClientSession();
+		event.client(clientSession.getClient()).detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
+				.detail(Details.RESPONSE_TYPE, "code").detail(Details.USERNAME, username).detail(Details.EMAIL, email)
+				.detail(Details.REGISTER_METHOD, "form");
+
+		if (!realm.isEnabled()) {
+			event.error(Errors.REALM_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled");
+		}
+		ClientModel client = clientSession.getClient();
+		if (client == null) {
+			event.error(Errors.CLIENT_NOT_FOUND);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
+		}
+
+		if (!client.isEnabled()) {
+			event.error(Errors.CLIENT_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
+		}
+
+		List<String> requiredCredentialTypes = new LinkedList<String>();
+		for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
+			requiredCredentialTypes.add(m.getType());
+		}
+
+		// Validate here, so user is not created if password doesn't validate to passwordPolicy of current realm
+		String error = Validation.validateRegistrationForm(realm, formData, requiredCredentialTypes);
+		if (error == null) {
+			error = Validation.validatePassword(formData, realm.getPasswordPolicy());
+		}
+
+		if (error != null) {
+			event.error(Errors.INVALID_REGISTRATION);
+			return Flows.forms(session, realm, client, uriInfo).setError(error).setFormData(formData)
+					.setClientSessionCode(clientCode.getCode()).createRegistration();
+		}
+
+		// Validate that user with this username doesn't exist in realm or any federation provider
+		if (session.users().getUserByUsername(username, realm) != null) {
+			event.error(Errors.USERNAME_IN_USE);
+			return Flows.forms(session, realm, client, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData)
+					.setClientSessionCode(clientCode.getCode()).createRegistration();
+		}
+
+		// Validate that user with this email doesn't exist in realm or any federation provider
+		if (session.users().getUserByEmail(email, realm) != null) {
+			event.error(Errors.EMAIL_IN_USE);
+			return Flows.forms(session, realm, client, uriInfo).setError(Messages.EMAIL_EXISTS).setFormData(formData)
+					.setClientSessionCode(clientCode.getCode()).createRegistration();
+		}
+
+		UserModel user = session.users().addUser(realm, username);
+		user.setEnabled(true);
+		user.setFirstName(formData.getFirst("firstName"));
+		user.setLastName(formData.getFirst("lastName"));
+
+		user.setEmail(email);
+
+		if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) {
+			UserCredentialModel credentials = new UserCredentialModel();
+			credentials.setType(CredentialRepresentation.PASSWORD);
+			credentials.setValue(formData.getFirst("password"));
+
+			boolean passwordUpdateSuccessful;
+			String passwordUpdateError = null;
+			try {
+				session.users().updateCredential(realm, user, UserCredentialModel.password(formData.getFirst("password")));
+				passwordUpdateSuccessful = true;
+			} catch (Exception ape) {
+				passwordUpdateSuccessful = false;
+				passwordUpdateError = ape.getMessage();
+			}
+
+			// User already registered, but force him to update password
+			if (!passwordUpdateSuccessful) {
+				user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+				return Flows.forms(session, realm, client, uriInfo).setError(passwordUpdateError)
+						.setClientSessionCode(clientCode.getCode()).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
+			}
+		}
+
+		AttributeFormDataProcessor.process(formData, realm, user);
+
+		event.user(user).success();
+		event.reset();
+
+		return processLogin(code, formData);
+	}
+
+	/**
+	 * OAuth grant page. You should not invoked this directly!
+	 * 
+	 * @param formData
+	 * @return
+	 */
+	@Path("consent")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response processConsent(final MultivaluedMap<String, String> formData) {
+		event.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code");
+
+		if (!checkSsl()) {
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
+		}
+
+		String code = formData.getFirst("code");
+
+		ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
+		if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) {
+			event.error(Errors.INVALID_CODE);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid access code.");
+		}
+		ClientSessionModel clientSession = accessCode.getClientSession();
+		event.detail(Details.CODE_ID, clientSession.getId());
+
+		String redirect = clientSession.getRedirectUri();
+
+		event.client(clientSession.getClient()).user(clientSession.getUserSession().getUser())
+				.detail(Details.RESPONSE_TYPE, "code").detail(Details.REDIRECT_URI, redirect);
+
+		UserSessionModel userSession = clientSession.getUserSession();
+		if (userSession != null) {
+			event.detail(Details.AUTH_METHOD, userSession.getAuthMethod());
+			event.detail(Details.USERNAME, userSession.getLoginUsername());
+			if (userSession.isRememberMe()) {
+				event.detail(Details.REMEMBER_ME, "true");
+			}
+		}
+
+		if (!AuthenticationManager.isSessionValid(realm, userSession)) {
+			AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
+			event.error(Errors.INVALID_CODE);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Session not active");
+		}
+		event.session(userSession);
+
+		LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
+		protocol.setRealm(realm).setUriInfo(uriInfo);
+		if (formData.containsKey("cancel")) {
+			event.error(Errors.REJECTED_BY_USER);
+			return protocol.consentDenied(clientSession);
+		}
+
+		event.success();
+
+		return authManager.redirectAfterSuccessfulFlow(session, realm, userSession, clientSession, request, uriInfo,
+				clientConnection);
+	}
+
+	@Path("profile")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response updateProfile(@QueryParam("code") String code, final MultivaluedMap<String, String> formData) {
+		event.event(EventType.UPDATE_PROFILE);
+		Checks checks = new Checks();
+		if (!checks.check(code, ClientSessionModel.Action.UPDATE_PROFILE)) {
+			return checks.response;
+		}
+		ClientSessionCode accessCode = checks.clientCode;
+		ClientSessionModel clientSession = accessCode.getClientSession();
+		UserSessionModel userSession = clientSession.getUserSession();
+		UserModel user = userSession.getUser();
+
+		initEvent(clientSession);
+
+		String error = Validation.validateUpdateProfileForm(formData);
+		if (error != null) {
+			return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(error)
+					.setClientSessionCode(accessCode.getCode()).createResponse(RequiredAction.UPDATE_PROFILE);
+		}
+
+		user.setFirstName(formData.getFirst("firstName"));
+		user.setLastName(formData.getFirst("lastName"));
+
+		String email = formData.getFirst("email");
+
+		String oldEmail = user.getEmail();
+		boolean emailChanged = oldEmail != null ? !oldEmail.equals(email) : email != null;
+
+		if (emailChanged) {
+			UserModel userByEmail = session.users().getUserByEmail(email, realm);
+
+			// check for duplicated email
+			if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
+				return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(Messages.EMAIL_EXISTS)
+						.setClientSessionCode(accessCode.getCode()).createResponse(RequiredAction.UPDATE_PROFILE);
+			}
+
+			user.setEmail(email);
+			user.setEmailVerified(false);
+		}
+
+		user.removeRequiredAction(RequiredAction.UPDATE_PROFILE);
+		event.clone().event(EventType.UPDATE_PROFILE).success();
+
+		if (emailChanged) {
+			event.clone().event(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, oldEmail)
+					.detail(Details.UPDATED_EMAIL, email).success();
+		}
+
+		return redirectOauth(user, accessCode, clientSession, userSession);
+	}
+
+	@Path("totp")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response updateTotp(@QueryParam("code") String code, final MultivaluedMap<String, String> formData) {
+		event.event(EventType.UPDATE_TOTP);
+		Checks checks = new Checks();
+		if (!checks.check(code, ClientSessionModel.Action.CONFIGURE_TOTP)) {
+			return checks.response;
+		}
+		ClientSessionCode accessCode = checks.clientCode;
+		ClientSessionModel clientSession = accessCode.getClientSession();
+		UserSessionModel userSession = clientSession.getUserSession();
+		UserModel user = userSession.getUser();
+
+		initEvent(clientSession);
+
+		String totp = formData.getFirst("totp");
+		String totpSecret = formData.getFirst("totpSecret");
+
+		LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
+		if (Validation.isEmpty(totp)) {
+			return loginForms.setError(Messages.MISSING_TOTP).setClientSessionCode(accessCode.getCode())
+					.createResponse(RequiredAction.CONFIGURE_TOTP);
+		} else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) {
+			return loginForms.setError(Messages.INVALID_TOTP).setClientSessionCode(accessCode.getCode())
+					.createResponse(RequiredAction.CONFIGURE_TOTP);
+		}
+
+		UserCredentialModel credentials = new UserCredentialModel();
+		credentials.setType(CredentialRepresentation.TOTP);
+		credentials.setValue(totpSecret);
+		session.users().updateCredential(realm, user, credentials);
+
+		user.setTotp(true);
+
+		user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP);
+
+		event.clone().event(EventType.UPDATE_TOTP).success();
+
+		return redirectOauth(user, accessCode, clientSession, userSession);
+	}
+
+	@Path("password")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response updatePassword(@QueryParam("code") String code, final MultivaluedMap<String, String> formData) {
+		event.event(EventType.UPDATE_PASSWORD);
+		Checks checks = new Checks();
+		if (!checks.check(code, ClientSessionModel.Action.UPDATE_PASSWORD, ClientSessionModel.Action.RECOVER_PASSWORD)) {
+			return checks.response;
+		}
+		ClientSessionCode accessCode = checks.clientCode;
+		ClientSessionModel clientSession = accessCode.getClientSession();
+		UserSessionModel userSession = clientSession.getUserSession();
+		UserModel user = userSession.getUser();
+
+		initEvent(clientSession);
+
+		String passwordNew = formData.getFirst("password-new");
+		String passwordConfirm = formData.getFirst("password-confirm");
+
+		LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
+		if (Validation.isEmpty(passwordNew)) {
+			return loginForms.setError(Messages.MISSING_PASSWORD).setClientSessionCode(accessCode.getCode())
+					.createResponse(RequiredAction.UPDATE_PASSWORD);
+		} else if (!passwordNew.equals(passwordConfirm)) {
+			return loginForms.setError(Messages.NOTMATCH_PASSWORD).setClientSessionCode(accessCode.getCode())
+					.createResponse(RequiredAction.UPDATE_PASSWORD);
+		}
+
+		try {
+			session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew));
+		} catch (Exception ape) {
+			return loginForms.setError(ape.getMessage()).setClientSessionCode(accessCode.getCode())
+					.createResponse(RequiredAction.UPDATE_PASSWORD);
+		}
+
+		user.removeRequiredAction(RequiredAction.UPDATE_PASSWORD);
+
+		event.event(EventType.UPDATE_PASSWORD).success();
+
+		if (clientSession.getAction().equals(ClientSessionModel.Action.RECOVER_PASSWORD)) {
+			String actionCookieValue = getActionCookie();
+			if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
+				return Flows.forms(session, realm, clientSession.getClient(), uriInfo).setSuccess("passwordUpdated")
+						.createInfoPage();
+			}
+		}
+
+		event = event.clone().event(EventType.LOGIN);
+
+		return redirectOauth(user, accessCode, clientSession, userSession);
+	}
+
+	@Path("email-verification")
+	@GET
+	public Response emailVerification(@QueryParam("code") String code, @QueryParam("key") String key) {
+		event.event(EventType.VERIFY_EMAIL);
+		if (key != null) {
+			Checks checks = new Checks();
+			if (!checks.check(key, ClientSessionModel.Action.VERIFY_EMAIL)) {
+				return checks.response;
+			}
+			ClientSessionCode accessCode = checks.clientCode;
+			ClientSessionModel clientSession = accessCode.getClientSession();
+			UserSessionModel userSession = clientSession.getUserSession();
+			UserModel user = userSession.getUser();
+			initEvent(clientSession);
+			user.setEmailVerified(true);
+
+			user.removeRequiredAction(RequiredAction.VERIFY_EMAIL);
+
+			event.event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();
+
+			String actionCookieValue = getActionCookie();
+			if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
+				return Flows.forms(session, realm, clientSession.getClient(), uriInfo).setSuccess("emailVerified")
+						.createInfoPage();
+			}
+
+			event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN);
+
+			return redirectOauth(user, accessCode, clientSession, userSession);
+		} else {
+			Checks checks = new Checks();
+			if (!checks.check(code, ClientSessionModel.Action.VERIFY_EMAIL)) {
+				return checks.response;
+			}
+			ClientSessionCode accessCode = checks.clientCode;
+			ClientSessionModel clientSession = accessCode.getClientSession();
+			UserSessionModel userSession = clientSession.getUserSession();
+			initEvent(clientSession);
+
+			createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
+
+			return Flows.forms(session, realm, null, uriInfo).setClientSessionCode(accessCode.getCode())
+					.setUser(userSession.getUser()).createResponse(RequiredAction.VERIFY_EMAIL);
+		}
+	}
+
+	@Path("password-reset")
+	@GET
+	public Response passwordReset(@QueryParam("code") String code, @QueryParam("key") String key) {
+		event.event(EventType.RESET_PASSWORD);
+		if (key != null) {
+			Checks checks = new Checks();
+			if (!checks.check(key, ClientSessionModel.Action.RECOVER_PASSWORD)) {
+				return checks.response;
+			}
+			ClientSessionCode accessCode = checks.clientCode;
+			return Flows.forms(session, realm, null, uriInfo).setClientSessionCode(accessCode.getCode())
+					.createResponse(RequiredAction.UPDATE_PASSWORD);
+		} else {
+			return Flows.forms(session, realm, null, uriInfo).setClientSessionCode(code).createPasswordReset();
+		}
+	}
+
+	@Path("password-reset")
+	@POST
+	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+	public Response sendPasswordReset(@QueryParam("code") String code, final MultivaluedMap<String, String> formData) {
+		event.event(EventType.SEND_RESET_PASSWORD);
+		if (!checkSsl()) {
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
+		}
+		if (!realm.isEnabled()) {
+			event.error(Errors.REALM_DISABLED);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
+		}
+		ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
+		if (accessCode == null) {
+			event.error(Errors.INVALID_CODE);
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
+					"Unknown code, please login again through your application.");
+		}
+		ClientSessionModel clientSession = accessCode.getClientSession();
+
+		String username = formData.getFirst("username");
+
+		ClientModel client = clientSession.getClient();
+		if (client == null) {
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
+		}
+		if (!client.isEnabled()) {
+			return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
+		}
+
+		event.client(client.getClientId()).detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
+				.detail(Details.RESPONSE_TYPE, "code").detail(Details.AUTH_METHOD, "form").detail(Details.USERNAME, username);
+
+		UserModel user = session.users().getUserByUsername(username, realm);
+		if (user == null && username.contains("@")) {
+			user = session.users().getUserByEmail(username, realm);
+		}
+
+		if (user == null) {
+			event.error(Errors.USER_NOT_FOUND);
+		} else if (!user.isEnabled()) {
+			event.user(user).error(Errors.USER_DISABLED);
+		} else if (user.getEmail() == null || user.getEmail().trim().length() == 0) {
+			event.user(user).error(Errors.INVALID_EMAIL);
+		} else {
+			event.user(user);
+
+			UserSessionModel userSession = session.sessions().createUserSession(realm, user, username,
+					clientConnection.getRemoteAddr(), "form", false);
+			event.session(userSession);
+			TokenManager.attachClientSession(userSession, clientSession);
+
+			accessCode.setAction(ClientSessionModel.Action.RECOVER_PASSWORD);
+
+			try {
+				UriBuilder builder = Urls.loginPasswordResetBuilder(uriInfo.getBaseUri());
+				builder.queryParam("key", accessCode.getCode());
+
+				String link = builder.build(realm.getName()).toString();
+				long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());
+
+				this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendPasswordReset(link, expiration);
+
+				event.detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, clientSession.getId()).success();
+			} catch (EmailException e) {
+				event.error(Errors.EMAIL_SEND_FAILED);
+				logger.error("Failed to send password reset email", e);
+				return Flows.forms(this.session, realm, client, uriInfo).setError("emailSendError")
+						.setClientSessionCode(accessCode.getCode()).createErrorPage();
+			}
+
+			createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
+		}
+
+		return Flows.forms(session, realm, client, uriInfo).setSuccess("emailSent")
+				.setClientSessionCode(accessCode.getCode()).createPasswordReset();
+	}
+
+	private String getActionCookie() {
+		Cookie cookie = headers.getCookies().get(ACTION_COOKIE);
+		AuthenticationManager.expireCookie(realm, ACTION_COOKIE, AuthenticationManager.getRealmCookiePath(realm, uriInfo),
+				realm.getSslRequired().isRequired(clientConnection), clientConnection);
+		return cookie != null ? cookie.getValue() : null;
+	}
+
+	public static void createActionCookie(RealmModel realm, UriInfo uriInfo, ClientConnection clientConnection,
+			String sessionId) {
+		CookieHelper.addCookie(ACTION_COOKIE, sessionId, AuthenticationManager.getRealmCookiePath(realm, uriInfo), null,
+				null, -1, realm.getSslRequired().isRequired(clientConnection), true);
+	}
+
+	private Response redirectOauth(UserModel user, ClientSessionCode accessCode, ClientSessionModel clientSession,
+			UserSessionModel userSession) {
+		return AuthenticationManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection,
+				request, uriInfo, event);
+	}
+
+	private void initEvent(ClientSessionModel clientSession) {
+		event.event(EventType.LOGIN).client(clientSession.getClient()).user(clientSession.getUserSession().getUser())
+				.session(clientSession.getUserSession().getId()).detail(Details.CODE_ID, clientSession.getId())
+				.detail(Details.REDIRECT_URI, clientSession.getRedirectUri()).detail(Details.RESPONSE_TYPE, "code");
+
+		UserSessionModel userSession = clientSession.getUserSession();
+
+		if (userSession != null) {
+			event.detail(Details.AUTH_METHOD, userSession.getAuthMethod());
+			event.detail(Details.USERNAME, userSession.getLoginUsername());
+			if (userSession.isRememberMe()) {
+				event.detail(Details.REMEMBER_ME, "true");
+			}
+		}
+	}
 }
diff --git a/services/src/main/java/org/keycloak/services/validation/Validation.java b/services/src/main/java/org/keycloak/services/validation/Validation.java
index a5a0f3f..e983037 100755
--- a/services/src/main/java/org/keycloak/services/validation/Validation.java
+++ b/services/src/main/java/org/keycloak/services/validation/Validation.java
@@ -1,83 +1,86 @@
 package org.keycloak.services.validation;
 
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.MultivaluedMap;
+
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.messages.Messages;
 
-import javax.ws.rs.core.MultivaluedMap;
-import java.util.List;
-import java.util.regex.Pattern;
-
 public class Validation {
 
-    // Actually allow same emails like angular. See ValidationTest.testEmailValidation()
-    private static final Pattern EMAIL_PATTERN = Pattern.compile("[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*");
-
-    public static String validateRegistrationForm(MultivaluedMap<String, String> formData, List<String> requiredCredentialTypes) {
-        if (isEmpty(formData.getFirst("firstName"))) {
-            return Messages.MISSING_FIRST_NAME;
-        }
+	// Actually allow same emails like angular. See ValidationTest.testEmailValidation()
+	private static final Pattern EMAIL_PATTERN = Pattern
+			.compile("[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*");
 
-        if (isEmpty(formData.getFirst("lastName"))) {
-            return Messages.MISSING_LAST_NAME;
-        }
+	public static String validateRegistrationForm(RealmModel realm, MultivaluedMap<String, String> formData,
+			List<String> requiredCredentialTypes) {
+		if (isEmpty(formData.getFirst("firstName"))) {
+			return Messages.MISSING_FIRST_NAME;
+		}
 
-        if (isEmpty(formData.getFirst("email"))) {
-            return Messages.MISSING_EMAIL;
-        }
+		if (isEmpty(formData.getFirst("lastName"))) {
+			return Messages.MISSING_LAST_NAME;
+		}
 
-        if (!isEmailValid(formData.getFirst("email"))) {
-            return Messages.INVALID_EMAIL;
-        }
+		if (isEmpty(formData.getFirst("email"))) {
+			return Messages.MISSING_EMAIL;
+		}
 
-        if (isEmpty(formData.getFirst("username"))) {
-            return Messages.MISSING_USERNAME;
-        }
+		if (!isEmailValid(formData.getFirst("email"))) {
+			return Messages.INVALID_EMAIL;
+		}
 
-        if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) {
-            if (isEmpty(formData.getFirst(CredentialRepresentation.PASSWORD))) {
-                return Messages.MISSING_PASSWORD;
-            }
+		if (!realm.isRegistrationEmailAsUsername() && isEmpty(formData.getFirst("username"))) {
+			return Messages.MISSING_USERNAME;
+		}
 
-            if (!formData.getFirst("password").equals(formData.getFirst("password-confirm"))) {
-                return Messages.INVALID_PASSWORD_CONFIRM;
-            }
-        }
+		if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) {
+			if (isEmpty(formData.getFirst(CredentialRepresentation.PASSWORD))) {
+				return Messages.MISSING_PASSWORD;
+			}
 
-        return null;
-    }
+			if (!formData.getFirst("password").equals(formData.getFirst("password-confirm"))) {
+				return Messages.INVALID_PASSWORD_CONFIRM;
+			}
+		}
 
-    public static String validatePassword(MultivaluedMap<String, String> formData, PasswordPolicy policy) {
-        return policy.validate(formData.getFirst("password"));
-    }
+		return null;
+	}
 
-    public static String validateUpdateProfileForm(MultivaluedMap<String, String> formData) {
-        if (isEmpty(formData.getFirst("firstName"))) {
-            return Messages.MISSING_FIRST_NAME;
-        }
+	public static String validatePassword(MultivaluedMap<String, String> formData, PasswordPolicy policy) {
+		return policy.validate(formData.getFirst("password"));
+	}
 
-        if (isEmpty(formData.getFirst("lastName"))) {
-            return Messages.MISSING_LAST_NAME;
-        }
+	public static String validateUpdateProfileForm(MultivaluedMap<String, String> formData) {
+		if (isEmpty(formData.getFirst("firstName"))) {
+			return Messages.MISSING_FIRST_NAME;
+		}
 
-        if (isEmpty(formData.getFirst("email"))) {
-            return Messages.MISSING_EMAIL;
-        }
+		if (isEmpty(formData.getFirst("lastName"))) {
+			return Messages.MISSING_LAST_NAME;
+		}
 
-        if (!isEmailValid(formData.getFirst("email"))) {
-            return Messages.INVALID_EMAIL;
-        }
+		if (isEmpty(formData.getFirst("email"))) {
+			return Messages.MISSING_EMAIL;
+		}
 
-        return null;
-    }
+		if (!isEmailValid(formData.getFirst("email"))) {
+			return Messages.INVALID_EMAIL;
+		}
 
-    public static boolean isEmpty(String s) {
-        return s == null || s.length() == 0;
-    }
+		return null;
+	}
 
-    public static boolean isEmailValid(String email) {
-        return EMAIL_PATTERN.matcher(email).matches();
-    }
+	public static boolean isEmpty(String s) {
+		return s == null || s.length() == 0;
+	}
 
+	public static boolean isEmailValid(String email) {
+		return EMAIL_PATTERN.matcher(email).matches();
+	}
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
index 100f9c1..d3ff943 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -21,6 +21,21 @@
  */
 package org.keycloak.testsuite.admin;
 
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Test;
@@ -41,252 +56,275 @@ import org.keycloak.services.resources.admin.AdminRoot;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 import org.keycloak.testutils.KeycloakServer;
 
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 /**
  * Tests Undertow Adapter
- *
+ * 
  * @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
  */
 public class AdminAPITest {
 
-    @ClassRule
-    public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
-        @Override
-        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
-        }
-    };
-
-    private static String createToken() {
-        KeycloakSession session = keycloakRule.startSession();
-        try {
-            RealmManager manager = new RealmManager(session);
-
-            RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
-            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
-            TokenManager tm = new TokenManager();
-            UserModel admin = session.users().getUserByUsername("admin", adminRealm);
-            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false);
-            AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm, adminConsole, admin, userSession, null);
-            return tm.encodeToken(adminRealm, token);
-        } finally {
-            keycloakRule.stopSession(session, true);
-        }
-    }
-
-    protected void testCreateRealm(RealmRepresentation rep) {
-        String token = createToken();
-        final String authHeader = "Bearer " + token;
-        ClientRequestFilter authFilter = new ClientRequestFilter() {
-            @Override
-            public void filter(ClientRequestContext requestContext) throws IOException {
-                requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
-            }
-        };
-        Client client = ClientBuilder.newBuilder().register(authFilter).build();
-        UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
-        WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
-        String realmName = rep.getRealm();
-        WebTarget realmTarget = adminRealms.path(realmName);
-
-
-        // create with just name, enabled, and id, just like admin console
-        RealmRepresentation newRep = new RealmRepresentation();
-        newRep.setRealm(rep.getRealm());
-        newRep.setEnabled(rep.isEnabled());
-        {
-            Response response = adminRealms.request().post(Entity.json(newRep));
-            Assert.assertEquals(201, response.getStatus());
-            response.close();
-        }
-        // todo test with full import with initial create
-        RealmRepresentation storedRealm = realmTarget.request().get(RealmRepresentation.class);
-        checkRealmRep(newRep, storedRealm);
-
-        Response updateResponse = realmTarget.request().put(Entity.json(rep));
-        Assert.assertEquals(204, updateResponse.getStatus());
-        updateResponse.close();
-        storedRealm = realmTarget.request().get(RealmRepresentation.class);
-        checkRealmRep(rep, storedRealm);
-
-        if (rep.getApplications() != null) {
-            WebTarget applicationsTarget = realmTarget.path("applications");
-            for (ApplicationRepresentation appRep : rep.getApplications()) {
-                ApplicationRepresentation newApp = new ApplicationRepresentation();
-                if (appRep.getId() != null) newApp.setId(appRep.getId());
-                newApp.setName(appRep.getName());
-                if (appRep.getSecret() != null) {
-                    newApp.setSecret(appRep.getSecret());
-                }
-                Response appCreateResponse = applicationsTarget.request().post(Entity.json(newApp));
-                Assert.assertEquals(201, appCreateResponse.getStatus());
-                appCreateResponse.close();
-                WebTarget appTarget = applicationsTarget.path(appRep.getName());
-                CredentialRepresentation cred = appTarget.path("client-secret").request().get(CredentialRepresentation.class);
-                if (appRep.getSecret() != null) Assert.assertEquals(appRep.getSecret(), cred.getValue());
-                CredentialRepresentation newCred = appTarget.path("client-secret").request().post(null, CredentialRepresentation.class);
-                Assert.assertNotEquals(newCred.getValue(), cred.getValue());
-
-                Response appUpdateResponse = appTarget.request().put(Entity.json(appRep));
-                Assert.assertEquals(204, appUpdateResponse.getStatus());
-                appUpdateResponse.close();
-
-
-                ApplicationRepresentation storedApp = appTarget.request().get(ApplicationRepresentation.class);
-
-                checkAppUpdate(appRep, storedApp);
-
-            }
-        }
-
-        // delete realm
-        {
-            Response response = adminRealms.path(realmName).request().delete();
-            Assert.assertEquals(204, response.getStatus());
-            response.close();
-
-        }
-        client.close();
-    }
-
-    protected void checkAppUpdate(ApplicationRepresentation appRep, ApplicationRepresentation storedApp) {
-        if (appRep.getName() != null) Assert.assertEquals(appRep.getName(), storedApp.getName());
-        if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled());
-        if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly());
-        if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient());
-        if (appRep.isFullScopeAllowed() != null) Assert.assertEquals(appRep.isFullScopeAllowed(), storedApp.isFullScopeAllowed());
-        if (appRep.getAdminUrl() != null) Assert.assertEquals(appRep.getAdminUrl(), storedApp.getAdminUrl());
-        if (appRep.getBaseUrl() != null) Assert.assertEquals(appRep.getBaseUrl(), storedApp.getBaseUrl());
-        if (appRep.isSurrogateAuthRequired() != null) Assert.assertEquals(appRep.isSurrogateAuthRequired(), storedApp.isSurrogateAuthRequired());
-
-        if (appRep.getNotBefore() != null) {
-            Assert.assertEquals(appRep.getNotBefore(), storedApp.getNotBefore());
-        }
-        if (appRep.getDefaultRoles() != null) {
-            Set<String> set = new HashSet<String>();
-            for (String val : appRep.getDefaultRoles()) {
-                set.add(val);
-            }
-            Set<String> storedSet = new HashSet<String>();
-            for (String val : storedApp.getDefaultRoles()) {
-                storedSet.add(val);
-            }
-
-            Assert.assertEquals(set, storedSet);
-        }
-
-        List<String> redirectUris = appRep.getRedirectUris();
-        if (redirectUris != null) {
-            Set<String> set = new HashSet<String>();
-            for (String val : appRep.getRedirectUris()) {
-                set.add(val);
-            }
-            Set<String> storedSet = new HashSet<String>();
-            for (String val : storedApp.getRedirectUris()) {
-                storedSet.add(val);
-            }
-
-            Assert.assertEquals(set, storedSet);
-        }
-
-        List<String> webOrigins = appRep.getWebOrigins();
-        if (webOrigins != null) {
-            Set<String> set = new HashSet<String>();
-            for (String val : appRep.getWebOrigins()) {
-                set.add(val);
-            }
-            Set<String> storedSet = new HashSet<String>();
-            for (String val : storedApp.getWebOrigins()) {
-                storedSet.add(val);
-            }
-
-            Assert.assertEquals(set, storedSet);
-        }
-    }
-
-    protected void checkRealmRep(RealmRepresentation rep, RealmRepresentation storedRealm) {
-        if (rep.getId() != null) {
-            Assert.assertEquals(rep.getId(), storedRealm.getId());
-        }
-        if (rep.getRealm() != null) {
-            Assert.assertEquals(rep.getRealm(), storedRealm.getRealm());
-        }
-        if (rep.isEnabled() != null) Assert.assertEquals(rep.isEnabled(), storedRealm.isEnabled());
-        if (rep.isBruteForceProtected() != null) Assert.assertEquals(rep.isBruteForceProtected(), storedRealm.isBruteForceProtected());
-        if (rep.getMaxFailureWaitSeconds() != null) Assert.assertEquals(rep.getMaxFailureWaitSeconds(), storedRealm.getMaxFailureWaitSeconds());
-        if (rep.getMinimumQuickLoginWaitSeconds() != null) Assert.assertEquals(rep.getMinimumQuickLoginWaitSeconds(), storedRealm.getMinimumQuickLoginWaitSeconds());
-        if (rep.getWaitIncrementSeconds() != null) Assert.assertEquals(rep.getWaitIncrementSeconds(), storedRealm.getWaitIncrementSeconds());
-        if (rep.getQuickLoginCheckMilliSeconds() != null) Assert.assertEquals(rep.getQuickLoginCheckMilliSeconds(), storedRealm.getQuickLoginCheckMilliSeconds());
-        if (rep.getMaxDeltaTimeSeconds() != null) Assert.assertEquals(rep.getMaxDeltaTimeSeconds(), storedRealm.getMaxDeltaTimeSeconds());
-        if (rep.getFailureFactor() != null) Assert.assertEquals(rep.getFailureFactor(), storedRealm.getFailureFactor());
-        if (rep.isPasswordCredentialGrantAllowed() != null) Assert.assertEquals(rep.isPasswordCredentialGrantAllowed(), storedRealm.isPasswordCredentialGrantAllowed());
-        if (rep.isRegistrationAllowed() != null) Assert.assertEquals(rep.isRegistrationAllowed(), storedRealm.isRegistrationAllowed());
-        if (rep.isRememberMe() != null) Assert.assertEquals(rep.isRememberMe(), storedRealm.isRememberMe());
-        if (rep.isVerifyEmail() != null) Assert.assertEquals(rep.isVerifyEmail(), storedRealm.isVerifyEmail());
-        if (rep.isResetPasswordAllowed() != null) Assert.assertEquals(rep.isResetPasswordAllowed(), storedRealm.isResetPasswordAllowed());
-        if (rep.getSslRequired() != null) Assert.assertEquals(rep.getSslRequired(), storedRealm.getSslRequired());
-        if (rep.getAccessCodeLifespan() != null) Assert.assertEquals(rep.getAccessCodeLifespan(), storedRealm.getAccessCodeLifespan());
-        if (rep.getAccessCodeLifespanUserAction() != null)
-            Assert.assertEquals(rep.getAccessCodeLifespanUserAction(), storedRealm.getAccessCodeLifespanUserAction());
-        if (rep.getNotBefore() != null) Assert.assertEquals(rep.getNotBefore(), storedRealm.getNotBefore());
-        if (rep.getAccessTokenLifespan() != null) Assert.assertEquals(rep.getAccessTokenLifespan(), storedRealm.getAccessTokenLifespan());
-        if (rep.getSsoSessionIdleTimeout() != null) Assert.assertEquals(rep.getSsoSessionIdleTimeout(), storedRealm.getSsoSessionIdleTimeout());
-        if (rep.getSsoSessionMaxLifespan() != null) Assert.assertEquals(rep.getSsoSessionMaxLifespan(), storedRealm.getSsoSessionMaxLifespan());
-        if (rep.getRequiredCredentials() != null) {
-            Assert.assertNotNull(storedRealm.getRequiredCredentials());
-            for (String cred : rep.getRequiredCredentials()) {
-                Assert.assertTrue(storedRealm.getRequiredCredentials().contains(cred));
-            }
-        }
-        if (rep.getLoginTheme() != null) Assert.assertEquals(rep.getLoginTheme(), storedRealm.getLoginTheme());
-        if (rep.getAccountTheme() != null) Assert.assertEquals(rep.getAccountTheme(), storedRealm.getAccountTheme());
-        if (rep.getAdminTheme() != null) Assert.assertEquals(rep.getAdminTheme(), storedRealm.getAdminTheme());
-        if (rep.getEmailTheme() != null) Assert.assertEquals(rep.getEmailTheme(), storedRealm.getEmailTheme());
-
-        if (rep.getPasswordPolicy() != null) Assert.assertEquals(rep.getPasswordPolicy(), storedRealm.getPasswordPolicy());
-
-        if (rep.getDefaultRoles() != null) {
-            Assert.assertNotNull(storedRealm.getDefaultRoles());
-            for (String role : rep.getDefaultRoles()) {
-                Assert.assertTrue(storedRealm.getDefaultRoles().contains(role));
-            }
-        }
-
-        if (rep.getSmtpServer() != null) {
-            Assert.assertEquals(rep.getSmtpServer(), storedRealm.getSmtpServer());
-        }
-
-        if (rep.getBrowserSecurityHeaders() != null) {
-            Assert.assertEquals(rep.getBrowserSecurityHeaders(), storedRealm.getBrowserSecurityHeaders());
-        }
-
-    }
-
-    protected void testCreateRealm(String path) {
-        RealmRepresentation rep = KeycloakServer.loadJson(getClass().getResourceAsStream(path), RealmRepresentation.class);
-        Assert.assertNotNull(rep);
-        testCreateRealm(rep);
-    }
-
-    @Test
-    public void testAdminApi() {
-        RealmRepresentation empty = new RealmRepresentation();
-        empty.setEnabled(true);
-        empty.setRealm("empty");
-        testCreateRealm(empty);
-        testCreateRealm("/admin-test/testrealm.json");
-    }
+	@ClassRule
+	public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
+		@Override
+		protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
+		}
+	};
+
+	private static String createToken() {
+		KeycloakSession session = keycloakRule.startSession();
+		try {
+			RealmManager manager = new RealmManager(session);
+
+			RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
+			ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+			TokenManager tm = new TokenManager();
+			UserModel admin = session.users().getUserByUsername("admin", adminRealm);
+			UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form",
+					false);
+			AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, adminConsole, admin), adminRealm,
+					adminConsole, admin, userSession, null);
+			return tm.encodeToken(adminRealm, token);
+		} finally {
+			keycloakRule.stopSession(session, true);
+		}
+	}
+
+	protected void testCreateRealm(RealmRepresentation rep) {
+		String token = createToken();
+		final String authHeader = "Bearer " + token;
+		ClientRequestFilter authFilter = new ClientRequestFilter() {
+			@Override
+			public void filter(ClientRequestContext requestContext) throws IOException {
+				requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
+			}
+		};
+		Client client = ClientBuilder.newBuilder().register(authFilter).build();
+		UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
+		WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
+		String realmName = rep.getRealm();
+		WebTarget realmTarget = adminRealms.path(realmName);
+
+		// create with just name, enabled, and id, just like admin console
+		RealmRepresentation newRep = new RealmRepresentation();
+		newRep.setRealm(rep.getRealm());
+		newRep.setEnabled(rep.isEnabled());
+		{
+			Response response = adminRealms.request().post(Entity.json(newRep));
+			Assert.assertEquals(201, response.getStatus());
+			response.close();
+		}
+		// todo test with full import with initial create
+		RealmRepresentation storedRealm = realmTarget.request().get(RealmRepresentation.class);
+		checkRealmRep(newRep, storedRealm);
+
+		Response updateResponse = realmTarget.request().put(Entity.json(rep));
+		Assert.assertEquals(204, updateResponse.getStatus());
+		updateResponse.close();
+		storedRealm = realmTarget.request().get(RealmRepresentation.class);
+		checkRealmRep(rep, storedRealm);
+
+		if (rep.getApplications() != null) {
+			WebTarget applicationsTarget = realmTarget.path("applications");
+			for (ApplicationRepresentation appRep : rep.getApplications()) {
+				ApplicationRepresentation newApp = new ApplicationRepresentation();
+				if (appRep.getId() != null)
+					newApp.setId(appRep.getId());
+				newApp.setName(appRep.getName());
+				if (appRep.getSecret() != null) {
+					newApp.setSecret(appRep.getSecret());
+				}
+				Response appCreateResponse = applicationsTarget.request().post(Entity.json(newApp));
+				Assert.assertEquals(201, appCreateResponse.getStatus());
+				appCreateResponse.close();
+				WebTarget appTarget = applicationsTarget.path(appRep.getName());
+				CredentialRepresentation cred = appTarget.path("client-secret").request().get(CredentialRepresentation.class);
+				if (appRep.getSecret() != null)
+					Assert.assertEquals(appRep.getSecret(), cred.getValue());
+				CredentialRepresentation newCred = appTarget.path("client-secret").request()
+						.post(null, CredentialRepresentation.class);
+				Assert.assertNotEquals(newCred.getValue(), cred.getValue());
+
+				Response appUpdateResponse = appTarget.request().put(Entity.json(appRep));
+				Assert.assertEquals(204, appUpdateResponse.getStatus());
+				appUpdateResponse.close();
+
+				ApplicationRepresentation storedApp = appTarget.request().get(ApplicationRepresentation.class);
+
+				checkAppUpdate(appRep, storedApp);
+
+			}
+		}
+
+		// delete realm
+		{
+			Response response = adminRealms.path(realmName).request().delete();
+			Assert.assertEquals(204, response.getStatus());
+			response.close();
+
+		}
+		client.close();
+	}
+
+	protected void checkAppUpdate(ApplicationRepresentation appRep, ApplicationRepresentation storedApp) {
+		if (appRep.getName() != null)
+			Assert.assertEquals(appRep.getName(), storedApp.getName());
+		if (appRep.isEnabled() != null)
+			Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled());
+		if (appRep.isBearerOnly() != null)
+			Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly());
+		if (appRep.isPublicClient() != null)
+			Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient());
+		if (appRep.isFullScopeAllowed() != null)
+			Assert.assertEquals(appRep.isFullScopeAllowed(), storedApp.isFullScopeAllowed());
+		if (appRep.getAdminUrl() != null)
+			Assert.assertEquals(appRep.getAdminUrl(), storedApp.getAdminUrl());
+		if (appRep.getBaseUrl() != null)
+			Assert.assertEquals(appRep.getBaseUrl(), storedApp.getBaseUrl());
+		if (appRep.isSurrogateAuthRequired() != null)
+			Assert.assertEquals(appRep.isSurrogateAuthRequired(), storedApp.isSurrogateAuthRequired());
+
+		if (appRep.getNotBefore() != null) {
+			Assert.assertEquals(appRep.getNotBefore(), storedApp.getNotBefore());
+		}
+		if (appRep.getDefaultRoles() != null) {
+			Set<String> set = new HashSet<String>();
+			for (String val : appRep.getDefaultRoles()) {
+				set.add(val);
+			}
+			Set<String> storedSet = new HashSet<String>();
+			for (String val : storedApp.getDefaultRoles()) {
+				storedSet.add(val);
+			}
+
+			Assert.assertEquals(set, storedSet);
+		}
+
+		List<String> redirectUris = appRep.getRedirectUris();
+		if (redirectUris != null) {
+			Set<String> set = new HashSet<String>();
+			for (String val : appRep.getRedirectUris()) {
+				set.add(val);
+			}
+			Set<String> storedSet = new HashSet<String>();
+			for (String val : storedApp.getRedirectUris()) {
+				storedSet.add(val);
+			}
+
+			Assert.assertEquals(set, storedSet);
+		}
+
+		List<String> webOrigins = appRep.getWebOrigins();
+		if (webOrigins != null) {
+			Set<String> set = new HashSet<String>();
+			for (String val : appRep.getWebOrigins()) {
+				set.add(val);
+			}
+			Set<String> storedSet = new HashSet<String>();
+			for (String val : storedApp.getWebOrigins()) {
+				storedSet.add(val);
+			}
+
+			Assert.assertEquals(set, storedSet);
+		}
+	}
+
+	protected void checkRealmRep(RealmRepresentation rep, RealmRepresentation storedRealm) {
+		if (rep.getId() != null) {
+			Assert.assertEquals(rep.getId(), storedRealm.getId());
+		}
+		if (rep.getRealm() != null) {
+			Assert.assertEquals(rep.getRealm(), storedRealm.getRealm());
+		}
+		if (rep.isEnabled() != null)
+			Assert.assertEquals(rep.isEnabled(), storedRealm.isEnabled());
+		if (rep.isBruteForceProtected() != null)
+			Assert.assertEquals(rep.isBruteForceProtected(), storedRealm.isBruteForceProtected());
+		if (rep.getMaxFailureWaitSeconds() != null)
+			Assert.assertEquals(rep.getMaxFailureWaitSeconds(), storedRealm.getMaxFailureWaitSeconds());
+		if (rep.getMinimumQuickLoginWaitSeconds() != null)
+			Assert.assertEquals(rep.getMinimumQuickLoginWaitSeconds(), storedRealm.getMinimumQuickLoginWaitSeconds());
+		if (rep.getWaitIncrementSeconds() != null)
+			Assert.assertEquals(rep.getWaitIncrementSeconds(), storedRealm.getWaitIncrementSeconds());
+		if (rep.getQuickLoginCheckMilliSeconds() != null)
+			Assert.assertEquals(rep.getQuickLoginCheckMilliSeconds(), storedRealm.getQuickLoginCheckMilliSeconds());
+		if (rep.getMaxDeltaTimeSeconds() != null)
+			Assert.assertEquals(rep.getMaxDeltaTimeSeconds(), storedRealm.getMaxDeltaTimeSeconds());
+		if (rep.getFailureFactor() != null)
+			Assert.assertEquals(rep.getFailureFactor(), storedRealm.getFailureFactor());
+		if (rep.isPasswordCredentialGrantAllowed() != null)
+			Assert.assertEquals(rep.isPasswordCredentialGrantAllowed(), storedRealm.isPasswordCredentialGrantAllowed());
+		if (rep.isRegistrationAllowed() != null)
+			Assert.assertEquals(rep.isRegistrationAllowed(), storedRealm.isRegistrationAllowed());
+		if (rep.isRegistrationEmailAsUsername() != null)
+			Assert.assertEquals(rep.isRegistrationEmailAsUsername(), storedRealm.isRegistrationEmailAsUsername());
+		if (rep.isRememberMe() != null)
+			Assert.assertEquals(rep.isRememberMe(), storedRealm.isRememberMe());
+		if (rep.isVerifyEmail() != null)
+			Assert.assertEquals(rep.isVerifyEmail(), storedRealm.isVerifyEmail());
+		if (rep.isResetPasswordAllowed() != null)
+			Assert.assertEquals(rep.isResetPasswordAllowed(), storedRealm.isResetPasswordAllowed());
+		if (rep.getSslRequired() != null)
+			Assert.assertEquals(rep.getSslRequired(), storedRealm.getSslRequired());
+		if (rep.getAccessCodeLifespan() != null)
+			Assert.assertEquals(rep.getAccessCodeLifespan(), storedRealm.getAccessCodeLifespan());
+		if (rep.getAccessCodeLifespanUserAction() != null)
+			Assert.assertEquals(rep.getAccessCodeLifespanUserAction(), storedRealm.getAccessCodeLifespanUserAction());
+		if (rep.getNotBefore() != null)
+			Assert.assertEquals(rep.getNotBefore(), storedRealm.getNotBefore());
+		if (rep.getAccessTokenLifespan() != null)
+			Assert.assertEquals(rep.getAccessTokenLifespan(), storedRealm.getAccessTokenLifespan());
+		if (rep.getSsoSessionIdleTimeout() != null)
+			Assert.assertEquals(rep.getSsoSessionIdleTimeout(), storedRealm.getSsoSessionIdleTimeout());
+		if (rep.getSsoSessionMaxLifespan() != null)
+			Assert.assertEquals(rep.getSsoSessionMaxLifespan(), storedRealm.getSsoSessionMaxLifespan());
+		if (rep.getRequiredCredentials() != null) {
+			Assert.assertNotNull(storedRealm.getRequiredCredentials());
+			for (String cred : rep.getRequiredCredentials()) {
+				Assert.assertTrue(storedRealm.getRequiredCredentials().contains(cred));
+			}
+		}
+		if (rep.getLoginTheme() != null)
+			Assert.assertEquals(rep.getLoginTheme(), storedRealm.getLoginTheme());
+		if (rep.getAccountTheme() != null)
+			Assert.assertEquals(rep.getAccountTheme(), storedRealm.getAccountTheme());
+		if (rep.getAdminTheme() != null)
+			Assert.assertEquals(rep.getAdminTheme(), storedRealm.getAdminTheme());
+		if (rep.getEmailTheme() != null)
+			Assert.assertEquals(rep.getEmailTheme(), storedRealm.getEmailTheme());
+
+		if (rep.getPasswordPolicy() != null)
+			Assert.assertEquals(rep.getPasswordPolicy(), storedRealm.getPasswordPolicy());
+
+		if (rep.getDefaultRoles() != null) {
+			Assert.assertNotNull(storedRealm.getDefaultRoles());
+			for (String role : rep.getDefaultRoles()) {
+				Assert.assertTrue(storedRealm.getDefaultRoles().contains(role));
+			}
+		}
+
+		if (rep.getSmtpServer() != null) {
+			Assert.assertEquals(rep.getSmtpServer(), storedRealm.getSmtpServer());
+		}
+
+		if (rep.getBrowserSecurityHeaders() != null) {
+			Assert.assertEquals(rep.getBrowserSecurityHeaders(), storedRealm.getBrowserSecurityHeaders());
+		}
+
+	}
+
+	protected void testCreateRealm(String path) {
+		RealmRepresentation rep = KeycloakServer.loadJson(getClass().getResourceAsStream(path), RealmRepresentation.class);
+		Assert.assertNotNull(rep);
+		testCreateRealm(rep);
+	}
+
+	@Test
+	public void testAdminApi() {
+		RealmRepresentation empty = new RealmRepresentation();
+		empty.setEnabled(true);
+		empty.setRealm("empty");
+		testCreateRealm(empty);
+		testCreateRealm("/admin-test/testrealm.json");
+	}
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ModelTest.java
index 30807a4..9e2147d 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ModelTest.java
@@ -1,5 +1,7 @@
 package org.keycloak.testsuite.model;
 
+import java.util.HashMap;
+
 import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.enums.SslRequired;
@@ -9,67 +11,67 @@ import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 
-import java.util.HashMap;
-
 public class ModelTest extends AbstractModelTest {
 
-    @Test
-    public void importExportRealm() {
-        RealmModel realm = realmManager.createRealm("original");
-        realm.setRegistrationAllowed(true);
-        realm.setResetPasswordAllowed(true);
-        realm.setSslRequired(SslRequired.EXTERNAL);
-        realm.setVerifyEmail(true);
-        realm.setAccessTokenLifespan(1000);
-        realm.setPasswordPolicy(new PasswordPolicy("length"));
-        realm.setAccessCodeLifespan(1001);
-        realm.setAccessCodeLifespanUserAction(1002);
-        KeycloakModelUtils.generateRealmKeys(realm);
-        realm.addDefaultRole("default-role");
+	@Test
+	public void importExportRealm() {
+		RealmModel realm = realmManager.createRealm("original");
+		realm.setRegistrationAllowed(true);
+		realm.setRegistrationEmailAsUsername(true);
+		realm.setResetPasswordAllowed(true);
+		realm.setSslRequired(SslRequired.EXTERNAL);
+		realm.setVerifyEmail(true);
+		realm.setAccessTokenLifespan(1000);
+		realm.setPasswordPolicy(new PasswordPolicy("length"));
+		realm.setAccessCodeLifespan(1001);
+		realm.setAccessCodeLifespanUserAction(1002);
+		KeycloakModelUtils.generateRealmKeys(realm);
+		realm.addDefaultRole("default-role");
 
-        HashMap<String, String> smtp = new HashMap<String,String>();
-        smtp.put("from", "auto@keycloak");
-        smtp.put("hostname", "localhost");
-        realm.setSmtpConfig(smtp);
+		HashMap<String, String> smtp = new HashMap<String, String>();
+		smtp.put("from", "auto@keycloak");
+		smtp.put("hostname", "localhost");
+		realm.setSmtpConfig(smtp);
 
-        HashMap<String, String> social = new HashMap<String,String>();
-        social.put("google.key", "1234");
-        social.put("google.secret", "5678");
-        //FIXME: KEYCLOAK-883
-//        realm.setSocialConfig(social);
+		HashMap<String, String> social = new HashMap<String, String>();
+		social.put("google.key", "1234");
+		social.put("google.secret", "5678");
+		// FIXME: KEYCLOAK-883
+		// realm.setSocialConfig(social);
 
-        RealmModel persisted = realmManager.getRealm(realm.getId());
-        assertEquals(realm, persisted);
+		RealmModel persisted = realmManager.getRealm(realm.getId());
+		assertEquals(realm, persisted);
 
-        RealmModel copy = importExport(realm, "copy");
-        assertEquals(realm, copy);
-    }
+		RealmModel copy = importExport(realm, "copy");
+		assertEquals(realm, copy);
+	}
 
-    public static void assertEquals(RealmModel expected, RealmModel actual) {
-        Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
-        Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
-        Assert.assertEquals(expected.getSslRequired(), actual.getSslRequired());
-        Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
-        Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());
+	public static void assertEquals(RealmModel expected, RealmModel actual) {
+		Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
+		Assert.assertEquals(expected.isRegistrationEmailAsUsername(), actual.isRegistrationEmailAsUsername());
+		Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
+		Assert.assertEquals(expected.getSslRequired(), actual.getSslRequired());
+		Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
+		Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());
 
-        Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan());
-        Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction());
-        Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem());
-        Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem());
+		Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan());
+		Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction());
+		Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem());
+		Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem());
 
-        Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
+		Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
 
-        Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig());
-        //FIXME: KEYCLOAK-883
-//        Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig());
-    }
+		Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig());
+		// FIXME: KEYCLOAK-883
+		// Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig());
+	}
 
-    private RealmModel importExport(RealmModel src, String copyName) {
-        RealmRepresentation representation = ModelToRepresentation.toRepresentation(src, true);
-        representation.setRealm(copyName);
-        representation.setId(copyName);
-        RealmModel copy = realmManager.importRealm(representation);
-        return realmManager.getRealm(copy.getId());
-    }
+	private RealmModel importExport(RealmModel src, String copyName) {
+		RealmRepresentation representation = ModelToRepresentation.toRepresentation(src, true);
+		representation.setRealm(copyName);
+		representation.setId(copyName);
+		RealmModel copy = realmManager.importRealm(representation);
+		return realmManager.getRealm(copy.getId());
+	}
 
 }
diff --git a/testsuite/integration/src/test/resources/admin-test/testrealm.json b/testsuite/integration/src/test/resources/admin-test/testrealm.json
index 55a2fe1..e4adb40 100755
--- a/testsuite/integration/src/test/resources/admin-test/testrealm.json
+++ b/testsuite/integration/src/test/resources/admin-test/testrealm.json
@@ -3,6 +3,7 @@
     "enabled": true,
     "sslRequired": "external",
     "registrationAllowed": true,
+    "registrationEmailAsUsername": true,
     "resetPasswordAllowed": true,
     "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
     "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",