keycloak-aplcache

KEYCLOAK-1187 First round: Combined ApplicationModel and

4/9/2015 5:01:42 AM

Changes

forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/oauth-clients.js 611(+0 -611)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-claims.html 19(+0 -19)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-credentials.html 29(+0 -29)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-detail.html 116(+0 -116)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-identity-provider.html 31(+0 -31)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-installation.html 26(+0 -26)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-list.html 55(+0 -55)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers.html 47(+0 -47)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-mappers-add.html 49(+0 -49)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-protocol-mapper-detail.html 108(+0 -108)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-revocation.html 29(+0 -29)

forms/common-themes/src/main/resources/theme/base/admin/resources/partials/oauth-client-scope-mappings.html 124(+0 -124)

forms/common-themes/src/main/resources/theme/base/admin/resources/templates/kc-navigation-oauth-client.html 9(+0 -9)

integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java 57(+0 -57)

integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientsResource.java 30(+0 -30)

model/api/src/main/java/org/keycloak/models/ApplicationModel.java 56(+0 -56)

model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java 154(+0 -154)

model/api/src/main/java/org/keycloak/models/entities/OAuthClientEntity.java 16(+0 -16)

model/api/src/main/java/org/keycloak/models/OAuthClientModel.java 10(+0 -10)

model/file/src/main/java/org/keycloak/models/file/adapter/ApplicationAdapter.java 322(+0 -322)

model/file/src/main/java/org/keycloak/models/file/adapter/OAuthClientAdapter.java 45(+0 -45)

model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ApplicationAdapter.java 247(+0 -247)

model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java 152(+0 -152)

model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedOAuthClient.java 17(+0 -17)

model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/OAuthClientAdapter.java 56(+0 -56)

model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java 308(+0 -308)

model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java 116(+0 -116)

model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java 29(+0 -29)

model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java 52(+0 -52)

model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java 275(+0 -275)

model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java 48(+0 -48)

model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoOAuthClientEntity.java 23(+0 -23)

services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java 96(+0 -96)

services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java 206(+0 -206)

services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsByIdResource.java 26(+0 -26)

services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java 121(+0 -121)

testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java 54(+0 -54)

Details

diff --git a/connections/jpa/src/main/resources/META-INF/persistence.xml b/connections/jpa/src/main/resources/META-INF/persistence.xml
index aca54ef..2a066d0 100755
--- a/connections/jpa/src/main/resources/META-INF/persistence.xml
+++ b/connections/jpa/src/main/resources/META-INF/persistence.xml
@@ -3,9 +3,8 @@
     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
     version="1.0">
     <persistence-unit name="keycloak-default" transaction-type="RESOURCE_LOCAL">
-        <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
+        <class>org.keycloak.models.jpa.entities.ClientEntity</class>
         <class>org.keycloak.models.jpa.entities.CredentialEntity</class>
-        <class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
         <class>org.keycloak.models.jpa.entities.RealmEntity</class>
         <class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class>
         <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java
new file mode 100644
index 0000000..6ff8b12
--- /dev/null
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/SetConsentRequiredOnOAuthClients.java
@@ -0,0 +1,84 @@
+package org.keycloak.connections.jpa.updater.liquibase.custom;
+
+import liquibase.change.custom.CustomSqlChange;
+import liquibase.database.Database;
+import liquibase.database.jvm.JdbcConnection;
+import liquibase.exception.CustomChangeException;
+import liquibase.exception.SetupException;
+import liquibase.exception.ValidationErrors;
+import liquibase.resource.ResourceAccessor;
+import liquibase.snapshot.SnapshotGeneratorFactory;
+import liquibase.statement.SqlStatement;
+import liquibase.statement.core.UpdateStatement;
+import liquibase.structure.core.Table;
+import org.keycloak.models.utils.KeycloakModelUtils;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class SetConsentRequiredOnOAuthClients implements CustomSqlChange {
+
+    private String confirmationMessage;
+
+    @Override
+    public SqlStatement[] generateStatements(Database database) throws CustomChangeException {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Set consent required for: ");
+
+            Connection connection = ((JdbcConnection) (database.getConnection())).getWrappedConnection();
+            ArrayList<SqlStatement> statements = new ArrayList<SqlStatement>();
+
+            String correctedTableName = database.correctObjectName("CLIENT", Table.class);
+            if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) {
+                ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM CLIENT");
+                while (resultSet.next()) {
+                    String id = resultSet.getString(1);
+
+                    UpdateStatement statement = new UpdateStatement(null, null, correctedTableName)
+                            .addNewColumnValue("CONSENT_REQUIRED", true)
+                            .setWhereClause("ID='" + id + "'");
+                    statements.add(statement);
+
+                    if (!resultSet.isFirst()) {
+                        sb.append(", ");
+                    }
+                    sb.append(id);
+                }
+
+                if (!statements.isEmpty()) {
+                    confirmationMessage = sb.toString();
+                }
+            }
+
+            return statements.toArray(new SqlStatement[statements.size()]);
+        } catch (Exception e) {
+            throw new CustomChangeException("Failed to add realm code secret", e);
+        }
+    }
+
+    @Override
+    public String getConfirmationMessage() {
+        return confirmationMessage;
+    }
+
+    @Override
+    public void setUp() throws SetupException {
+
+    }
+
+    @Override
+    public void setFileOpener(ResourceAccessor resourceAccessor) {
+
+    }
+
+    @Override
+    public ValidationErrors validate(Database database) {
+        return null;
+    }
+
+}
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml
index 7c50600..b7349f2 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.RC1.xml
@@ -36,5 +36,12 @@
         <addPrimaryKey columnNames="IDP_MAPPER_ID, NAME" constraintName="CONSTRAINT_IDPMConfig" tableName="IDP_MAPPER_CONFIG"/>
         <addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="IDENTITY_PROVIDER_MAPPER" constraintName="FK_IDPM_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
         <addForeignKeyConstraint baseColumnNames="IDP_MAPPER_ID" baseTableName="IDP_MAPPER_CONFIG" constraintName="FK_IDPMConfig" referencedColumnNames="ID" referencedTableName="IDENTITY_PROVIDER_MAPPER"/>
+
+        <addColumn tableName="CLIENT">
+            <column name="CONSENT_REQUIRED" type="BOOLEAN" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
+        </addColumn>
+        <dropColumn tableName="CLIENT" columnName="DTYPE"/>
     </changeSet>
 </databaseChangeLog>
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
index f5ed855..138955b 100755
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
@@ -33,8 +33,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
             "org.keycloak.models.entities.RequiredCredentialEntity",
             "org.keycloak.models.entities.CredentialEntity",
             "org.keycloak.models.entities.FederatedIdentityEntity",
-            "org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity",
-            "org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity",
+            "org.keycloak.models.mongo.keycloak.entities.MongoClientEntity",
             "org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
             "org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
             "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index e407049..8f38e4b 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -22,6 +22,8 @@ public class ApplicationRepresentation {
     protected ClaimRepresentation claims;
     protected Integer notBefore;
     protected Boolean bearerOnly;
+    protected Boolean consentRequired;
+    protected Boolean directGrantsOnly;
     protected Boolean publicClient;
     protected Boolean frontchannelLogout;
     protected String protocol;
@@ -136,6 +138,22 @@ public class ApplicationRepresentation {
         this.bearerOnly = bearerOnly;
     }
 
+    public Boolean isConsentRequired() {
+        return consentRequired;
+    }
+
+    public void setConsentRequired(Boolean consentRequired) {
+        this.consentRequired = consentRequired;
+    }
+
+    public Boolean getDirectGrantsOnly() {
+        return directGrantsOnly;
+    }
+
+    public void setDirectGrantsOnly(Boolean directGrantsOnly) {
+        this.directGrantsOnly = directGrantsOnly;
+    }
+
     public Boolean isPublicClient() {
         return publicClient;
     }
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index 9e68367..787f8ca 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -6,10 +6,8 @@ import org.codehaus.jackson.JsonFactory;
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.SerializationConfig;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
@@ -18,9 +16,7 @@ import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.representations.idm.ClaimRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.OAuthClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.RolesRepresentation;
@@ -58,24 +54,14 @@ public class ExportUtils {
         }
 
         // Applications
-        List<ApplicationModel> applications = realm.getApplications();
+        List<ClientModel> applications = realm.getClients();
         List<ApplicationRepresentation> appReps = new ArrayList<ApplicationRepresentation>();
-        for (ApplicationModel app : applications) {
+        for (ClientModel app : applications) {
             ApplicationRepresentation appRep = exportApplication(app);
             appReps.add(appRep);
         }
         rep.setApplications(appReps);
 
-        // OAuth clients
-        List<OAuthClientModel> oauthClients = realm.getOAuthClients();
-        List<OAuthClientRepresentation> oauthClientReps = new ArrayList<OAuthClientRepresentation>();
-        for (OAuthClientModel oauthClient : oauthClients) {
-            OAuthClientRepresentation clientRep = ModelToRepresentation.toRepresentation(oauthClient);
-            clientRep.setSecret(oauthClient.getSecret());
-            oauthClientReps.add(clientRep);
-        }
-        rep.setOauthClients(oauthClientReps);
-
         // Roles
         List<RoleRepresentation> realmRoleReps = null;
         Map<String, List<RoleRepresentation>> appRolesReps = new HashMap<String, List<RoleRepresentation>>();
@@ -84,10 +70,10 @@ public class ExportUtils {
         if (realmRoles != null && realmRoles.size() > 0) {
             realmRoleReps = exportRoles(realmRoles);
         }
-        for (ApplicationModel app : applications) {
+        for (ClientModel app : applications) {
             Set<RoleModel> currentAppRoles = app.getRoles();
             List<RoleRepresentation> currentAppRoleReps = exportRoles(currentAppRoles);
-            appRolesReps.put(app.getName(), currentAppRoleReps);
+            appRolesReps.put(app.getClientId(), currentAppRoleReps);
         }
 
         RolesRepresentation rolesRep = new RolesRepresentation();
@@ -100,9 +86,8 @@ public class ExportUtils {
         rep.setRoles(rolesRep);
 
         // Scopes
-        List<ClientModel> allClients = new ArrayList<ClientModel>(applications);
-        allClients.addAll(realm.getOAuthClients());
-        Map<String, List<ScopeMappingRepresentation>> appScopeReps = new HashMap<String, List<ScopeMappingRepresentation>>();
+        List<ClientModel> allClients = new ArrayList<>(applications);
+        Map<String, List<ScopeMappingRepresentation>> appScopeReps = new HashMap<>();
 
         for (ClientModel client : allClients) {
             Set<RoleModel> clientScopes = client.getScopeMappings();
@@ -114,11 +99,11 @@ public class ExportUtils {
                     }
                     scopeMappingRep.role(scope.getName());
                 } else {
-                    ApplicationModel app = (ApplicationModel)scope.getContainer();
-                    String appName = app.getName();
+                    ClientModel app = (ClientModel)scope.getContainer();
+                    String appName = app.getClientId();
                     List<ScopeMappingRepresentation> currentAppScopes = appScopeReps.get(appName);
                     if (currentAppScopes == null) {
-                        currentAppScopes = new ArrayList<ScopeMappingRepresentation>();
+                        currentAppScopes = new ArrayList<>();
                         appScopeReps.put(appName, currentAppScopes);
                     }
 
@@ -165,7 +150,7 @@ public class ExportUtils {
      * @param app
      * @return full ApplicationRepresentation
      */
-    public static ApplicationRepresentation exportApplication(ApplicationModel app) {
+    public static ApplicationRepresentation exportApplication(ClientModel app) {
         ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app);
 
         appRep.setSecret(app.getSecret());
@@ -216,8 +201,8 @@ public class ExportUtils {
                         compositeAppRoles = new HashMap<String, List<String>>();
                     }
 
-                    ApplicationModel app = (ApplicationModel)crContainer;
-                    String appName = app.getName();
+                    ClientModel app = (ClientModel)crContainer;
+                    String appName = app.getClientId();
                     List<String> currentAppComposites = compositeAppRoles.get(appName);
                     if (currentAppComposites == null) {
                         currentAppComposites = new ArrayList<String>();
@@ -269,8 +254,8 @@ public class ExportUtils {
             if (role.getContainer() instanceof RealmModel) {
                 realmRoleNames.add(role.getName());
             } else {
-                ApplicationModel app = (ApplicationModel)role.getContainer();
-                String appName = app.getName();
+                ClientModel app = (ClientModel)role.getContainer();
+                String appName = app.getClientId();
                 List<String> currentAppRoles = appRoleNames.get(appName);
                 if (currentAppRoles == null) {
                     currentAppRoles = new ArrayList<String>();
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
index 5c0a60c..3bf9d46 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
@@ -8,7 +8,7 @@ import org.jboss.logging.Logger;
 import org.keycloak.Config;
 import org.keycloak.exportimport.Strategy;
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
@@ -81,7 +81,7 @@ public class ImportUtils {
             // We just imported master realm. All 'masterAdminApps' need to be refreshed
             RealmModel adminRealm = realm;
             for (RealmModel currentRealm : model.getRealms()) {
-                ApplicationModel masterApp = adminRealm.getApplicationByName(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm));
+                ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm));
                 if (masterApp != null) {
                     currentRealm.setMasterAdminApp(masterApp);
                 }  else {
@@ -91,7 +91,7 @@ public class ImportUtils {
         } else {
             // Need to refresh masterApp for current realm
             RealmModel adminRealm = model.getRealm(adminRealmId);
-            ApplicationModel masterApp = adminRealm.getApplicationByName(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
+            ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
             if (masterApp != null) {
                 realm.setMasterAdminApp(masterApp);
             }  else {
@@ -119,7 +119,7 @@ public class ImportUtils {
         }
         adminRole.setDescription("${role_"+AdminRoles.ADMIN+"}");
 
-        ApplicationModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
+        ClientModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
         realmAdminApp.setBearerOnly(true);
         realm.setMasterAdminApp(realmAdminApp);
 
@@ -220,7 +220,7 @@ public class ImportUtils {
 
     private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List<UserRepresentation> userReps) {
         RealmModel realm = model.getRealmByName(realmName);
-        Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
+        Map<String, ClientModel> apps = realm.getClientNameMap();
         for (UserRepresentation user : userReps) {
             RepresentationToModel.createUser(session, realm, user, apps);
         }
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java
index 03ba5b3..646b44b 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/SessionsBean.java
@@ -1,14 +1,11 @@
 package org.keycloak.account.freemarker.model;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.util.Time;
 
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -63,23 +60,14 @@ public class SessionsBean {
             return Time.toDate(max);
         }
 
-        public Set<String> getApplications() {
-            Set<String> apps = new HashSet<String>();
+        public Set<String> getClients() {
+            Set<String> clients = new HashSet<String>();
             for (ClientSessionModel clientSession : session.getClientSessions()) {
                 ClientModel client = clientSession.getClient();
-                if (client instanceof ApplicationModel) apps.add(client.getClientId());
+                clients.add(client.getClientId());
             }
-            return apps;
+            return clients;
         }
-        public List<String> getClients() {
-            List<String> apps = new ArrayList<String>();
-            for (ClientSessionModel clientSession : session.getClientSessions()) {
-                ClientModel client = clientSession.getClient();
-                if (client instanceof OAuthClientModel) apps.add(client.getClientId());
-            }
-            return apps;
-        }
-
     }
 
 }
diff --git a/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl b/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl
index c781c79..1c0ef1b 100755
--- a/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/account/sessions.ftl
@@ -14,7 +14,6 @@
             <td>${msg("started")}</td>
             <td>${msg("lastAccess")}</td>
             <td>${msg("expires")}</td>
-            <td>${msg("applications")}</td>
             <td>${msg("clients")}</td>
         </tr>
         </thead>
@@ -27,11 +26,6 @@
                 <td>${session.lastAccess?datetime}</td>
                 <td>${session.expires?datetime}</td>
                 <td>
-                    <#list session.applications as app>
-                        ${app}<br/>
-                    </#list>
-                </td>
-                <td>
                     <#list session.clients as client>
                         ${client}<br/>
                     </#list>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
index e38c29c..f7ea60d 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
@@ -512,72 +512,6 @@ module.config([ '$routeProvider', function($routeProvider) {
             },
             controller : 'ApplicationProtocolMapperCreateCtrl'
         })
-
-        .when('/realms/:realm/oauth-clients/:oauth/mappers', {
-                templateUrl : resourceUrl + '/partials/oauth-client-mappers.html',
-                resolve : {
-                    realm : function(RealmLoader) {
-                        return RealmLoader();
-                    },
-                    oauth : function(OAuthClientLoader) {
-                        return OAuthClientLoader();
-                    },
-                    serverInfo : function(ServerInfoLoader) {
-                        return ServerInfoLoader();
-                    }
-                },
-                controller : 'OAuthClientProtocolMapperListCtrl'
-            })
-            .when('/realms/:realm/oauth-clients/:oauth/add-mappers', {
-                templateUrl : resourceUrl + '/partials/oauth-client-mappers-add.html',
-                resolve : {
-                    realm : function(RealmLoader) {
-                        return RealmLoader();
-                    },
-                    oauth : function(OAuthClientLoader) {
-                        return OAuthClientLoader();
-                    },
-                    serverInfo : function(ServerInfoLoader) {
-                        return ServerInfoLoader();
-                    }
-                },
-                controller : 'OAuthClientAddBuiltinProtocolMapperCtrl'
-            })
-            .when('/realms/:realm/oauth-clients/:oauth/mappers/:id', {
-                templateUrl : resourceUrl + '/partials/oauth-client-protocol-mapper-detail.html',
-                resolve : {
-                    realm : function(RealmLoader) {
-                        return RealmLoader();
-                    },
-                    oauth : function(OAuthClientLoader) {
-                        return OAuthClientLoader();
-                    },
-                    serverInfo : function(ServerInfoLoader) {
-                        return ServerInfoLoader();
-                    },
-                    mapper : function(OAuthClientProtocolMapperLoader) {
-                        return OAuthClientProtocolMapperLoader();
-                    }
-
-                },
-                controller : 'OAuthClientProtocolMapperCtrl'
-            })
-            .when('/create/oauth-client/:realm/:oauth/mappers', {
-                templateUrl : resourceUrl + '/partials/oauth-client-protocol-mapper-detail.html',
-                resolve : {
-                    realm : function(RealmLoader) {
-                        return RealmLoader();
-                    },
-                    serverInfo : function(ServerInfoLoader) {
-                        return ServerInfoLoader();
-                    },
-                    oauth : function(OAuthClientLoader) {
-                        return OAuthClientLoader();
-                    }
-                },
-                controller : 'OAuthClientProtocolMapperCreateCtrl'
-            })
-
         .when('/realms/:realm/applications/:application/sessions', {
             templateUrl : resourceUrl + '/partials/application-sessions.html',
             resolve : {
@@ -807,127 +741,6 @@ module.config([ '$routeProvider', function($routeProvider) {
             },
             controller : 'ApplicationImportCtrl'
         })
-
-        // OAUTH Client
-
-        .when('/realms/:realm/oauth-clients/:oauth/claims', {
-            templateUrl : resourceUrl + '/partials/oauth-client-claims.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                },
-                claims : function(OAuthClientClaimsLoader) {
-                    return OAuthClientClaimsLoader();
-                }
-            },
-            controller : 'OAuthClientClaimsCtrl'
-        })
-        .when('/realms/:realm/oauth-clients/:oauth/revocation', {
-            templateUrl : resourceUrl + '/partials/oauth-client-revocation.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                }
-            },
-            controller : 'OAuthClientRevocationCtrl'
-        })
-        .when('/realms/:realm/oauth-clients/:oauth/credentials', {
-            templateUrl : resourceUrl + '/partials/oauth-client-credentials.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                }
-            },
-            controller : 'OAuthClientCredentialsCtrl'
-        })
-        .when('/realms/:realm/oauth-clients/:oauth/scope-mappings', {
-            templateUrl : resourceUrl + '/partials/oauth-client-scope-mappings.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                },
-                applications : function(ApplicationListLoader) {
-                    return ApplicationListLoader();
-                }
-            },
-            controller : 'OAuthClientScopeMappingCtrl'
-        })
-        .when('/realms/:realm/oauth-clients/:oauth/installation', {
-            templateUrl : resourceUrl + '/partials/oauth-client-installation.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                },
-                installation : function(OAuthClientInstallationLoader) {
-                    return OAuthClientInstallationLoader();
-                }
-            },
-            controller : 'OAuthClientInstallationCtrl'
-        })
-        .when('/create/oauth-client/:realm', {
-            templateUrl : resourceUrl + '/partials/oauth-client-detail.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function() {
-                    return {};
-                }
-            },
-            controller : 'OAuthClientDetailCtrl'
-        })
-        .when('/realms/:realm/oauth-clients/:oauth', {
-            templateUrl : resourceUrl + '/partials/oauth-client-detail.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                }
-            },
-            controller : 'OAuthClientDetailCtrl'
-        })
-        .when('/realms/:realm/oauth-clients/:oauth/identity-provider', {
-            templateUrl : resourceUrl + '/partials/oauth-client-identity-provider.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauth : function(OAuthClientLoader) {
-                    return OAuthClientLoader();
-                }
-            },
-            controller : 'OAuthClientIdentityProviderCtrl'
-        })
-        .when('/realms/:realm/oauth-clients', {
-            templateUrl : resourceUrl + '/partials/oauth-client-list.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                oauthClients : function(OAuthClientListLoader) {
-                    return OAuthClientListLoader();
-                }
-            },
-            controller : 'OAuthClientListCtrl'
-        })
-
         .when('/', {
             templateUrl : resourceUrl + '/partials/home.html',
             controller : 'HomeCtrl'
@@ -1549,15 +1362,6 @@ module.directive('kcNavigationApplication', function () {
     }
 });
 
-module.directive('kcNavigationOauthClient', function () {
-    return {
-        scope: true,
-        restrict: 'E',
-        replace: true,
-        templateUrl: resourceUrl + '/templates/kc-navigation-oauth-client.html'
-    }
-});
-
 /*
 *  Used to select the element (invoke $(elem).select()) on specified action list.
 *  Usages kc-select-action="click mouseover"
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
index bb7620e..750d482 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -53,10 +53,6 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $
             return getAccess('view-realm') || this.manageRealm;
         },
 
-        get viewApplications() {
-            return getAccess('view-applications') || this.manageApplications;
-        },
-
         get viewClients() {
             return getAccess('view-clients') || this.manageClients;
         },
@@ -73,10 +69,6 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $
             return getAccess('manage-realm');
         },
 
-        get manageApplications() {
-            return getAccess('manage-applications');
-        },
-
         get manageClients() {
             return getAccess('manage-clients');
         },
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js
index da6873d..7223ae5 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js
@@ -89,17 +89,6 @@ module.factory('ApplicationProtocolMapperLoader', function(Loader, ApplicationPr
     });
 });
 
-module.factory('OAuthClientProtocolMapperLoader', function(Loader, OAuthClientProtocolMapper, $route, $q) {
-    return Loader.get(OAuthClientProtocolMapper, function() {
-        return {
-            realm : $route.current.params.realm,
-            oauth : $route.current.params.oauth,
-            id: $route.current.params.id
-        }
-    });
-});
-
-
 module.factory('UserLoader', function(Loader, User, $route, $q) {
     return Loader.get(User, function() {
         return {
@@ -261,42 +250,6 @@ module.factory('RoleMappingLoader', function(Loader, RoleMapping, $route, $q) {
 	});
 });
 
-module.factory('OAuthClientLoader', function(Loader, OAuthClient, $route, $q) {
-    return Loader.get(OAuthClient, function() {
-        return {
-            realm : $route.current.params.realm,
-            oauth : $route.current.params.oauth
-        }
-    });
-});
-
-module.factory('OAuthClientClaimsLoader', function(Loader, OAuthClientClaims, $route, $q) {
-    return Loader.get(OAuthClientClaims, function() {
-        return {
-            realm : $route.current.params.realm,
-            oauth : $route.current.params.oauth
-        }
-    });
-});
-
-
-module.factory('OAuthClientListLoader', function(Loader, OAuthClient, $route, $q) {
-    return Loader.query(OAuthClient, function() {
-        return {
-            realm : $route.current.params.realm
-        }
-    });
-});
-
-module.factory('OAuthClientInstallationLoader', function(Loader, OAuthClientInstallation, $route, $q) {
-    return Loader.get(OAuthClientInstallation, function() {
-        return {
-            realm : $route.current.params.realm,
-            oauth : $route.current.params.oauth
-        }
-    });
-});
-
 module.factory('IdentityProviderLoader', function(Loader, IdentityProvider, $route, $q) {
     return Loader.get(IdentityProvider, function () {
         return {
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
index d783324..805bc01 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
@@ -202,29 +202,6 @@ module.factory('ApplicationProtocolMapper', function($resource) {
     });
 });
 
-module.factory('OAuthClientProtocolMapper', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/protocol-mappers/models/:id', {
-        realm : '@realm',
-        oauth: '@oauth',
-        id : "@id"
-    }, {
-        update : {
-            method : 'PUT'
-        }
-    });
-});
-
-module.factory('OAuthClientProtocolMappersByProtocol', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/protocol-mappers/protocol/:protocol', {
-        realm : '@realm',
-        oauth : "@oauth",
-        protocol : "@protocol"
-    });
-});
-
-
-
-
 module.factory('User', function($resource) {
     return $resource(authUrl + '/admin/realms/:realm/users/:userId', {
         realm : '@realm',
@@ -840,120 +817,6 @@ module.factory('ApplicationOrigins', function($resource) {
     });
 });
 
-module.factory('OAuthClient', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth', {
-        realm : '@realm',
-        oauth : '@oauth'
-    },  {
-        update : {
-            method : 'PUT'
-        }
-    });
-});
-
-module.factory('OAuthClientClaims', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/claims', {
-        realm : '@realm',
-        oauth : "@oauth"
-    },  {
-        update : {
-            method : 'PUT'
-        }
-    });
-});
-
-
-module.factory('OAuthClientCredentials', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/client-secret', {
-        realm : '@realm',
-        oauth : '@oauth'
-    },  {
-        update : {
-            method : 'POST'
-        }
-    });
-
-});
-
-module.factory('OAuthCertificate', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/certificates', {
-        realm : '@realm',
-        oauth : '@oauth'
-    });
-});
-
-module.factory('OAuthCertificateDownload', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/certificates/download', {
-        realm : '@realm',
-        oauth : '@oauth'
-    });
-});
-
-
-module.factory('OAuthClientRealmScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm', {
-        realm : '@realm',
-        oauth : '@oauth'
-    });
-});
-
-module.factory('OAuthClientCompositeRealmScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm/composite', {
-        realm : '@realm',
-        oauth : '@oauth'
-    });
-});
-
-module.factory('OAuthClientAvailableRealmScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm/available', {
-        realm : '@realm',
-        oauth : '@oauth'
-    });
-});
-
-module.factory('OAuthClientApplicationScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp', {
-        realm : '@realm',
-        oauth : '@oauth',
-        targetApp : '@targetApp'
-    });
-});
-
-module.factory('OAuthClientCompositeApplicationScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp/composite', {
-        realm : '@realm',
-        oauth : '@oauth',
-        targetApp : '@targetApp'
-    });
-});
-
-module.factory('OAuthClientAvailableApplicationScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp/available', {
-        realm : '@realm',
-        oauth : '@oauth',
-        targetApp : '@targetApp'
-    });
-});
-
-
-
-module.factory('OAuthClientInstallation', function($resource) {
-    var url = authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/installation';
-    var resource = $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/installation', {
-        realm : '@realm',
-        oauth : '@oauth'
-    },  {
-        update : {
-            method : 'PUT'
-        }
-    });
-    resource.url = function(parameters) {
-        return url.replace(':realm', parameters.realm).replace(':oauth', parameters.oauth);
-    }
-    return resource;
-});
-
-
 module.factory('Current', function(Realm, $route) {
     var current = {};
 
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html
index 985260f..dd5316e 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering.html
@@ -8,7 +8,7 @@
             <li class="active">Clustering</li>
         </ol>
         <h2 data-ng-hide="create"><span>{{application.name}}</span> Clustering</h2>
-        <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageApplications">
+        <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageClients">
             <legend><span class="text">Basic configuration</span></legend>
             <fieldset >
                 <div class="form-group clearfix">
@@ -43,7 +43,7 @@
                 <table class="table table-striped table-bordered">
                     <thead>
                         <tr>
-                            <th class="kc-table-actions" colspan="3" data-ng-show="access.manageApplications">
+                            <th class="kc-table-actions" colspan="3" data-ng-show="access.manageClients">
                                 <div class="pull-right">
                                     <a class="btn btn-primary" tooltip="Manually register cluster node. This is usually not needed as cluster node should be registered automatically by adapter"
                                        tooltip-placement="bottom" href="#/register-node/realms/{{realm.realm}}/applications/{{application.id}}/clustering">Register node manually</a>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html
index 74ef211..3c4f614 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-clustering-node.html
@@ -10,7 +10,7 @@
         </ol>
         <h2 data-ng-show="create || registered"><span>{{application.name}} Clustering</span></h2>
         <h2 data-ng-hide="create || registered">Cluster node on host <span>{{node.host}}</span> not registered!</h2>
-        <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageApplications" data-ng-show="create || registered">
+        <form class="form-horizontal" name="clusteringForm" novalidate kc-read-only="!access.manageClients" data-ng-show="create || registered">
             <fieldset >
                 <legend><span class="text">Configuration of cluster node</span></legend>
                 <div class="form-group">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html
index c3b1f9d..9c0a2c5 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-detail.html
@@ -15,7 +15,7 @@
         <h2 data-ng-show="create" class="pull-left"><span>{{realm.realm}}</span> Add Application</h2>
         <p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
 
-        <form class="form-horizontal" name="applicationForm" novalidate kc-read-only="!access.manageApplications">
+        <form class="form-horizontal" name="applicationForm" novalidate kc-read-only="!access.manageClients">
             <fieldset class="border-top">
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="name">Name <span class="required" data-ng-show="create">*</span></label>
@@ -30,6 +30,20 @@
                     </div>
                     <span tooltip-placement="right" tooltip="Disabled applications cannot initiate a login or have obtain access tokens." class="fa fa-info-circle"></span>
                 </div>
+                <div class="form-group clearfix block">
+                    <label class="col-sm-2 control-label" for="consentRequired">Consent Required</label>
+                    <div class="col-sm-6">
+                        <input ng-model="application.consentRequired" name="consentRequired" id="consentRequired" onoffswitch />
+                    </div>
+                    <span tooltip-placement="right" tooltip="If enabled users have to consent to client access." class="fa fa-info-circle"></span>
+                </div>
+                <div class="form-group clearfix block">
+                    <label class="col-sm-2 control-label" for="directGrantsOnly">Direct Grants Only</label>
+                    <div class="col-sm-6">
+                        <input ng-model="application.directGrantsOnly" name="directGrantsOnly" id="directGrantsOnly" onoffswitch />
+                    </div>
+                    <span tooltip-placement="right" tooltip="When enabled, client can only obtain grants from grant REST API." class="fa fa-info-circle"></span>
+                </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="protocol">Client Protocol</label>
                     <div class="col-sm-6">
@@ -244,11 +258,11 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right form-actions" data-ng-show="create && access.manageApplications">
+            <div class="pull-right form-actions" data-ng-show="create && access.manageClients">
                 <button kc-cancel data-ng-click="cancel()">Cancel</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
-            <div class="pull-right form-actions" data-ng-show="!create && access.manageApplications">
+            <div class="pull-right form-actions" data-ng-show="!create && access.manageClients">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save  data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete Application</button>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html
index 41e8c11..cfd17cd 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-revocation.html
@@ -18,7 +18,7 @@
                     <span tooltip-placement="right" tooltip="Revoke any tokens issued before this date for this application." class="fa fa-info-circle"></span>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions" data-ng-show="access.manageApplications">
+            <div class="pull-right form-actions" data-ng-show="access.manageClients">
                 <button type="submit" data-ng-click="clear()" class="btn btn-default btn-lg">Clear
                 </button>
                 <button type="submit" data-ng-click="setNotBeforeNow()" class="btn btn-primary btn-lg">Set To Now
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html
index 5145f37..9729b94 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-detail.html
@@ -20,7 +20,7 @@
         <h2 data-ng-show="create" class="pull-left"><span>{{application.name}}</span> Add Application Role</h2>
         <p class="subtitle" data-ng-show="create"><span class="required">*</span> Required fields</p>
 
-        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications">
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients">
             
             <fieldset class="border-top">
                 <div class="form-group">
@@ -126,11 +126,11 @@
                 </div>
             </fieldset>
 
-            <div class="pull-right form-actions" data-ng-show="create && access.manageApplications">
+            <div class="pull-right form-actions" data-ng-show="create && access.manageClients">
                 <button kc-cancel data-ng-click="cancel()">Cancel</button>
                 <button kc-save data-ng-show="changed">Save</button>
             </div>
-            <div class="pull-right form-actions" data-ng-show="!create && access.manageApplications">
+            <div class="pull-right form-actions" data-ng-show="!create && access.manageClients">
                 <button kc-reset data-ng-show="changed">Clear changes</button>
                 <button kc-save  data-ng-show="changed">Save</button>
                 <button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html
index e10126e..b2dc850 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-role-list.html
@@ -12,7 +12,7 @@
         <table class="table table-striped table-bordered">
             <thead>
             <tr>
-                <th class="kc-table-actions" colspan="3" data-ng-show="access.manageApplications">
+                <th class="kc-table-actions" colspan="3" data-ng-show="access.manageClients">
                     <div class="pull-right">
                         <a class="btn btn-primary" href="#/create/role/{{realm.realm}}/applications/{{application.id}}">Add Role</a>
                         <!-- <button class="remove disabled">Remove</button> -->
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html
index 852f1f4..ce693c1 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/application-scope-mappings.html
@@ -10,7 +10,7 @@
         </ol>
         <h2><span>{{application.name}}</span> Scope Mappings <span tooltip-placement="right" tooltip="Scope mappings allow you to restrict which user role mappings are included within the access token requested by the application." class="fa fa-info-circle"></span></h2>
         <p class="subtitle"></p>
-        <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageApplications">
+        <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageClients">
             <fieldset class="border-top">
                 <div class="form-group">
                     <label class="col-sm-2 control-label" for="fullScopeAllowed">Full Scope Allowed</label>
@@ -22,7 +22,7 @@
             </fieldset>
         </form>
 
-        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications" data-ng-show="!application.fullScopeAllowed">
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients" data-ng-show="!application.fullScopeAllowed">
             <fieldset>
                 <legend><span class="text">Realm Roles</span>  <span tooltip-placement="right" tooltip="Realm level roles assigned to scope." class="fa fa-info-circle"></span></legend>
                 <div class="form-group col-sm-10">
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html
index 098f317..00d2e31 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-menu.html
@@ -7,12 +7,9 @@
     || path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings' || path[2] == 'auth-settings') && path[3] != 'applications') && 'active'">
         <a href="#/realms/{{realm.realm}}">Settings</a>
     </li>
-    <li data-ng-show="access.viewUsers" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a>
-    </li>
-    <li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || (path[1] == 'role' && path[3] != 'applications')) && 'active'"><a href="#/realms/{{realm.realm}}/roles">Roles</a>
-    </li>
-    <li data-ng-show="access.viewApplications" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
-    <li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
+    <li data-ng-show="access.viewUsers" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a></li>
+    <li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Clients</a></li>
+    <li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || (path[1] == 'role' && path[3] != 'applications')) && 'active'"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
     <li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'sessions' || path[2] == 'token-settings') && 'active'"><a href="#/realms/{{realm.realm}}/sessions/realm">Sessions and Tokens</a></li>
     <li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'defense') && 'active'"><a href="#/realms/{{realm.realm}}/defense/headers">Security Defenses</a></li>
     <li data-ng-show="access.viewEvents" data-ng-class="(path[2] == 'events' || path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events">Events</a></li>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html
index c87af7f..79007bc 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/session-revocation.html
@@ -18,7 +18,7 @@
                     <span tooltip-placement="right" tooltip="Revoke any tokens issued before this date." class="fa fa-info-circle"></span>
                 </div>
             </fieldset>
-            <div class="pull-right form-actions" data-ng-show="access.manageApplications">
+            <div class="pull-right form-actions" data-ng-show="access.manageClients">
                 <button type="submit" data-ng-click="clear()" class="btn btn-default btn-lg">Clear
                 </button>
                 <button type="submit" data-ng-click="setNotBeforeNow()" class="btn btn-primary btn-lg">Set To Now
diff --git a/forms/common-themes/src/main/resources/theme/base/login/login.ftl b/forms/common-themes/src/main/resources/theme/base/login/login.ftl
index 505e185..858e075 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/login.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/login/login.ftl
@@ -1,17 +1,9 @@
 <#import "template.ftl" as layout>
 <@layout.registrationLayout displayInfo=social.displayInfo; section>
     <#if section = "title">
-        <#if client.application>
-            ${msg("loginTitle",(realm.name!''))}
-        <#elseif client.oauthClient>
-            ${msg("loginOauthTitle",(realm.name!''))}
-        </#if>
+        ${msg("loginTitle",(realm.name!''))}
     <#elseif section = "header">
-        <#if client.application>
-            ${msg("loginTitleHtml",(realm.name!''))}
-        <#elseif client.oauthClient>
-            ${msg("loginOauthTitleHtml",(realm.name!''), (client.clientId!''))}
-        </#if>
+        ${msg("loginTitleHtml",(realm.name!''))}
     <#elseif section = "form">
         <#if realm.password>
             <form id="kc-form-login" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
index 06abbb1..75ffd3e 100644
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_de.properties
@@ -11,7 +11,7 @@ registerWithTitle=Registrierung bei {0}
 registerWithTitleHtml=Registrierung bei <strong>{0}</strong>
 loginTitle=Anmeldung bei {0}
 loginTitleHtml=Anmeldung bei <strong>{0}</strong>
-loginOauthTitle=Tempor\u00E4rer zugriff auf {0}
+loginOauthTitle=
 loginOauthTitleHtml=Tempor\u00E4rer zugriff auf <strong>{0}</strong> angefordert von <strong>{1}</strong>.
 loginTotpTitle=Mobile Authentifizierung Einrichten
 loginProfileTitle=Benutzerkonto Informationen aktualisieren
diff --git a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
index 4bb3a66..7c1347f 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/login/messages/messages_en.properties
@@ -11,8 +11,6 @@ registerWithTitle=Register with {0}
 registerWithTitleHtml=Register with <strong>{0}</strong>
 loginTitle=Log in to {0}
 loginTitleHtml=Log in to <strong>{0}</strong>
-loginOauthTitle=Temporary access for {0}
-loginOauthTitleHtml=Temporary access for <strong>{0}</strong> requested by <strong>{1}</strong>.
 loginTotpTitle=Mobile Authenticator Setup
 loginProfileTitle=Update Account Information
 oauthGrantTitle=OAuth Grant
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
index 0dd6342..228a146 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
@@ -1,23 +1,5 @@
 package org.keycloak.login.freemarker;
 
-import java.io.IOException;
-import java.net.URI;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-
-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 org.jboss.logging.Logger;
 import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.keycloak.OAuth2Constants;
@@ -57,6 +39,23 @@ import org.keycloak.models.utils.FormMessage;
 import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.flows.Urls;
 
+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 java.io.IOException;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
index fcd9e11..53f7937 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ClientBean.java
@@ -1,37 +1,25 @@
 package org.keycloak.login.freemarker.model;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.OAuthClientModel;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class ClientBean {
+
     protected ClientModel client;
 
     public ClientBean(ClientModel client) {
         this.client = client;
     }
 
-    public boolean isApplication() {
-        return client instanceof ApplicationModel;
-    }
-
-    public boolean isOauthClient() {
-        return client instanceof OAuthClientModel;
-    }
-
     public String getClientId() {
         return client.getClientId();
     }
 
     public String getBaseUrl() {
-        if (client instanceof ApplicationModel) {
-            return ((ApplicationModel) client).getBaseUrl();
-        }
-        return null;
+        return client.getBaseUrl();
     }
 
 }
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
index 8da7f4d..cd11bfd 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
@@ -21,10 +21,6 @@
  */
 package org.keycloak.login.freemarker.model;
 
-import org.keycloak.OAuth2Constants;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.Constants;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.services.resources.flows.Urls;
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
index 1ed0a80..b40cc13 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
@@ -29,9 +29,6 @@ public interface RealmResource {
     @Path("users")
     public UsersResource users();
 
-    @Path("oauth-clients")
-    public OAuthClientsResource oAuthClients();
-
     @Path("roles")
     public RolesResource roles();
 
diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
index 8d46505..73a93c3 100755
--- a/model/api/src/main/java/org/keycloak/models/AdminRoles.java
+++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java
@@ -16,18 +16,16 @@ public class AdminRoles {
 
     public static String VIEW_REALM = "view-realm";
     public static String VIEW_USERS = "view-users";
-    public static String VIEW_APPLICATIONS = "view-applications";
     public static String VIEW_CLIENTS = "view-clients";
     public static String VIEW_EVENTS = "view-events";
     public static String VIEW_IDENTITY_PROVIDERS = "view-identity-providers";
 
     public static String MANAGE_REALM = "manage-realm";
     public static String MANAGE_USERS = "manage-users";
-    public static String MANAGE_APPLICATIONS = "manage-applications";
     public static String MANAGE_IDENTITY_PROVIDERS = "manage-identity-providers";
     public static String MANAGE_CLIENTS = "manage-clients";
     public static String MANAGE_EVENTS = "manage-events";
 
-    public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, VIEW_EVENTS, VIEW_IDENTITY_PROVIDERS, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS, MANAGE_EVENTS, MANAGE_IDENTITY_PROVIDERS};
+    public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_CLIENTS, VIEW_EVENTS, VIEW_IDENTITY_PROVIDERS, MANAGE_REALM, MANAGE_USERS, MANAGE_CLIENTS, MANAGE_EVENTS, MANAGE_IDENTITY_PROVIDERS};
 
 }
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index e9de509..ad0c51e 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -8,7 +8,7 @@ import java.util.Set;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public interface ClientModel {
+public interface ClientModel extends RoleContainerModel {
 
     // COMMON ATTRIBUTES
 
@@ -16,20 +16,22 @@ public interface ClientModel {
     String PUBLIC_KEY = "publicKey";
     String X509CERTIFICATE = "X509Certificate";
 
-    /**
-     * Internal database key
-     *
-     * @return
-     */
+    void updateApplication();
+
     String getId();
 
-    /**
-     * String exposed to outside world
-     *
-     * @return
-     */
     String getClientId();
 
+    void setClientId(String clientId);
+
+    boolean isEnabled();
+
+    void setEnabled(boolean enabled);
+
+    boolean isSurrogateAuthRequired();
+
+    void setSurrogateAuthRequired(boolean surrogateAuthRequired);
+
     Set<String> getWebOrigins();
 
     void setWebOrigins(Set<String> webOrigins);
@@ -46,10 +48,28 @@ public interface ClientModel {
 
     void removeRedirectUri(String redirectUri);
 
+    String getManagementUrl();
 
-    boolean isEnabled();
+    void setManagementUrl(String url);
 
-    void setEnabled(boolean enabled);
+    String getBaseUrl();
+
+    void setBaseUrl(String url);
+
+    List<String> getDefaultRoles();
+
+    void addDefaultRole(String name);
+
+    void updateDefaultRoles(String[] defaultRoles);
+
+    Set<RoleModel> getApplicationScopeMappings(ClientModel client);
+
+    boolean isBearerOnly();
+    void setBearerOnly(boolean only);
+
+    int getNodeReRegistrationTimeout();
+
+    void setNodeReRegistrationTimeout(int timeout);
 
     boolean validateSecret(String secret);
     String getSecret();
@@ -76,13 +96,15 @@ public interface ClientModel {
     boolean isDirectGrantsOnly();
     void setDirectGrantsOnly(boolean flag);
 
+    boolean isConsentRequired();
+    void setConsentRequired(boolean consentRequired);
+
     Set<RoleModel> getScopeMappings();
     void addScopeMapping(RoleModel role);
     void deleteScopeMapping(RoleModel role);
     Set<RoleModel> getRealmScopeMappings();
     boolean hasScope(RoleModel role);
 
-
     RealmModel getRealm();
 
     /**
@@ -104,4 +126,16 @@ public interface ClientModel {
     void updateProtocolMapper(ProtocolMapperModel mapping);
     public ProtocolMapperModel getProtocolMapperById(String id);
     public ProtocolMapperModel getProtocolMapperByName(String protocol, String name);
+
+    Map<String, Integer> getRegisteredNodes();
+
+    /**
+     * Register node or just update the 'lastReRegistration' time if this node is already registered
+     *
+     * @param nodeHost
+     * @param registrationTime
+     */
+    void registerNode(String nodeHost, int registrationTime);
+
+    void unregisterNode(String nodeHost);
 }
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java
index c39ede4..4919e5f 100644
--- a/model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ApplicationEntity.java
@@ -1,18 +1,31 @@
 package org.keycloak.models.entities;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
-public class ApplicationEntity extends ClientEntity {
+public class ApplicationEntity extends AbstractIdentifiableEntity {
+
+    private String name;
+    private String realmId;
+    private boolean enabled;
+    private String secret;
+    private String protocol;
+    private int notBefore;
+    private boolean publicClient;
+    private boolean fullScopeAllowed;
+    private boolean frontchannelLogout;
 
     private boolean surrogateAuthRequired;
     private String managementUrl;
     private String baseUrl;
     private boolean bearerOnly;
+    private boolean consentRequired;
+    private boolean directGrantsOnly;
     private int nodeReRegistrationTimeout;
 
     // We are using names of defaultRoles (not ids)
@@ -20,6 +33,134 @@ public class ApplicationEntity extends ClientEntity {
 
     private Map<String, Integer> registeredNodes;
 
+    private Map<String, String> attributes = new HashMap<String, String>();
+
+    private List<String> webOrigins = new ArrayList<String>();
+    private List<String> redirectUris = new ArrayList<String>();
+    private List<String> scopeIds = new ArrayList<String>();
+    private List<ClientIdentityProviderMappingEntity> identityProviders = new ArrayList<ClientIdentityProviderMappingEntity>();
+    private List<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
+
+    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 getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    public int getNotBefore() {
+        return notBefore;
+    }
+
+    public void setNotBefore(int notBefore) {
+        this.notBefore = notBefore;
+    }
+
+    public boolean isPublicClient() {
+        return publicClient;
+    }
+
+    public void setPublicClient(boolean publicClient) {
+        this.publicClient = publicClient;
+    }
+
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    public List<String> getWebOrigins() {
+        return webOrigins;
+    }
+
+    public void setWebOrigins(List<String> webOrigins) {
+        this.webOrigins = webOrigins;
+    }
+
+    public List<String> getRedirectUris() {
+        return redirectUris;
+    }
+
+    public void setRedirectUris(List<String> redirectUris) {
+        this.redirectUris = redirectUris;
+    }
+
+    public List<String> getScopeIds() {
+        return scopeIds;
+    }
+
+    public void setScopeIds(List<String> scopeIds) {
+        this.scopeIds = scopeIds;
+    }
+
+    public boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
+
+    public void setFullScopeAllowed(boolean fullScopeAllowed) {
+        this.fullScopeAllowed = fullScopeAllowed;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Map<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+    public boolean isFrontchannelLogout() {
+        return frontchannelLogout;
+    }
+
+    public void setFrontchannelLogout(boolean frontchannelLogout) {
+        this.frontchannelLogout = frontchannelLogout;
+    }
+
+    public List<ClientIdentityProviderMappingEntity> getIdentityProviders() {
+        return this.identityProviders;
+    }
+
+    public void setIdentityProviders(List<ClientIdentityProviderMappingEntity> identityProviders) {
+        this.identityProviders = identityProviders;
+    }
+
+    public List<ProtocolMapperEntity> getProtocolMappers() {
+        return protocolMappers;
+    }
+
+    public void setProtocolMappers(List<ProtocolMapperEntity> protocolMappers) {
+        this.protocolMappers = protocolMappers;
+    }
+
     public boolean isSurrogateAuthRequired() {
         return surrogateAuthRequired;
     }
@@ -52,6 +193,22 @@ public class ApplicationEntity extends ClientEntity {
         this.bearerOnly = bearerOnly;
     }
 
+    public boolean isConsentRequired() {
+        return consentRequired;
+    }
+
+    public void setConsentRequired(boolean consentRequired) {
+        this.consentRequired = consentRequired;
+    }
+
+    public boolean isDirectGrantsOnly() {
+        return directGrantsOnly;
+    }
+
+    public void setDirectGrantsOnly(boolean directGrantsOnly) {
+        this.directGrantsOnly = directGrantsOnly;
+    }
+
     public List<String> getDefaultRoles() {
         return defaultRoles;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/entities/RoleEntity.java b/model/api/src/main/java/org/keycloak/models/entities/RoleEntity.java
index a961c70..a610d39 100644
--- a/model/api/src/main/java/org/keycloak/models/entities/RoleEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/RoleEntity.java
@@ -13,7 +13,7 @@ public class RoleEntity extends AbstractIdentifiableEntity {
     private List<String> compositeRoleIds;
 
     private String realmId;
-    private String applicationId;
+    private String clientId;
 
     public String getName() {
         return name;
@@ -47,11 +47,12 @@ public class RoleEntity extends AbstractIdentifiableEntity {
         this.realmId = realmId;
     }
 
-    public String getApplicationId() {
-        return applicationId;
+    public String getClientId() {
+        return clientId;
     }
 
-    public void setApplicationId(String applicationId) {
-        this.applicationId = applicationId;
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
     }
+
 }
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 81d53a6..0272500 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -19,15 +19,10 @@ 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();
-    }
 
     String getId();
 
@@ -150,33 +145,21 @@ public interface RealmModel extends RoleContainerModel {
 
     void updateDefaultRoles(String[] defaultRoles);
 
-    ClientModel findClient(String clientId);
+    Map<String, ClientModel> getClientNameMap();
 
-    Map<String, ApplicationModel> getApplicationNameMap();
+    List<ClientModel> getClients();
 
-    List<ApplicationModel> getApplications();
+    ClientModel addClient(String name);
 
-    ApplicationModel addApplication(String name);
+    ClientModel addClient(String id, String clientId);
 
-    ApplicationModel addApplication(String id, String name);
+    boolean removeClient(String id);
 
-    boolean removeApplication(String id);
-
-    ApplicationModel getApplicationById(String id);
-    ApplicationModel getApplicationByName(String name);
+    ClientModel getClientById(String id);
+    ClientModel getClientByClientId(String clientId);
 
     void updateRequiredCredentials(Set<String> creds);
 
-    OAuthClientModel addOAuthClient(String name);
-
-    OAuthClientModel addOAuthClient(String id, String name);
-
-    OAuthClientModel getOAuthClient(String name);
-    OAuthClientModel getOAuthClientById(String id);
-    boolean removeOAuthClient(String id);
-
-    List<OAuthClientModel> getOAuthClients();
-
     Map<String, String> getBrowserSecurityHeaders();
     void setBrowserSecurityHeaders(Map<String, String> headers);
 
@@ -249,11 +232,9 @@ public interface RealmModel extends RoleContainerModel {
 
     void setEnabledEventTypes(Set<String> enabledEventTypes);
 
-    ApplicationModel getMasterAdminApp();
-
-    void setMasterAdminApp(ApplicationModel app);
+    ClientModel getMasterAdminApp();
 
-    ClientModel findClientById(String id);
+    void setMasterAdminApp(ClientModel app);
 
     boolean isIdentityFederationEnabled();
 
diff --git a/model/api/src/main/java/org/keycloak/models/RealmProvider.java b/model/api/src/main/java/org/keycloak/models/RealmProvider.java
index 58328b2..17de99d 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmProvider.java
@@ -1,7 +1,6 @@
 package org.keycloak.models;
 
 import org.keycloak.provider.Provider;
-import org.keycloak.provider.ProviderEvent;
 
 import java.util.List;
 
@@ -19,8 +18,7 @@ public interface RealmProvider extends Provider {
     RealmModel getRealmByName(String name);
 
     RoleModel getRoleById(String id, RealmModel realm);
-    ApplicationModel getApplicationById(String id, RealmModel realm);
-    OAuthClientModel getOAuthClientById(String id, RealmModel realm);
+    ClientModel getClientById(String id, RealmModel realm);
     List<RealmModel> getRealms();
     boolean removeRealm(String id);
 
diff --git a/model/api/src/main/java/org/keycloak/models/UserModel.java b/model/api/src/main/java/org/keycloak/models/UserModel.java
index ee8ce80..9055e7c 100755
--- a/model/api/src/main/java/org/keycloak/models/UserModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserModel.java
@@ -66,7 +66,7 @@ public interface UserModel {
     void updateCredentialDirectly(UserCredentialValueModel cred);
 
     Set<RoleModel> getRealmRoleMappings();
-    Set<RoleModel> getApplicationRoleMappings(ApplicationModel app);
+    Set<RoleModel> getApplicationRoleMappings(ClientModel app);
     boolean hasRole(RoleModel role);
     void grantRole(RoleModel role);
     Set<RoleModel> getRoleMappings();
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
index b7421de..3a64206 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
@@ -3,7 +3,6 @@ package org.keycloak.models;
 import org.keycloak.provider.Provider;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index af0b92d..71d9ae7 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -1,8 +1,6 @@
 package org.keycloak.models.utils;
 
 import org.bouncycastle.openssl.PEMWriter;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClaimMask;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
@@ -174,8 +172,8 @@ public final class KeycloakModelUtils {
         return UUID.randomUUID().toString();
     }
 
-    public static ApplicationModel createApplication(RealmModel realm, String name) {
-        ApplicationModel app = realm.addApplication(name);
+    public static ClientModel createApplication(RealmModel realm, String name) {
+        ClientModel app = realm.addClient(name);
         generateSecret(app);
         app.setFullScopeAllowed(true);
 
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 78a64ca..09fc0a5 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,13 +1,10 @@
 package org.keycloak.models.utils;
 
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClaimMask;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
@@ -17,12 +14,10 @@ import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.representations.idm.ClaimRepresentation;
 import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.FederatedIdentityRepresentation;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.representations.idm.OAuthClientRepresentation;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -217,57 +212,54 @@ public class ModelToRepresentation {
         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());
-            }
+            rep.getApplications().put(client.getId(), client.getClientId());
         }
         return rep;
     }
 
-    public static ApplicationRepresentation toRepresentation(ApplicationModel applicationModel) {
+    public static ApplicationRepresentation toRepresentation(ClientModel clientModel) {
         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();
+        rep.setId(clientModel.getId());
+        rep.setName(clientModel.getClientId());
+        rep.setEnabled(clientModel.isEnabled());
+        rep.setAdminUrl(clientModel.getManagementUrl());
+        rep.setPublicClient(clientModel.isPublicClient());
+        rep.setFrontchannelLogout(clientModel.isFrontchannelLogout());
+        rep.setProtocol(clientModel.getProtocol());
+        rep.setAttributes(clientModel.getAttributes());
+        rep.setFullScopeAllowed(clientModel.isFullScopeAllowed());
+        rep.setBearerOnly(clientModel.isBearerOnly());
+        rep.setConsentRequired(clientModel.isConsentRequired());
+        rep.setSurrogateAuthRequired(clientModel.isSurrogateAuthRequired());
+        rep.setBaseUrl(clientModel.getBaseUrl());
+        rep.setNotBefore(clientModel.getNotBefore());
+        rep.setNodeReRegistrationTimeout(clientModel.getNodeReRegistrationTimeout());
+
+        Set<String> redirectUris = clientModel.getRedirectUris();
         if (redirectUris != null) {
             rep.setRedirectUris(new LinkedList<String>(redirectUris));
         }
 
-        Set<String> webOrigins = applicationModel.getWebOrigins();
+        Set<String> webOrigins = clientModel.getWebOrigins();
         if (webOrigins != null) {
             rep.setWebOrigins(new LinkedList<String>(webOrigins));
         }
 
-        if (!applicationModel.getDefaultRoles().isEmpty()) {
-            rep.setDefaultRoles(applicationModel.getDefaultRoles().toArray(new String[0]));
+        if (!clientModel.getDefaultRoles().isEmpty()) {
+            rep.setDefaultRoles(clientModel.getDefaultRoles().toArray(new String[0]));
         }
 
-        if (!applicationModel.getRegisteredNodes().isEmpty()) {
-            rep.setRegisteredNodes(new HashMap<String, Integer>(applicationModel.getRegisteredNodes()));
+        if (!clientModel.getRegisteredNodes().isEmpty()) {
+            rep.setRegisteredNodes(new HashMap<String, Integer>(clientModel.getRegisteredNodes()));
         }
 
-        if (!applicationModel.getIdentityProviders().isEmpty()) {
-            rep.setIdentityProviders(toRepresentation(applicationModel.getIdentityProviders()));
+        if (!clientModel.getIdentityProviders().isEmpty()) {
+            rep.setIdentityProviders(toRepresentation(clientModel.getIdentityProviders()));
         }
 
-        if (!applicationModel.getProtocolMappers().isEmpty()) {
+        if (!clientModel.getProtocolMappers().isEmpty()) {
             List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
-            for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) {
+            for (ProtocolMapperModel model : clientModel.getProtocolMappers()) {
                 mappings.add(toRepresentation(model));
             }
             rep.setProtocolMappers(mappings);
@@ -291,43 +283,6 @@ public class ModelToRepresentation {
         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());
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 4ebc2d0..66c75b6 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
@@ -4,7 +4,6 @@ import net.iharder.Base64;
 import org.jboss.logging.Logger;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.migration.MigrationProvider;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.BrowserSecurityHeaders;
 import org.keycloak.models.ClaimMask;
 import org.keycloak.models.ClientIdentityProviderMappingModel;
@@ -12,7 +11,6 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
@@ -130,7 +128,7 @@ public class RepresentationToModel {
         importIdentityProviders(rep, newRealm);
 
         if (rep.getApplications() != null) {
-            Map<String, ApplicationModel> appMap = createApplications(session, rep, newRealm);
+            Map<String, ClientModel> appMap = createApplications(session, rep, newRealm);
         }
 
         if (rep.getRoles() != null) {
@@ -141,7 +139,7 @@ public class RepresentationToModel {
             }
             if (rep.getRoles().getApplication() != null) {
                 for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
-                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    ClientModel app = newRealm.getClientByClientId(entry.getKey());
                     if (app == null) {
                         throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
                     }
@@ -161,7 +159,7 @@ public class RepresentationToModel {
             }
             if (rep.getRoles().getApplication() != null) {
                 for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
-                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    ClientModel app = newRealm.getClientByClientId(entry.getKey());
                     if (app == null) {
                         throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
                     }
@@ -183,7 +181,7 @@ public class RepresentationToModel {
         if (rep.getApplications() != null) {
             for (ApplicationRepresentation resourceRep : rep.getApplications()) {
                 if (resourceRep.getDefaultRoles() != null) {
-                    ApplicationModel appModel = newRealm.getApplicationByName(resourceRep.getName());
+                    ClientModel appModel = newRealm.getClientByClientId(resourceRep.getName());
                     appModel.updateDefaultRoles(resourceRep.getDefaultRoles());
                 }
             }
@@ -196,12 +194,12 @@ public class RepresentationToModel {
 
         // Now that all possible roles and applications are created, create scope mappings
 
-        Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap();
+        Map<String, ClientModel> appMap = newRealm.getClientNameMap();
 
         if (rep.getApplicationScopeMappings() != null) {
 
             for (Map.Entry<String, List<ScopeMappingRepresentation>> entry : rep.getApplicationScopeMappings().entrySet()) {
-                ApplicationModel app = appMap.get(entry.getKey());
+                ClientModel app = appMap.get(entry.getKey());
                 if (app == null) {
                     throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
                 }
@@ -211,7 +209,7 @@ public class RepresentationToModel {
 
         if (rep.getScopeMappings() != null) {
             for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
-                ClientModel client = newRealm.findClient(scope.getClient());
+                ClientModel client = newRealm.getClientByClientId(scope.getClient());
                 if (client == null) {
                     throw new RuntimeException("Unknown client specification in realm scope mappings");
                 }
@@ -434,7 +432,7 @@ public class RepresentationToModel {
         }
         if (roleRep.getComposites().getApplication() != null) {
             for (Map.Entry<String, List<String>> entry : roleRep.getComposites().getApplication().entrySet()) {
-                ApplicationModel app = realm.getApplicationByName(entry.getKey());
+                ClientModel app = realm.getClientByClientId(entry.getKey());
                 if (app == null) {
                     throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName());
                 }
@@ -452,11 +450,11 @@ public class RepresentationToModel {
 
     // APPLICATIONS
 
-    private static Map<String, ApplicationModel> createApplications(KeycloakSession session, RealmRepresentation rep, RealmModel realm) {
-        Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
+    private static Map<String, ClientModel> createApplications(KeycloakSession session, RealmRepresentation rep, RealmModel realm) {
+        Map<String, ClientModel> appMap = new HashMap<String, ClientModel>();
         for (ApplicationRepresentation resourceRep : rep.getApplications()) {
-            ApplicationModel app = createApplication(session, realm, resourceRep, false);
-            appMap.put(app.getName(), app);
+            ClientModel app = createApplication(session, realm, resourceRep, false);
+            appMap.put(app.getClientId(), app);
         }
         return appMap;
     }
@@ -468,7 +466,7 @@ public class RepresentationToModel {
      * @param resourceRep
      * @return
      */
-    public static ApplicationModel createApplication(KeycloakSession session, RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
+    public static ClientModel createApplication(KeycloakSession session, RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
         logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
 
         if (resourceRep.getProtocolMappers() == null) {
@@ -478,7 +476,7 @@ public class RepresentationToModel {
             }
         }
 
-        ApplicationModel applicationModel = resourceRep.getId()!=null ? realm.addApplication(resourceRep.getId(), resourceRep.getName()) : realm.addApplication(resourceRep.getName());
+        ClientModel applicationModel = resourceRep.getId()!=null ? realm.addClient(resourceRep.getId(), resourceRep.getName()) : realm.addClient(resourceRep.getName());
         if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled());
         applicationModel.setManagementUrl(resourceRep.getAdminUrl());
         if (resourceRep.isSurrogateAuthRequired() != null)
@@ -573,10 +571,11 @@ public class RepresentationToModel {
         return applicationModel;
     }
 
-    public static void updateApplication(ApplicationRepresentation rep, ApplicationModel resource) {
-        if (rep.getName() != null) resource.setName(rep.getName());
+    public static void updateApplication(ApplicationRepresentation rep, ClientModel resource) {
+        if (rep.getName() != null) resource.setClientId(rep.getName());
         if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
         if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
+        if (rep.isConsentRequired() != null) resource.setConsentRequired(rep.isConsentRequired());
         if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
         if (rep.isFullScopeAllowed() != null) resource.setFullScopeAllowed(rep.isFullScopeAllowed());
         if (rep.isFrontchannelLogout() != null) resource.setFrontchannelLogout(rep.isFrontchannelLogout());
@@ -684,14 +683,15 @@ public class RepresentationToModel {
         }
     }
 
-    public static OAuthClientModel createOAuthClient(String id, String name, RealmModel realm) {
-        OAuthClientModel model = id!=null ? realm.addOAuthClient(id, name) : realm.addOAuthClient(name);
+    public static ClientModel createOAuthClient(String id, String name, RealmModel realm) {
+        ClientModel model = id!=null ? realm.addClient(id, name) : realm.addClient(name);
+        model.setConsentRequired(true);
         KeycloakModelUtils.generateSecret(model);
         return model;
     }
 
-    public static OAuthClientModel createOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, RealmModel realm) {
-        OAuthClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
+    public static ClientModel createOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, RealmModel realm) {
+        ClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
 
         model.updateIdentityProviders(toModel(rep.getIdentityProviders(), realm));
 
@@ -699,7 +699,7 @@ public class RepresentationToModel {
         return model;
     }
 
-    public static void updateOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, OAuthClientModel model) {
+    public static void updateOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, ClientModel model) {
         if (rep.getProtocolMappers() == null) {
             List<ProtocolMapperRepresentation> convertedProtocolMappers = convertDeprecatedClaimsMask(session, rep.getClaims());
             if (convertedProtocolMappers != null) {
@@ -753,9 +753,9 @@ public class RepresentationToModel {
 
     // Scope mappings
 
-    public static void createApplicationScopeMappings(RealmModel realm, ApplicationModel applicationModel, List<ScopeMappingRepresentation> mappings) {
+    public static void createApplicationScopeMappings(RealmModel realm, ClientModel applicationModel, List<ScopeMappingRepresentation> mappings) {
         for (ScopeMappingRepresentation mapping : mappings) {
-            ClientModel client = realm.findClient(mapping.getClient());
+            ClientModel client = realm.getClientByClientId(mapping.getClient());
             if (client == null) {
                 throw new RuntimeException("Unknown client specified in application scope mappings");
             }
@@ -771,7 +771,7 @@ public class RepresentationToModel {
 
     // Users
 
-    public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
+    public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map<String, ClientModel> appMap) {
         convertDeprecatedSocialProviders(userRep);
 
         // Import users just to user storage. Don't federate
@@ -814,7 +814,7 @@ public class RepresentationToModel {
         }
         if (userRep.getApplicationRoles() != null) {
             for (Map.Entry<String, List<String>> entry : userRep.getApplicationRoles().entrySet()) {
-                ApplicationModel app = appMap.get(entry.getKey());
+                ClientModel app = appMap.get(entry.getKey());
                 if (app == null) {
                     throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
                 }
@@ -853,7 +853,7 @@ public class RepresentationToModel {
 
     // Role mappings
 
-    public static void createApplicationRoleMappings(ApplicationModel applicationModel, UserModel user, List<String> roleNames) {
+    public static void createApplicationRoleMappings(ClientModel applicationModel, UserModel user, List<String> roleNames) {
         if (user == null) {
             throw new RuntimeException("User not found");
         }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java b/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
index 90f54bd..40665e3 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
@@ -1,6 +1,6 @@
 package org.keycloak.models.utils;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
@@ -152,7 +152,7 @@ public class UserModelDelegate implements UserModel {
     }
 
     @Override
-    public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
+    public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
         return delegate.getApplicationRoleMappings(app);
     }
 
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
index 6c47bdf..ca92129 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
@@ -1,420 +1,660 @@
-/*
- * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
- * as indicated by the @author tags. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.keycloak.models.file.adapter;
-
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RealmProvider;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.entities.ClientEntity;
-
-import java.util.ArrayList;
-import java.util.Collection;
-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.models.ClientIdentityProviderMappingModel;
-import org.keycloak.models.ProtocolMapperModel;
-import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
-import org.keycloak.models.entities.ProtocolMapperEntity;
-import org.keycloak.models.utils.KeycloakModelUtils;
-
-/**
- * ClientModel for JSON persistence.
- *
- * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
- */
-public abstract class ClientAdapter implements ClientModel {
-
-    protected final ClientEntity clientEntity;
-    protected final RealmModel realm;
-    protected  KeycloakSession session;
-    private final RealmProvider model;
-
-    private final Map<String, RoleModel> allScopeMappings = new HashMap<String, RoleModel>();
-
-    public ClientAdapter(KeycloakSession session, RealmModel realm, ClientEntity clientEntity) {
-        this.clientEntity = clientEntity;
-        this.realm = realm;
-        this.session = session;
-        this.model = session.realms();
-    }
-
-    @Override
-    public String getId() {
-        return clientEntity.getId();
-    }
-
-    @Override
-    public String getClientId() {
-        return clientEntity.getName();
-    }
-
-    @Override
-    public Set<String> getWebOrigins() {
-        Set<String> result = new HashSet<String>();
-        if (clientEntity.getWebOrigins() != null) {
-            result.addAll(clientEntity.getWebOrigins());
-        }
-        return result;
-    }
-
-    @Override
-    public void setWebOrigins(Set<String> webOrigins) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(webOrigins);
-        clientEntity.setWebOrigins(result);
-    }
-
-    @Override
-    public void addWebOrigin(String webOrigin) {
-        Set<String> webOrigins = getWebOrigins();
-        webOrigins.add(webOrigin);
-        setWebOrigins(webOrigins);
-    }
-
-    @Override
-    public void removeWebOrigin(String webOrigin) {
-        Set<String> webOrigins = getWebOrigins();
-        webOrigins.remove(webOrigin);
-        setWebOrigins(webOrigins);
-    }
-
-    @Override
-    public Set<String> getRedirectUris() {
-        Set<String> result = new HashSet<String>();
-        if (clientEntity.getRedirectUris() != null) {
-            result.addAll(clientEntity.getRedirectUris());
-        }
-        return result;
-    }
-
-    @Override
-    public void setRedirectUris(Set<String> redirectUris) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(redirectUris);
-        clientEntity.setRedirectUris(result);
-    }
-
-    @Override
-    public void addRedirectUri(String redirectUri) {
-        if (clientEntity.getRedirectUris().contains(redirectUri)) return;
-        clientEntity.getRedirectUris().add(redirectUri);
-    }
-
-    @Override
-    public void removeRedirectUri(String redirectUri) {
-        clientEntity.getRedirectUris().remove(redirectUri);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return clientEntity.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        clientEntity.setEnabled(enabled);
-    }
-
-    @Override
-    public boolean validateSecret(String secret) {
-        return secret.equals(clientEntity.getSecret());
-    }
-
-    @Override
-    public String getSecret() {
-        return clientEntity.getSecret();
-    }
-
-    @Override
-    public void setSecret(String secret) {
-        clientEntity.setSecret(secret);
-    }
-
-    @Override
-    public boolean isPublicClient() {
-        return clientEntity.isPublicClient();
-    }
-
-    @Override
-    public void setPublicClient(boolean flag) {
-        clientEntity.setPublicClient(flag);
-    }
-
-
-    @Override
-    public boolean isFrontchannelLogout() {
-        return clientEntity.isFrontchannelLogout();
-    }
-
-    @Override
-    public void setFrontchannelLogout(boolean flag) {
-        clientEntity.setFrontchannelLogout(flag);
-    }
-
-    @Override
-    public boolean isFullScopeAllowed() {
-        return clientEntity.isFullScopeAllowed();
-    }
-
-    @Override
-    public void setFullScopeAllowed(boolean value) {
-        clientEntity.setFullScopeAllowed(value);
-
-    }
-
-    @Override
-    public RealmModel getRealm() {
-        return realm;
-    }
-
-    @Override
-    public int getNotBefore() {
-        return clientEntity.getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        clientEntity.setNotBefore(notBefore);
-    }
-
-    @Override
-    public Set<RoleModel> getScopeMappings() {
-        return new HashSet<RoleModel>(allScopeMappings.values());
-    }
-
-    @Override
-    public Set<RoleModel> getRealmScopeMappings() {
-        Set<RoleModel> allScopes = getScopeMappings();
-
-        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
-        for (RoleModel role : allScopes) {
-            RoleAdapter roleAdapter = (RoleAdapter)role;
-            if (roleAdapter.isRealmRole()) {
-                realmRoles.add(role);
-            }
-        }
-        return realmRoles;
-    }
-
-    @Override
-    public boolean hasScope(RoleModel role) {
-        if (isFullScopeAllowed()) return true;
-        Set<RoleModel> roles = getScopeMappings();
-        if (roles.contains(role)) return true;
-
-        for (RoleModel mapping : roles) {
-            if (mapping.hasRole(role)) return true;
-        }
-        return false;
-    }
-
-
-    @Override
-    public void addScopeMapping(RoleModel role) {
-        allScopeMappings.put(role.getId(), role);
-    }
-
-    @Override
-    public void deleteScopeMapping(RoleModel role) {
-        allScopeMappings.remove(role.getId());
-    }
-
-    @Override
-    public String getProtocol() {
-        return clientEntity.getProtocol();
-    }
-
-    @Override
-    public void setProtocol(String protocol) {
-        clientEntity.setProtocol(protocol);
-
-    }
-
-    @Override
-    public void setAttribute(String name, String value) {
-        clientEntity.getAttributes().put(name, value);
-
-    }
-
-    @Override
-    public void removeAttribute(String name) {
-        clientEntity.getAttributes().remove(name);
-    }
-
-    @Override
-    public String getAttribute(String name) {
-        return clientEntity.getAttributes().get(name);
-    }
-
-    @Override
-    public Map<String, String> getAttributes() {
-        Map<String, String> copy = new HashMap<String, String>();
-        copy.putAll(clientEntity.getAttributes());
-        return copy;
-    }
-
-    @Override
-    public Set<ProtocolMapperModel> getProtocolMappers() {
-        Set<ProtocolMapperModel> result = new HashSet<ProtocolMapperModel>();
-        for (ProtocolMapperEntity entity : clientEntity.getProtocolMappers()) {
-            ProtocolMapperModel model = getProtocolMapperById(entity.getId());
-            if (model != null) result.add(model);
-        }
-        return result;
-    }
-
-    @Override
-    public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
-        if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
-            throw new RuntimeException("protocol mapper name must be unique per protocol");
-        }
-        ProtocolMapperEntity entity = new ProtocolMapperEntity();
-        entity.setId(KeycloakModelUtils.generateId());
-        entity.setProtocol(model.getProtocol());
-        entity.setName(model.getName());
-        entity.setProtocolMapper(model.getProtocolMapper());
-        entity.setConfig(model.getConfig());
-        entity.setConsentRequired(model.isConsentRequired());
-        entity.setConsentText(model.getConsentText());
-        clientEntity.getProtocolMappers().add(entity);
-        return entityToModel(entity);
-    }
-
-    @Override
-    public void removeProtocolMapper(ProtocolMapperModel mapping) {
-        ProtocolMapperEntity toBeRemoved = null;
-        for (ProtocolMapperEntity entity : clientEntity.getProtocolMappers()) {
-            if (entity.getId().equals(mapping.getId())) {
-                toBeRemoved = entity;
-                break;
-            }
-        }
-
-        clientEntity.getProtocolMappers().remove(toBeRemoved);
-    }
-
-    @Override
-    public void updateProtocolMapper(ProtocolMapperModel mapping) {
-        ProtocolMapperEntity entity = getProtocolMapperEntityById(mapping.getId());
-        entity.setProtocolMapper(mapping.getProtocolMapper());
-        entity.setConsentRequired(mapping.isConsentRequired());
-        entity.setConsentText(mapping.getConsentText());
-        if (entity.getConfig() != null) {
-            entity.getConfig().clear();
-            entity.getConfig().putAll(mapping.getConfig());
-        } else {
-            entity.setConfig(mapping.getConfig());
-        }
-    }
-
-    protected ProtocolMapperEntity getProtocolMapperEntityById(String id) {
-        for (ProtocolMapperEntity entity : clientEntity.getProtocolMappers()) {
-            if (entity.getId().equals(id)) {
-                return entity;
-            }
-        }
-        return null;
-    }
-
-    protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
-        for (ProtocolMapperEntity entity : clientEntity.getProtocolMappers()) {
-            if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-
-    @Override
-    public ProtocolMapperModel getProtocolMapperById(String id) {
-        ProtocolMapperEntity entity = getProtocolMapperEntityById(id);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    @Override
-    public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
-        ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
-        ProtocolMapperModel mapping = new ProtocolMapperModel();
-        mapping.setId(entity.getId());
-        mapping.setName(entity.getName());
-        mapping.setProtocol(entity.getProtocol());
-        mapping.setProtocolMapper(entity.getProtocolMapper());
-        mapping.setConsentRequired(entity.isConsentRequired());
-        mapping.setConsentText(entity.getConsentText());
-        Map<String, String> config = new HashMap<String, String>();
-        if (entity.getConfig() != null) config.putAll(entity.getConfig());
-        mapping.setConfig(config);
-        return mapping;
-    }
-
-    @Override
-    public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
-        List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
-
-        for (ClientIdentityProviderMappingModel model : identityProviders) {
-            ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
-
-            entity.setId(model.getIdentityProvider());
-            entity.setRetrieveToken(model.isRetrieveToken());
-            stored.add(entity);
-        }
-
-        clientEntity.setIdentityProviders(stored);
-    }
-
-    @Override
-    public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
-        List<ClientIdentityProviderMappingModel> models = new ArrayList<ClientIdentityProviderMappingModel>();
-
-        for (ClientIdentityProviderMappingEntity entity : clientEntity.getIdentityProviders()) {
-            ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
-
-            model.setIdentityProvider(entity.getId());
-            model.setRetrieveToken(entity.isRetrieveToken());
-
-            models.add(model);
-        }
-
-        return models;
-    }
-
-    @Override
-    public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
-        for (ClientIdentityProviderMappingEntity identityProviderMappingModel : clientEntity.getIdentityProviders()) {
-            if (identityProviderMappingModel.getId().equals(providerId)) {
-                return identityProviderMappingModel.isRetrieveToken();
-            }
-        }
-
-        return false;
-    }
-
-}
+/*
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.models.file.adapter;
+
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.keycloak.connections.file.InMemoryModel;
+import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.entities.ApplicationEntity;
+import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
+import org.keycloak.models.entities.ProtocolMapperEntity;
+import org.keycloak.models.entities.RoleEntity;
+import org.keycloak.models.utils.KeycloakModelUtils;
+
+/**
+ * ApplicationModel used for JSON persistence.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
+ */
+public class ClientAdapter implements ClientModel {
+
+    private final RealmModel realm;
+    private  KeycloakSession session;
+    private final ApplicationEntity entity;
+    private final InMemoryModel inMemoryModel;
+
+    private final Map<String, RoleAdapter> allRoles = new HashMap<String, RoleAdapter>();
+    private final Map<String, RoleModel> allScopeMappings = new HashMap<String, RoleModel>();
+
+    public ClientAdapter(KeycloakSession session, RealmModel realm, ApplicationEntity entity, InMemoryModel inMemoryModel) {
+        this.realm = realm;
+        this.session = session;
+        this.entity = entity;
+        this.inMemoryModel = inMemoryModel;
+    }
+
+    @Override
+    public void updateApplication() {
+    }
+
+    @Override
+    public String getId() {
+        return entity.getId();
+    }
+
+    @Override
+    public Set<String> getWebOrigins() {
+        Set<String> result = new HashSet<String>();
+        if (entity.getWebOrigins() != null) {
+            result.addAll(entity.getWebOrigins());
+        }
+        return result;
+    }
+
+    @Override
+    public void setWebOrigins(Set<String> webOrigins) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(webOrigins);
+        entity.setWebOrigins(result);
+    }
+
+    @Override
+    public void addWebOrigin(String webOrigin) {
+        Set<String> webOrigins = getWebOrigins();
+        webOrigins.add(webOrigin);
+        setWebOrigins(webOrigins);
+    }
+
+    @Override
+    public void removeWebOrigin(String webOrigin) {
+        Set<String> webOrigins = getWebOrigins();
+        webOrigins.remove(webOrigin);
+        setWebOrigins(webOrigins);
+    }
+
+    @Override
+    public Set<String> getRedirectUris() {
+        Set<String> result = new HashSet<String>();
+        if (entity.getRedirectUris() != null) {
+            result.addAll(entity.getRedirectUris());
+        }
+        return result;
+    }
+
+    @Override
+    public void setRedirectUris(Set<String> redirectUris) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(redirectUris);
+        entity.setRedirectUris(result);
+    }
+
+    @Override
+    public void addRedirectUri(String redirectUri) {
+        if (entity.getRedirectUris().contains(redirectUri)) return;
+        entity.getRedirectUris().add(redirectUri);
+    }
+
+    @Override
+    public void removeRedirectUri(String redirectUri) {
+        entity.getRedirectUris().remove(redirectUri);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return entity.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        entity.setEnabled(enabled);
+    }
+
+    @Override
+    public boolean validateSecret(String secret) {
+        return secret.equals(entity.getSecret());
+    }
+
+    @Override
+    public String getSecret() {
+        return entity.getSecret();
+    }
+
+    @Override
+    public void setSecret(String secret) {
+        entity.setSecret(secret);
+    }
+
+    @Override
+    public boolean isPublicClient() {
+        return entity.isPublicClient();
+    }
+
+    @Override
+    public void setPublicClient(boolean flag) {
+        entity.setPublicClient(flag);
+    }
+
+
+    @Override
+    public boolean isFrontchannelLogout() {
+        return entity.isFrontchannelLogout();
+    }
+
+    @Override
+    public void setFrontchannelLogout(boolean flag) {
+        entity.setFrontchannelLogout(flag);
+    }
+
+    @Override
+    public boolean isFullScopeAllowed() {
+        return entity.isFullScopeAllowed();
+    }
+
+    @Override
+    public void setFullScopeAllowed(boolean value) {
+        entity.setFullScopeAllowed(value);
+    }
+
+    @Override
+    public RealmModel getRealm() {
+        return realm;
+    }
+
+    @Override
+    public int getNotBefore() {
+        return entity.getNotBefore();
+    }
+
+    @Override
+    public void setNotBefore(int notBefore) {
+        entity.setNotBefore(notBefore);
+    }
+
+    @Override
+    public Set<RoleModel> getScopeMappings() {
+        return new HashSet<RoleModel>(allScopeMappings.values());
+    }
+
+    @Override
+    public Set<RoleModel> getRealmScopeMappings() {
+        Set<RoleModel> allScopes = getScopeMappings();
+
+        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
+        for (RoleModel role : allScopes) {
+            RoleAdapter roleAdapter = (RoleAdapter)role;
+            if (roleAdapter.isRealmRole()) {
+                realmRoles.add(role);
+            }
+        }
+        return realmRoles;
+    }
+
+    @Override
+    public void addScopeMapping(RoleModel role) {
+        allScopeMappings.put(role.getId(), role);
+    }
+
+    @Override
+    public void deleteScopeMapping(RoleModel role) {
+        allScopeMappings.remove(role.getId());
+    }
+
+    @Override
+    public String getProtocol() {
+        return entity.getProtocol();
+    }
+
+    @Override
+    public void setProtocol(String protocol) {
+        entity.setProtocol(protocol);
+
+    }
+
+    @Override
+    public void setAttribute(String name, String value) {
+        entity.getAttributes().put(name, value);
+
+    }
+
+    @Override
+    public void removeAttribute(String name) {
+        entity.getAttributes().remove(name);
+    }
+
+    @Override
+    public String getAttribute(String name) {
+        return entity.getAttributes().get(name);
+    }
+
+    @Override
+    public Map<String, String> getAttributes() {
+        Map<String, String> copy = new HashMap<String, String>();
+        copy.putAll(entity.getAttributes());
+        return copy;
+    }
+
+    @Override
+    public Set<ProtocolMapperModel> getProtocolMappers() {
+        Set<ProtocolMapperModel> result = new HashSet<ProtocolMapperModel>();
+        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+            ProtocolMapperModel model = getProtocolMapperById(entity.getId());
+            if (model != null) result.add(model);
+        }
+        return result;
+    }
+
+    @Override
+    public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
+        if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
+            throw new RuntimeException("protocol mapper name must be unique per protocol");
+        }
+        ProtocolMapperEntity entity = new ProtocolMapperEntity();
+        entity.setId(KeycloakModelUtils.generateId());
+        entity.setProtocol(model.getProtocol());
+        entity.setName(model.getName());
+        entity.setProtocolMapper(model.getProtocolMapper());
+        entity.setConfig(model.getConfig());
+        entity.setConsentRequired(model.isConsentRequired());
+        entity.setConsentText(model.getConsentText());
+        this.entity.getProtocolMappers().add(entity);
+        return entityToModel(entity);
+    }
+
+    @Override
+    public void removeProtocolMapper(ProtocolMapperModel mapping) {
+        ProtocolMapperEntity toBeRemoved = null;
+        for (ProtocolMapperEntity e : entity.getProtocolMappers()) {
+            if (e.getId().equals(mapping.getId())) {
+                toBeRemoved = e;
+                break;
+            }
+        }
+
+        entity.getProtocolMappers().remove(toBeRemoved);
+    }
+
+    @Override
+    public void updateProtocolMapper(ProtocolMapperModel mapping) {
+        ProtocolMapperEntity entity = getProtocolMapperEntityById(mapping.getId());
+        entity.setProtocolMapper(mapping.getProtocolMapper());
+        entity.setConsentRequired(mapping.isConsentRequired());
+        entity.setConsentText(mapping.getConsentText());
+        if (entity.getConfig() != null) {
+            entity.getConfig().clear();
+            entity.getConfig().putAll(mapping.getConfig());
+        } else {
+            entity.setConfig(mapping.getConfig());
+        }
+    }
+
+    protected ProtocolMapperEntity getProtocolMapperEntityById(String id) {
+        for (ProtocolMapperEntity e : entity.getProtocolMappers()) {
+            if (e.getId().equals(id)) {
+                return e;
+            }
+        }
+        return null;
+    }
+
+    protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
+        for (ProtocolMapperEntity e : entity.getProtocolMappers()) {
+            if (e.getProtocol().equals(protocol) && e.getName().equals(name)) {
+                return e;
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public ProtocolMapperModel getProtocolMapperById(String id) {
+        ProtocolMapperEntity entity = getProtocolMapperEntityById(id);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    @Override
+    public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+        ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
+        ProtocolMapperModel mapping = new ProtocolMapperModel();
+        mapping.setId(entity.getId());
+        mapping.setName(entity.getName());
+        mapping.setProtocol(entity.getProtocol());
+        mapping.setProtocolMapper(entity.getProtocolMapper());
+        mapping.setConsentRequired(entity.isConsentRequired());
+        mapping.setConsentText(entity.getConsentText());
+        Map<String, String> config = new HashMap<String, String>();
+        if (entity.getConfig() != null) config.putAll(entity.getConfig());
+        mapping.setConfig(config);
+        return mapping;
+    }
+
+    @Override
+    public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
+        List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
+
+        for (ClientIdentityProviderMappingModel model : identityProviders) {
+            ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
+
+            entity.setId(model.getIdentityProvider());
+            entity.setRetrieveToken(model.isRetrieveToken());
+            stored.add(entity);
+        }
+
+        entity.setIdentityProviders(stored);
+    }
+
+    @Override
+    public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
+        List<ClientIdentityProviderMappingModel> models = new ArrayList<>();
+
+        for (ClientIdentityProviderMappingEntity e : entity.getIdentityProviders()) {
+            ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
+
+            model.setIdentityProvider(e.getId());
+            model.setRetrieveToken(e.isRetrieveToken());
+
+            models.add(model);
+        }
+
+        return models;
+    }
+
+    @Override
+    public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
+        for (ClientIdentityProviderMappingEntity identityProviderMappingModel : entity.getIdentityProviders()) {
+            if (identityProviderMappingModel.getId().equals(providerId)) {
+                return identityProviderMappingModel.isRetrieveToken();
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public String getClientId() {
+        return entity.getName();
+    }
+
+    @Override
+    public void setClientId(String clientId) {
+        if (appNameExists(clientId)) throw new ModelDuplicateException("Application named " + clientId + " already exists.");
+        entity.setName(clientId);
+    }
+
+    private boolean appNameExists(String name) {
+        for (ClientModel app : realm.getClients()) {
+            if (app == this) continue;
+            if (app.getClientId().equals(name)) return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isSurrogateAuthRequired() {
+        return entity.isSurrogateAuthRequired();
+    }
+
+    @Override
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        entity.setSurrogateAuthRequired(surrogateAuthRequired);
+    }
+
+    @Override
+    public String getManagementUrl() {
+        return entity.getManagementUrl();
+    }
+
+    @Override
+    public void setManagementUrl(String url) {
+        entity.setManagementUrl(url);
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        entity.setBaseUrl(url);
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return entity.getBaseUrl();
+    }
+
+    @Override
+    public boolean isBearerOnly() {
+        return entity.isBearerOnly();
+    }
+
+    @Override
+    public void setBearerOnly(boolean only) {
+        entity.setBearerOnly(only);
+    }
+
+    @Override
+    public boolean isConsentRequired() {
+        return entity.isConsentRequired();
+    }
+
+    @Override
+    public void setConsentRequired(boolean consentRequired) {
+        entity.setConsentRequired(consentRequired);
+    }
+
+    @Override
+    public boolean isDirectGrantsOnly() {
+        return entity.isDirectGrantsOnly();
+    }
+
+    @Override
+    public void setDirectGrantsOnly(boolean flag) {
+        entity.setDirectGrantsOnly(flag);
+    }
+
+    @Override
+    public RoleAdapter getRole(String name) {
+        for (RoleAdapter role : allRoles.values()) {
+            if (role.getName().equals(name)) return role;
+        }
+        return null;
+    }
+
+    @Override
+    public RoleAdapter addRole(String name) {
+        return this.addRole(KeycloakModelUtils.generateId(), name);
+    }
+
+    @Override
+    public RoleAdapter addRole(String id, String name) {
+        if (roleNameExists(name)) throw new ModelDuplicateException("Role named " + name + " already exists.");
+        RoleEntity roleEntity = new RoleEntity();
+        roleEntity.setId(id);
+        roleEntity.setName(name);
+        roleEntity.setClientId(getId());
+
+        RoleAdapter role = new RoleAdapter(getRealm(), roleEntity, this);
+        allRoles.put(id, role);
+
+        return role;
+    }
+
+    private boolean roleNameExists(String name) {
+        for (RoleModel role : allRoles.values()) {
+            if (role.getName().equals(name)) return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean removeRole(RoleModel role) {
+        boolean removed = (allRoles.remove(role.getId()) != null);
+
+        // remove application roles from users
+        for (UserModel user : inMemoryModel.getUsers(realm.getId())) {
+            user.deleteRoleMapping(role);
+        }
+
+        // delete scope mappings from applications
+        for (ClientModel app : realm.getClients()) {
+            app.deleteScopeMapping(role);
+        }
+
+        // remove role from the realm
+        realm.removeRole(role);
+
+        this.deleteScopeMapping(role);
+
+        return removed;
+    }
+
+    @Override
+    public Set<RoleModel> getRoles() {
+        return new HashSet(allRoles.values());
+    }
+
+    @Override
+    public boolean hasScope(RoleModel role) {
+        if (isFullScopeAllowed()) return true;
+        Set<RoleModel> roles = getScopeMappings();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        roles = getRoles();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
+        Set<RoleModel> allScopes = client.getScopeMappings();
+
+        Set<RoleModel> appRoles = new HashSet<RoleModel>();
+        for (RoleModel role : allScopes) {
+            RoleAdapter roleAdapter = (RoleAdapter)role;
+            if (getId().equals(roleAdapter.getRoleEntity().getClientId())) {
+                appRoles.add(role);
+            }
+        }
+        return appRoles;
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        return entity.getDefaultRoles();
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        RoleModel role = getRole(name);
+        if (role == null) {
+            addRole(name);
+        }
+
+        List<String> defaultRoles = getDefaultRoles();
+        if (defaultRoles.contains(name)) return;
+
+        String[] defaultRoleNames = defaultRoles.toArray(new String[defaultRoles.size() + 1]);
+        defaultRoleNames[defaultRoleNames.length - 1] = name;
+        updateDefaultRoles(defaultRoleNames);
+    }
+
+    @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);
+        }
+
+        entity.setDefaultRoles(roleNames);
+    }
+
+    @Override
+    public int getNodeReRegistrationTimeout() {
+        return entity.getNodeReRegistrationTimeout();
+    }
+
+    @Override
+    public void setNodeReRegistrationTimeout(int timeout) {
+        entity.setNodeReRegistrationTimeout(timeout);
+    }
+
+    @Override
+    public Map<String, Integer> getRegisteredNodes() {
+        return entity.getRegisteredNodes() == null ? Collections.<String, Integer>emptyMap() : Collections.unmodifiableMap(entity.getRegisteredNodes());
+    }
+
+    @Override
+    public void registerNode(String nodeHost, int registrationTime) {
+        if (entity.getRegisteredNodes() == null) {
+            entity.setRegisteredNodes(new HashMap<String, Integer>());
+        }
+
+        entity.getRegisteredNodes().put(nodeHost, registrationTime);
+    }
+
+    @Override
+    public void unregisterNode(String nodeHost) {
+        if (entity.getRegisteredNodes() == null) return;
+
+        entity.getRegisteredNodes().remove(nodeHost);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof ClientModel)) return false;
+
+        ClientModel that = (ClientModel) o;
+        return that.getId().equals(getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return getId().hashCode();
+    }
+}
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 a1490ed..5ae793b 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
@@ -1,1264 +1,1167 @@
-/*
- * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
- * as indicated by the @author tags. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-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.IdentityProviderMapperModel;
-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.IdentityProviderMapperEntity;
-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;
-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.file.InMemoryModel;
-import org.keycloak.models.ModelDuplicateException;
-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.RoleEntity;
-
-/**
- * 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 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(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) {
-        if (type == null) throw new NullPointerException("Credential type can not be null");
-
-        RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
-
-        List<RequiredCredentialEntity> requiredCredList = realm.getRequiredCredentials();
-        for (RequiredCredentialEntity cred : requiredCredList) {
-            if (type.equals(cred.getType())) return;
-        }
-
-        addRequiredCredential(credentialModel, requiredCredList);
-    }
-
-    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 getIdentityProviderByAlias(String alias) {
-        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
-            if (identityProviderModel.getAlias().equals(alias)) {
-                return identityProviderModel;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public void addIdentityProvider(IdentityProviderModel identityProvider) {
-        if (identityProvider.getAlias() == null) throw new NullPointerException("identityProvider.getAlias() == null");
-        if (identityProvider.getInternalId() == null) identityProvider.setInternalId(KeycloakModelUtils.generateId());
-        allIdProviders.put(identityProvider.getInternalId(), identityProvider);
-    }
-
-    @Override
-    public void removeIdentityProviderByAlias(String alias) {
-        for (IdentityProviderModel provider : getIdentityProviders()) {
-            if (provider.getAlias().equals(alias)) {
-                allIdProviders.remove(provider.getInternalId());
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
-        removeIdentityProviderByAlias(identityProvider.getAlias());
-        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 Set<String> getEnabledEventTypes() {
-        return new HashSet<String>(realm.getEnabledEventTypes());
-    }
-
-    @Override
-    public void setEnabledEventTypes(Set<String> enabledEventTypes) {
-        if (enabledEventTypes != null) {
-            realm.setEnabledEventTypes(new ArrayList<String>(enabledEventTypes));
-        } else {
-            realm.setEnabledEventTypes(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 isInternationalizationEnabled() {
-        return realm.isInternationalizationEnabled();
-    }
-
-    @Override
-    public void setInternationalizationEnabled(boolean enabled) {
-        realm.setInternationalizationEnabled(enabled);
-    }
-
-    @Override
-    public Set<String> getSupportedLocales() {
-        return new HashSet<>(realm.getSupportedLocales());
-    }
-
-    @Override
-    public void setSupportedLocales(Set<String> locales) {
-        realm.setSupportedLocales(new ArrayList<>(locales));
-    }
-
-    @Override
-    public String getDefaultLocale() {
-        return realm.getDefaultLocale();
-    }
-
-    @Override
-    public void setDefaultLocale(String locale) {
-        realm.setDefaultLocale(locale);
-    }
-
-    @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 Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
-        Set<IdentityProviderMapperModel> mappings = new HashSet<>();
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
-            mapping.setId(entity.getId());
-            mapping.setName(entity.getName());
-            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
-            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
-            Map<String, String> config = new HashMap<String, String>();
-            if (entity.getConfig() != null) {
-                config.putAll(entity.getConfig());
-            }
-            mapping.setConfig(config);
-            mappings.add(mapping);
-        }
-        return mappings;
-    }
-    @Override
-    public Set<IdentityProviderMapperModel> getIdentityProviderMappersByAlias(String brokerAlias) {
-        Set<IdentityProviderMapperModel> mappings = new HashSet<>();
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
-                continue;
-            }
-            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
-            mapping.setId(entity.getId());
-            mapping.setName(entity.getName());
-            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
-            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
-            Map<String, String> config = new HashMap<String, String>();
-            if (entity.getConfig() != null) {
-                config.putAll(entity.getConfig());
-            }
-            mapping.setConfig(config);
-            mappings.add(mapping);
-        }
-        return mappings;
-    }
-
-    @Override
-    public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
-        if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
-            throw new RuntimeException("protocol mapper name must be unique per protocol");
-        }
-        String id = KeycloakModelUtils.generateId();
-        IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
-        entity.setId(id);
-        entity.setName(model.getName());
-        entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
-        entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
-        entity.setConfig(model.getConfig());
-
-        this.realm.getIdentityProviderMappers().add(entity);
-        return entityToModel(entity);
-    }
-
-    protected IdentityProviderMapperEntity getIdentityProviderMapperEntity(String id) {
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            if (entity.getId().equals(id)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-
-    protected IdentityProviderMapperEntity getIdentityProviderMapperEntityByName(String alias, String name) {
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            if (entity.getIdentityProviderAlias().equals(alias) && entity.getName().equals(name)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-
-    @Override
-    public void removeIdentityProviderMapper(IdentityProviderMapperModel mapping) {
-        IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
-        if (toDelete != null) {
-            this.realm.getIdentityProviderMappers().remove(toDelete);
-        }
-
-    }
-
-    @Override
-    public void updateIdentityProviderMapper(IdentityProviderMapperModel mapping) {
-        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(mapping.getId());
-        entity.setIdentityProviderAlias(mapping.getIdentityProviderAlias());
-        entity.setIdentityProviderMapper(mapping.getIdentityProviderMapper());
-        if (entity.getConfig() == null) {
-            entity.setConfig(mapping.getConfig());
-        } else {
-            entity.getConfig().clear();
-            entity.getConfig().putAll(mapping.getConfig());
-        }
-
-    }
-
-    @Override
-    public IdentityProviderMapperModel getIdentityProviderMapperById(String id) {
-        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(id);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    @Override
-    public IdentityProviderMapperModel getIdentityProviderMapperByName(String alias, String name) {
-        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntityByName(alias, name);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    protected IdentityProviderMapperModel entityToModel(IdentityProviderMapperEntity entity) {
-        IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
-        mapping.setId(entity.getId());
-        mapping.setName(entity.getName());
-        mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
-        mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
-        Map<String, String> config = new HashMap<String, String>();
-        if (entity.getConfig() != null) config.putAll(entity.getConfig());
-        mapping.setConfig(config);
-        return mapping;
-    }
-
-}
+/*
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.models.file.adapter;
+
+import org.keycloak.connections.file.InMemoryModel;
+import org.keycloak.enums.SslRequired;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
+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.IdentityProviderMapperEntity;
+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.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;
+
+/**
+ * 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, ClientModel> allApps = new HashMap<String, ClientModel>();
+    private ClientModel masterAdminApp = null;
+    private final Map<String, RoleAdapter> allRoles = new HashMap<String, RoleAdapter>();
+    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 (ClientModel app : getClients()) {
+            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 (ClientModel app : getClients()) {
+            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 getClientById(String id) {
+        return allApps.get(id);
+    }
+
+    @Override
+    public ClientModel getClientByClientId(String clientId) {
+        for (ClientModel app : getClients()) {
+            if (app.getClientId().equals(clientId)) return app;
+        }
+
+        return null;
+    }
+
+    @Override
+    public Map<String, ClientModel> getClientNameMap() {
+        Map<String, ClientModel> resourceMap = new HashMap<String, ClientModel>();
+        for (ClientModel resource : getClients()) {
+            resourceMap.put(resource.getClientId(), resource);
+        }
+        return resourceMap;
+    }
+
+    @Override
+    public List<ClientModel> getClients() {
+        return new ArrayList<ClientModel>(allApps.values());
+    }
+
+    @Override
+    public ClientModel addClient(String name) {
+        return this.addClient(KeycloakModelUtils.generateId(), name);
+    }
+
+    @Override
+    public ClientModel addClient(String id, String clientId) {
+        if (clientId == null) throw new NullPointerException("name == null");
+        if (id == null) throw new NullPointerException("id == null");
+
+        if (getClientNameMap().containsKey(clientId)) {
+            throw new ModelDuplicateException("Application named '" + clientId + "' already exists.");
+        }
+
+        ApplicationEntity appEntity = new ApplicationEntity();
+        appEntity.setId(id);
+        appEntity.setName(clientId);
+        appEntity.setRealmId(getId());
+        appEntity.setEnabled(true);
+
+        final ClientModel app = new ClientAdapter(session, this, appEntity, inMemoryModel);
+        session.getKeycloakSessionFactory().publish(new ClientCreationEvent() {
+            @Override
+            public ClientModel getCreatedClient() {
+                return app;
+            }
+        });
+
+        allApps.put(id, app);
+
+        return app;
+    }
+
+    @Override
+    public boolean removeClient(String id) {
+        ClientModel appToBeRemoved = this.getClientById(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);
+    }
+
+    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 void addRequiredCredential(String type) {
+        if (type == null) throw new NullPointerException("Credential type can not be null");
+
+        RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
+
+        List<RequiredCredentialEntity> requiredCredList = realm.getRequiredCredentials();
+        for (RequiredCredentialEntity cred : requiredCredList) {
+            if (type.equals(cred.getType())) return;
+        }
+
+        addRequiredCredential(credentialModel, requiredCredList);
+    }
+
+    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 getIdentityProviderByAlias(String alias) {
+        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+            if (identityProviderModel.getAlias().equals(alias)) {
+                return identityProviderModel;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void addIdentityProvider(IdentityProviderModel identityProvider) {
+        if (identityProvider.getAlias() == null) throw new NullPointerException("identityProvider.getAlias() == null");
+        if (identityProvider.getInternalId() == null) identityProvider.setInternalId(KeycloakModelUtils.generateId());
+        allIdProviders.put(identityProvider.getInternalId(), identityProvider);
+    }
+
+    @Override
+    public void removeIdentityProviderByAlias(String alias) {
+        for (IdentityProviderModel provider : getIdentityProviders()) {
+            if (provider.getAlias().equals(alias)) {
+                allIdProviders.remove(provider.getInternalId());
+                break;
+            }
+        }
+    }
+
+    @Override
+    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+        removeIdentityProviderByAlias(identityProvider.getAlias());
+        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 Set<String> getEnabledEventTypes() {
+        return new HashSet<String>(realm.getEnabledEventTypes());
+    }
+
+    @Override
+    public void setEnabledEventTypes(Set<String> enabledEventTypes) {
+        if (enabledEventTypes != null) {
+            realm.setEnabledEventTypes(new ArrayList<String>(enabledEventTypes));
+        } else {
+            realm.setEnabledEventTypes(Collections.EMPTY_LIST);
+        }        
+    }
+
+    @Override
+    public ClientModel getMasterAdminApp() {
+        return this.masterAdminApp;
+    }
+
+    @Override
+    public void setMasterAdminApp(ClientModel 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 isInternationalizationEnabled() {
+        return realm.isInternationalizationEnabled();
+    }
+
+    @Override
+    public void setInternationalizationEnabled(boolean enabled) {
+        realm.setInternationalizationEnabled(enabled);
+    }
+
+    @Override
+    public Set<String> getSupportedLocales() {
+        return new HashSet<>(realm.getSupportedLocales());
+    }
+
+    @Override
+    public void setSupportedLocales(Set<String> locales) {
+        realm.setSupportedLocales(new ArrayList<>(locales));
+    }
+
+    @Override
+    public String getDefaultLocale() {
+        return realm.getDefaultLocale();
+    }
+
+    @Override
+    public void setDefaultLocale(String locale) {
+        realm.setDefaultLocale(locale);
+    }
+
+    @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 Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
+        Set<IdentityProviderMapperModel> mappings = new HashSet<>();
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
+            mapping.setId(entity.getId());
+            mapping.setName(entity.getName());
+            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
+            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
+            Map<String, String> config = new HashMap<String, String>();
+            if (entity.getConfig() != null) {
+                config.putAll(entity.getConfig());
+            }
+            mapping.setConfig(config);
+            mappings.add(mapping);
+        }
+        return mappings;
+    }
+    @Override
+    public Set<IdentityProviderMapperModel> getIdentityProviderMappersByAlias(String brokerAlias) {
+        Set<IdentityProviderMapperModel> mappings = new HashSet<>();
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
+                continue;
+            }
+            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
+            mapping.setId(entity.getId());
+            mapping.setName(entity.getName());
+            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
+            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
+            Map<String, String> config = new HashMap<String, String>();
+            if (entity.getConfig() != null) {
+                config.putAll(entity.getConfig());
+            }
+            mapping.setConfig(config);
+            mappings.add(mapping);
+        }
+        return mappings;
+    }
+
+    @Override
+    public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
+        if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
+            throw new RuntimeException("protocol mapper name must be unique per protocol");
+        }
+        String id = KeycloakModelUtils.generateId();
+        IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
+        entity.setId(id);
+        entity.setName(model.getName());
+        entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
+        entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
+        entity.setConfig(model.getConfig());
+
+        this.realm.getIdentityProviderMappers().add(entity);
+        return entityToModel(entity);
+    }
+
+    protected IdentityProviderMapperEntity getIdentityProviderMapperEntity(String id) {
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            if (entity.getId().equals(id)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+    protected IdentityProviderMapperEntity getIdentityProviderMapperEntityByName(String alias, String name) {
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            if (entity.getIdentityProviderAlias().equals(alias) && entity.getName().equals(name)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public void removeIdentityProviderMapper(IdentityProviderMapperModel mapping) {
+        IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
+        if (toDelete != null) {
+            this.realm.getIdentityProviderMappers().remove(toDelete);
+        }
+
+    }
+
+    @Override
+    public void updateIdentityProviderMapper(IdentityProviderMapperModel mapping) {
+        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(mapping.getId());
+        entity.setIdentityProviderAlias(mapping.getIdentityProviderAlias());
+        entity.setIdentityProviderMapper(mapping.getIdentityProviderMapper());
+        if (entity.getConfig() == null) {
+            entity.setConfig(mapping.getConfig());
+        } else {
+            entity.getConfig().clear();
+            entity.getConfig().putAll(mapping.getConfig());
+        }
+
+    }
+
+    @Override
+    public IdentityProviderMapperModel getIdentityProviderMapperById(String id) {
+        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(id);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    @Override
+    public IdentityProviderMapperModel getIdentityProviderMapperByName(String alias, String name) {
+        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntityByName(alias, name);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    protected IdentityProviderMapperModel entityToModel(IdentityProviderMapperEntity entity) {
+        IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
+        mapping.setId(entity.getId());
+        mapping.setName(entity.getName());
+        mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
+        mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
+        Map<String, String> config = new HashMap<String, String>();
+        if (entity.getConfig() != null) config.putAll(entity.getConfig());
+        mapping.setConfig(config);
+        return mapping;
+    }
+
+}
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java
index 28a2f90..f53c0ce 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RoleAdapter.java
@@ -111,7 +111,7 @@ public class RoleAdapter implements RoleModel {
         Set<RoleModel> toBeRemoved = new HashSet<RoleModel>();
         for (RoleModel compositeRole : getComposites()) {
             RoleAdapter roleAdapter = (RoleAdapter)compositeRole;
-            if (appId.equals(roleAdapter.getRoleEntity().getApplicationId())) {
+            if (appId.equals(roleAdapter.getRoleEntity().getClientId())) {
                 toBeRemoved.add(compositeRole);
             } else {
                 roleAdapter.removeApplicationComposites(appId);
@@ -143,8 +143,8 @@ public class RoleAdapter implements RoleModel {
             // Compute it
             if (role.getRealmId() != null) {
                 roleContainer = realm;//new RealmAdapter(session, realm);
-            } else if (role.getApplicationId() != null) {
-                roleContainer = realm.getApplicationById(role.getApplicationId());//new ApplicationAdapter(session, realm, appEntity);
+            } else if (role.getClientId() != null) {
+                roleContainer = realm.getClientById(role.getClientId());//new ApplicationAdapter(session, realm, appEntity);
             } else {
                 throw new IllegalStateException("Both realmId and applicationId are null for role: " + this);
             }
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
index f1a7a28..00b6af8 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
@@ -16,7 +16,7 @@
  */
 package org.keycloak.models.file.adapter;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
@@ -325,12 +325,12 @@ public class UserAdapter implements UserModel, Comparable {
     }
 
     @Override
-    public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
+    public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
         Set<RoleModel> result = new HashSet<RoleModel>();
 
         for (RoleModel role : allRoles) {
             RoleEntity roleEntity = ((RoleAdapter)role).getRoleEntity();
-            if (app.getId().equals(roleEntity.getApplicationId())) {
+            if (app.getId().equals(roleEntity.getClientId())) {
                 result.add(new RoleAdapter(realm, roleEntity, app));
             }
         }
diff --git a/model/file/src/main/java/org/keycloak/models/file/FileRealmProvider.java b/model/file/src/main/java/org/keycloak/models/file/FileRealmProvider.java
index 52b3f39..3f23b5c 100644
--- a/model/file/src/main/java/org/keycloak/models/file/FileRealmProvider.java
+++ b/model/file/src/main/java/org/keycloak/models/file/FileRealmProvider.java
@@ -16,21 +16,20 @@
  */
 package org.keycloak.models.file;
 
-import org.keycloak.models.file.adapter.RealmAdapter;
-import java.util.ArrayList;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.connections.file.FileConnectionProvider;
+import org.keycloak.connections.file.InMemoryModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.entities.RealmEntity;
+import org.keycloak.models.file.adapter.RealmAdapter;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
+import java.util.ArrayList;
 import java.util.List;
-import org.keycloak.connections.file.FileConnectionProvider;
-import org.keycloak.connections.file.InMemoryModel;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.entities.RealmEntity;
 
 /**
  * Realm Provider for JSON persistence.
@@ -100,13 +99,8 @@ public class FileRealmProvider implements RealmProvider {
     }
 
     @Override
-    public ApplicationModel getApplicationById(String id, RealmModel realm) {
-        return realm.getApplicationById(id);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
-        return realm.getOAuthClientById(id);
+    public ClientModel getClientById(String id, RealmModel realm) {
+        return realm.getClientById(id);
     }
 
 }
diff --git a/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java b/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
index 456831f..850d1a7 100644
--- a/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
+++ b/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
@@ -36,7 +36,7 @@ import java.util.Set;
 import java.util.regex.Pattern;
 import org.keycloak.connections.file.FileConnectionProvider;
 import org.keycloak.connections.file.InMemoryModel;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.CredentialValidationOutput;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.entities.FederatedIdentityEntity;
@@ -276,7 +276,7 @@ public class FileUserProvider implements UserProvider {
                 userModel.grantRole(realm.getRole(r));
             }
 
-            for (ApplicationModel application : realm.getApplications()) {
+            for (ClientModel application : realm.getClients()) {
                 for (String r : application.getDefaultRoles()) {
                     userModel.grantRole(application.getRole(r));
                 }
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
index a01a135..b5204e8 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
@@ -4,7 +4,6 @@ import org.infinispan.Cache;
 import org.jboss.logging.Logger;
 import org.keycloak.models.cache.RealmCache;
 import org.keycloak.models.cache.entities.CachedApplication;
-import org.keycloak.models.cache.entities.CachedOAuthClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRole;
 
@@ -103,31 +102,6 @@ public class InfinispanRealmCache implements RealmCache {
     }
 
     @Override
-    public CachedOAuthClient getOAuthClient(String id) {
-        if (!enabled) return null;
-        return get(id, CachedOAuthClient.class);
-    }
-
-    @Override
-    public void invalidateOAuthClient(CachedOAuthClient client) {
-        logger.tracev("Removing oauth client {0}", client.getId());
-        cache.remove(client.getId());
-    }
-
-    @Override
-    public void addCachedOAuthClient(CachedOAuthClient client) {
-        if (!enabled) return;
-        logger.tracev("Adding oauth client {0}", client.getId());
-        cache.put(client.getId(), client);
-    }
-
-    @Override
-    public void invalidateCachedOAuthClientById(String id) {
-        logger.tracev("Removing oauth client {0}", id);
-        cache.remove(id);
-    }
-
-    @Override
     public CachedRole getRole(String id) {
         if (!enabled) return null;
         return get(id, CachedRole.class);
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProvider.java
index 8a4c869..9810d50 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProvider.java
@@ -17,8 +17,4 @@ public interface CacheRealmProvider extends RealmProvider {
     void registerApplicationInvalidation(String id);
 
     void registerRoleInvalidation(String id);
-
-    void registerOAuthClientInvalidation(String id);
-
-    void registerUserInvalidation(String id);
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
index 12e89e1..0dc490d 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.cache.entities.CachedClient;
+import org.keycloak.models.cache.entities.CachedApplication;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -18,80 +18,88 @@ import java.util.Set;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public abstract class ClientAdapter implements ClientModel {
-    protected CachedClient cachedClient;
+public class ClientAdapter implements ClientModel {
     protected CacheRealmProvider cacheSession;
-    protected ClientModel updatedClient;
     protected RealmModel cachedRealm;
     protected RealmCache cache;
 
-    public ClientAdapter(RealmModel cachedRealm, CachedClient cached, RealmCache cache, CacheRealmProvider cacheSession) {
+    protected ClientModel updated;
+    protected CachedApplication cached;
+
+    public ClientAdapter(RealmModel cachedRealm, CachedApplication cached, CacheRealmProvider cacheSession, RealmCache cache) {
         this.cachedRealm = cachedRealm;
         this.cache = cache;
         this.cacheSession = cacheSession;
-        this.cachedClient = cached;
+        this.cached = cached;
     }
 
-    protected abstract void getDelegateForUpdate();
+    private void getDelegateForUpdate() {
+        if (updated == null) {
+            cacheSession.registerApplicationInvalidation(getId());
+            updated = updated = cacheSession.getDelegate().getClientById(getId(), cachedRealm);
+            if (updated == null) throw new IllegalStateException("Not found in database");
+        }
+    }
 
     @Override
-    public String getId() {
-        if (updatedClient != null) return updatedClient.getId();
-        return cachedClient.getId();
+    public void updateApplication() {
+        if (updated != null) updated.updateApplication();
     }
 
-
     @Override
-    public abstract String getClientId();
+    public String getId() {
+        if (updated != null) return updated.getId();
+        return cached.getId();
+    }
 
     public Set<String> getWebOrigins() {
-        if (updatedClient != null) return updatedClient.getWebOrigins();
-        return cachedClient.getWebOrigins();
+        if (updated != null) return updated.getWebOrigins();
+        return cached.getWebOrigins();
     }
 
     public void setWebOrigins(Set<String> webOrigins) {
         getDelegateForUpdate();
-        updatedClient.setWebOrigins(webOrigins);
+        updated.setWebOrigins(webOrigins);
     }
 
     public void addWebOrigin(String webOrigin) {
         getDelegateForUpdate();
-        updatedClient.addWebOrigin(webOrigin);
+        updated.addWebOrigin(webOrigin);
     }
 
     public void removeWebOrigin(String webOrigin) {
         getDelegateForUpdate();
-        updatedClient.removeWebOrigin(webOrigin);
+        updated.removeWebOrigin(webOrigin);
     }
 
     public Set<String> getRedirectUris() {
-        if (updatedClient != null) return updatedClient.getRedirectUris();
-        return cachedClient.getRedirectUris();
+        if (updated != null) return updated.getRedirectUris();
+        return cached.getRedirectUris();
     }
 
     public void setRedirectUris(Set<String> redirectUris) {
         getDelegateForUpdate();
-        updatedClient.setRedirectUris(redirectUris);
+        updated.setRedirectUris(redirectUris);
     }
 
     public void addRedirectUri(String redirectUri) {
         getDelegateForUpdate();
-        updatedClient.addRedirectUri(redirectUri);
+        updated.addRedirectUri(redirectUri);
     }
 
     public void removeRedirectUri(String redirectUri) {
         getDelegateForUpdate();
-        updatedClient.removeRedirectUri(redirectUri);
+        updated.removeRedirectUri(redirectUri);
     }
 
     public boolean isEnabled() {
-        if (updatedClient != null) return updatedClient.isEnabled();
-        return cachedClient.isEnabled();
+        if (updated != null) return updated.isEnabled();
+        return cached.isEnabled();
     }
 
     public void setEnabled(boolean enabled) {
         getDelegateForUpdate();
-        updatedClient.setEnabled(enabled);
+        updated.setEnabled(enabled);
     }
 
     public boolean validateSecret(String secret) {
@@ -99,62 +107,62 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     public String getSecret() {
-        if (updatedClient != null) return updatedClient.getSecret();
-        return cachedClient.getSecret();
+        if (updated != null) return updated.getSecret();
+        return cached.getSecret();
     }
 
     public void setSecret(String secret) {
         getDelegateForUpdate();
-        updatedClient.setSecret(secret);
+        updated.setSecret(secret);
     }
 
     public boolean isPublicClient() {
-        if (updatedClient != null) return updatedClient.isPublicClient();
-        return cachedClient.isPublicClient();
+        if (updated != null) return updated.isPublicClient();
+        return cached.isPublicClient();
     }
 
     public void setPublicClient(boolean flag) {
         getDelegateForUpdate();
-        updatedClient.setPublicClient(flag);
+        updated.setPublicClient(flag);
     }
 
     public boolean isFrontchannelLogout() {
-        if (updatedClient != null) return updatedClient.isPublicClient();
-        return cachedClient.isFrontchannelLogout();
+        if (updated != null) return updated.isPublicClient();
+        return cached.isFrontchannelLogout();
     }
 
     public void setFrontchannelLogout(boolean flag) {
         getDelegateForUpdate();
-        updatedClient.setFrontchannelLogout(flag);
+        updated.setFrontchannelLogout(flag);
     }
 
     @Override
     public boolean isFullScopeAllowed() {
-        if (updatedClient != null) return updatedClient.isFullScopeAllowed();
-        return cachedClient.isFullScopeAllowed();
+        if (updated != null) return updated.isFullScopeAllowed();
+        return cached.isFullScopeAllowed();
     }
 
     @Override
     public void setFullScopeAllowed(boolean value) {
         getDelegateForUpdate();
-        updatedClient.setFullScopeAllowed(value);
+        updated.setFullScopeAllowed(value);
 
     }
 
     public boolean isDirectGrantsOnly() {
-        if (updatedClient != null) return updatedClient.isDirectGrantsOnly();
-        return cachedClient.isDirectGrantsOnly();
+        if (updated != null) return updated.isDirectGrantsOnly();
+        return cached.isDirectGrantsOnly();
     }
 
     public void setDirectGrantsOnly(boolean flag) {
         getDelegateForUpdate();
-        updatedClient.setDirectGrantsOnly(flag);
+        updated.setDirectGrantsOnly(flag);
     }
 
     public Set<RoleModel> getScopeMappings() {
-        if (updatedClient != null) return updatedClient.getScopeMappings();
+        if (updated != null) return updated.getScopeMappings();
         Set<RoleModel> roles = new HashSet<RoleModel>();
-        for (String id : cachedClient.getScope()) {
+        for (String id : cached.getScope()) {
             roles.add(cacheSession.getRoleById(id, getRealm()));
 
         }
@@ -163,12 +171,12 @@ public abstract class ClientAdapter implements ClientModel {
 
     public void addScopeMapping(RoleModel role) {
         getDelegateForUpdate();
-        updatedClient.addScopeMapping(role);
+        updated.addScopeMapping(role);
     }
 
     public void deleteScopeMapping(RoleModel role) {
         getDelegateForUpdate();
-        updatedClient.deleteScopeMapping(role);
+        updated.deleteScopeMapping(role);
     }
 
     public Set<RoleModel> getRealmScopeMappings() {
@@ -187,119 +195,107 @@ public abstract class ClientAdapter implements ClientModel {
         return appRoles;
     }
 
-    public boolean hasScope(RoleModel role) {
-        if (updatedClient != null) return updatedClient.hasScope(role);
-        if (cachedClient.isFullScopeAllowed() || cachedClient.getScope().contains(role.getId())) return true;
-
-        Set<RoleModel> roles = getScopeMappings();
-
-        for (RoleModel mapping : roles) {
-            if (mapping.hasRole(role)) return true;
-        }
-        return false;
-    }
-
     public RealmModel getRealm() {
         return cachedRealm;
     }
 
     public int getNotBefore() {
-        if (updatedClient != null) return updatedClient.getNotBefore();
-        return cachedClient.getNotBefore();
+        if (updated != null) return updated.getNotBefore();
+        return cached.getNotBefore();
     }
 
     public void setNotBefore(int notBefore) {
         getDelegateForUpdate();
-        updatedClient.setNotBefore(notBefore);
+        updated.setNotBefore(notBefore);
     }
 
     @Override
     public String getProtocol() {
-        if (updatedClient != null) return updatedClient.getProtocol();
-        return cachedClient.getProtocol();
+        if (updated != null) return updated.getProtocol();
+        return cached.getProtocol();
     }
 
     @Override
     public void setProtocol(String protocol) {
         getDelegateForUpdate();
-        updatedClient.setProtocol(protocol);
+        updated.setProtocol(protocol);
     }
 
     @Override
     public void setAttribute(String name, String value) {
         getDelegateForUpdate();
-        updatedClient.setAttribute(name, value);
+        updated.setAttribute(name, value);
 
     }
 
     @Override
     public void removeAttribute(String name) {
         getDelegateForUpdate();
-        updatedClient.removeAttribute(name);
+        updated.removeAttribute(name);
 
     }
 
     @Override
     public String getAttribute(String name) {
-        if (updatedClient != null) return updatedClient.getAttribute(name);
-        return cachedClient.getAttributes().get(name);
+        if (updated != null) return updated.getAttribute(name);
+        return cached.getAttributes().get(name);
     }
 
     @Override
     public Map<String, String> getAttributes() {
-        if (updatedClient != null) return updatedClient.getAttributes();
+        if (updated != null) return updated.getAttributes();
         Map<String, String> copy = new HashMap<String, String>();
-        copy.putAll(cachedClient.getAttributes());
+        copy.putAll(cached.getAttributes());
         return copy;
     }
 
     @Override
     public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
         getDelegateForUpdate();
-        updatedClient.updateIdentityProviders(identityProviders);
+        updated.updateIdentityProviders(identityProviders);
     }
 
     @Override
     public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
-        if (updatedClient != null) return updatedClient.getIdentityProviders();
-        return cachedClient.getIdentityProviders();
+        if (updated != null) return updated.getIdentityProviders();
+        return cached.getIdentityProviders();
     }
 
     @Override
     public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
-        if (updatedClient != null) return updatedClient.isAllowedRetrieveTokenFromIdentityProvider(providerId);
-        return cachedClient.isAllowedRetrieveTokenFromIdentityProvider(providerId);
+        if (updated != null) return updated.isAllowedRetrieveTokenFromIdentityProvider(providerId);
+        return cached.isAllowedRetrieveTokenFromIdentityProvider(providerId);
     }
 
     @Override
     public Set<ProtocolMapperModel> getProtocolMappers() {
-        if (updatedClient != null) return updatedClient.getProtocolMappers();
-        return cachedClient.getProtocolMappers();
+        if (updated != null) return updated.getProtocolMappers();
+        return cached.getProtocolMappers();
     }
 
     @Override
     public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
         getDelegateForUpdate();
-        return updatedClient.addProtocolMapper(model);
+        return updated.addProtocolMapper(model);
     }
 
     @Override
     public void removeProtocolMapper(ProtocolMapperModel mapping) {
         getDelegateForUpdate();
-        updatedClient.removeProtocolMapper(mapping);
+        updated.removeProtocolMapper(mapping);
 
     }
 
     @Override
     public void updateProtocolMapper(ProtocolMapperModel mapping) {
         getDelegateForUpdate();
-        updatedClient.updateProtocolMapper(mapping);
+        updated.updateProtocolMapper(mapping);
 
     }
 
     @Override
     public ProtocolMapperModel getProtocolMapperById(String id) {
-        for (ProtocolMapperModel mapping : cachedClient.getProtocolMappers()) {
+        for (ProtocolMapperModel mapping : cached.getProtocolMappers()) {
             if (mapping.getId().equals(id)) return mapping;
         }
         return null;
@@ -307,9 +303,228 @@ public abstract class ClientAdapter implements ClientModel {
 
     @Override
     public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
-        for (ProtocolMapperModel mapping : cachedClient.getProtocolMappers()) {
+        for (ProtocolMapperModel mapping : cached.getProtocolMappers()) {
             if (mapping.getProtocol().equals(protocol) && mapping.getName().equals(name)) return mapping;
         }
         return null;
     }
+
+    @Override
+    public String getClientId() {
+        if (updated != null) return updated.getClientId();
+        return cached.getName();
+    }
+
+    @Override
+    public void setClientId(String clientId) {
+        getDelegateForUpdate();
+        updated.setClientId(clientId);
+        cacheSession.registerRealmInvalidation(cachedRealm.getId());
+    }
+
+    @Override
+    public boolean isSurrogateAuthRequired() {
+        if (updated != null) return updated.isSurrogateAuthRequired();
+        return cached.isSurrogateAuthRequired();
+    }
+
+    @Override
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        getDelegateForUpdate();
+        updated.setSurrogateAuthRequired(surrogateAuthRequired);
+    }
+
+    @Override
+    public String getManagementUrl() {
+        if (updated != null) return updated.getManagementUrl();
+        return cached.getManagementUrl();
+    }
+
+    @Override
+    public void setManagementUrl(String url) {
+        getDelegateForUpdate();
+        updated.setManagementUrl(url);
+    }
+
+    @Override
+    public String getBaseUrl() {
+        if (updated != null) return updated.getBaseUrl();
+        return cached.getBaseUrl();
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        getDelegateForUpdate();
+        updated.setBaseUrl(url);
+    }
+
+    @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 Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
+        Set<RoleModel> roleMappings = client.getScopeMappings();
+
+        Set<RoleModel> appRoles = new HashSet<RoleModel>();
+        for (RoleModel role : roleMappings) {
+            RoleContainerModel container = role.getContainer();
+            if (container instanceof RealmModel) {
+            } else {
+                ClientModel app = (ClientModel)container;
+                if (app.getId().equals(getId())) {
+                    appRoles.add(role);
+                }
+            }
+        }
+
+        return appRoles;
+    }
+
+    @Override
+    public boolean isBearerOnly() {
+        if (updated != null) return updated.isBearerOnly();
+        return cached.isBearerOnly();
+    }
+
+    @Override
+    public void setBearerOnly(boolean only) {
+        getDelegateForUpdate();
+        updated.setBearerOnly(only);
+    }
+
+    @Override
+    public boolean isConsentRequired() {
+        if (updated != null) return updated.isConsentRequired();
+        return cached.isConsentRequired();
+    }
+
+    @Override
+    public void setConsentRequired(boolean consentRequired) {
+        getDelegateForUpdate();
+        updated.setConsentRequired(consentRequired);
+    }
+
+    @Override
+    public RoleModel getRole(String name) {
+        if (updated != null) return updated.getRole(name);
+        String id = cached.getRoles().get(name);
+        if (id == null) return null;
+        return cacheSession.getRoleById(id, cachedRealm);
+    }
+
+    @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.getRoles().values()) {
+            RoleModel roleById = cacheSession.getRoleById(id, cachedRealm);
+            if (roleById == null) continue;
+            roles.add(roleById);
+        }
+        return roles;
+    }
+
+    @Override
+    public int getNodeReRegistrationTimeout() {
+        if (updated != null) return updated.getNodeReRegistrationTimeout();
+        return cached.getNodeReRegistrationTimeout();
+    }
+
+    @Override
+    public void setNodeReRegistrationTimeout(int timeout) {
+        getDelegateForUpdate();
+        updated.setNodeReRegistrationTimeout(timeout);
+    }
+
+    @Override
+    public Map<String, Integer> getRegisteredNodes() {
+        if (updated != null) return updated.getRegisteredNodes();
+        return cached.getRegisteredNodes();
+    }
+
+    @Override
+    public void registerNode(String nodeHost, int registrationTime) {
+        getDelegateForUpdate();
+        updated.registerNode(nodeHost, registrationTime);
+    }
+
+    @Override
+    public void unregisterNode(String nodeHost) {
+        getDelegateForUpdate();
+        updated.unregisterNode(nodeHost);
+    }
+
+    @Override
+    public boolean hasScope(RoleModel role) {
+        if (updated != null) return updated.hasScope(role);
+        if (cached.isFullScopeAllowed() || cached.getScope().contains(role.getId())) return true;
+
+        Set<RoleModel> roles = getScopeMappings();
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+
+        roles = getRoles();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof ClientModel)) return false;
+
+        ClientModel that = (ClientModel) 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/DefaultCacheRealmProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheRealmProvider.java
index a1d232e..933ac74 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheRealmProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheRealmProvider.java
@@ -1,15 +1,13 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakTransaction;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.cache.entities.CachedApplication;
 import org.keycloak.models.cache.entities.CachedApplicationRole;
-import org.keycloak.models.cache.entities.CachedOAuthClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRealmRole;
 import org.keycloak.models.cache.entities.CachedRole;
@@ -34,11 +32,8 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
     protected Set<String> realmInvalidations = new HashSet<String>();
     protected Set<String> appInvalidations = new HashSet<String>();
     protected Set<String> roleInvalidations = new HashSet<String>();
-    protected Set<String> clientInvalidations = new HashSet<String>();
-    protected Set<String> userInvalidations = new HashSet<String>();
     protected Map<String, RealmModel> managedRealms = new HashMap<String, RealmModel>();
-    protected Map<String, ApplicationModel> managedApplications = new HashMap<String, ApplicationModel>();
-    protected Map<String, OAuthClientModel> managedClients = new HashMap<String, OAuthClientModel>();
+    protected Map<String, ClientModel> managedApplications = new HashMap<String, ClientModel>();
     protected Map<String, RoleModel> managedRoles = new HashMap<String, RoleModel>();
 
     protected boolean clearAll;
@@ -83,16 +78,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
         roleInvalidations.add(id);
     }
 
-    @Override
-    public void registerOAuthClientInvalidation(String id) {
-        clientInvalidations.add(id);
-    }
-
-    @Override
-    public void registerUserInvalidation(String id) {
-        userInvalidations.add(id);
-    }
-
     protected void runInvalidations() {
         for (String id : realmInvalidations) {
             cache.invalidateCachedRealmById(id);
@@ -103,9 +88,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
         for (String id : appInvalidations) {
             cache.invalidateCachedApplicationById(id);
         }
-        for (String id : clientInvalidations) {
-            cache.invalidateCachedOAuthClientById(id);
-        }
     }
 
     private KeycloakTransaction getTransaction() {
@@ -252,8 +234,8 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
             RoleModel model = getDelegate().getRoleById(id, realm);
             if (model == null) return null;
             if (roleInvalidations.contains(id)) return model;
-            if (model.getContainer() instanceof ApplicationModel) {
-                cached = new CachedApplicationRole(((ApplicationModel) model.getContainer()).getId(), model, realm);
+            if (model.getContainer() instanceof ClientModel) {
+                cached = new CachedApplicationRole(((ClientModel) model.getContainer()).getId(), model, realm);
             } else {
                 cached = new CachedRealmRole(model, realm);
             }
@@ -270,51 +252,27 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
     }
 
     @Override
-    public ApplicationModel getApplicationById(String id, RealmModel realm) {
-        if (!cache.isEnabled()) return getDelegate().getApplicationById(id, realm);
+    public ClientModel getClientById(String id, RealmModel realm) {
+        if (!cache.isEnabled()) return getDelegate().getClientById(id, realm);
         CachedApplication cached = cache.getApplication(id);
         if (cached != null && !cached.getRealm().equals(realm.getId())) {
             cached = null;
         }
 
         if (cached == null) {
-            ApplicationModel model = getDelegate().getApplicationById(id, realm);
+            ClientModel model = getDelegate().getClientById(id, realm);
             if (model == null) return null;
             if (appInvalidations.contains(id)) return model;
             cached = new CachedApplication(cache, getDelegate(), realm, model);
             cache.addCachedApplication(cached);
         } else if (appInvalidations.contains(id)) {
-            return getDelegate().getApplicationById(id, realm);
+            return getDelegate().getClientById(id, realm);
         } else if (managedApplications.containsKey(id)) {
             return managedApplications.get(id);
         }
-        ApplicationAdapter adapter = new ApplicationAdapter(realm, cached, this, cache);
+        ClientAdapter adapter = new ClientAdapter(realm, cached, this, cache);
         managedApplications.put(id, adapter);
         return adapter;
     }
 
-    @Override
-    public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
-        if (!cache.isEnabled()) return getDelegate().getOAuthClientById(id, realm);
-        CachedOAuthClient cached = cache.getOAuthClient(id);
-        if (cached != null && !cached.getRealm().equals(realm.getId())) {
-            cached = null;
-        }
-
-        if (cached == null) {
-            OAuthClientModel model = getDelegate().getOAuthClientById(id, realm);
-            if (model == null) return null;
-            if (clientInvalidations.contains(id)) return model;
-            cached = new CachedOAuthClient(cache, getDelegate(), realm, model);
-            cache.addCachedOAuthClient(cached);
-        } else if (clientInvalidations.contains(id)) {
-            return getDelegate().getOAuthClientById(id, realm);
-        } else if (managedClients.containsKey(id)) {
-            return managedClients.get(id);
-        }
-        OAuthClientAdapter adapter = new OAuthClientAdapter(realm, cached, this, cache);
-        managedClients.put(id, adapter);
-        return adapter;
-    }
-
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedApplication.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedApplication.java
index e537ea7..896dfc9 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedApplication.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedApplication.java
@@ -1,38 +1,82 @@
 package org.keycloak.models.cache.entities;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
+import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RoleModel;
 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;
 import java.util.TreeMap;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class CachedApplication extends CachedClient {
+public class CachedApplication {
+    private String id;
+    private String name;
+    private String realm;
+    private Set<String> redirectUris = new HashSet<String>();
+    private boolean enabled;
+    private String secret;
+    private String protocol;
+    private Map<String, String> attributes = new HashMap<String, String>();
+    private boolean publicClient;
+    private boolean fullScopeAllowed;
+    private boolean directGrantsOnly;
+    private boolean frontchannelLogout;
+    private int notBefore;
+    private Set<String> scope = new HashSet<String>();
+    private Set<String> webOrigins = new HashSet<String>();
+    private List<ClientIdentityProviderMappingModel> identityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
+    private Set<ProtocolMapperModel> protocolMappers = new HashSet<ProtocolMapperModel>();
     private boolean surrogateAuthRequired;
     private String managementUrl;
     private String baseUrl;
     private List<String> defaultRoles = new LinkedList<String>();
     private boolean bearerOnly;
+    private boolean consentRequired;
     private Map<String, String> roles = new HashMap<String, String>();
     private int nodeReRegistrationTimeout;
     private Map<String, Integer> registeredNodes;
 
-    public CachedApplication(RealmCache cache, RealmProvider delegate, RealmModel realm, ApplicationModel model) {
-        super(cache, delegate, realm, model);
+    public CachedApplication(RealmCache cache, RealmProvider delegate, RealmModel realm, ClientModel model) {
+        id = model.getId();
+        secret = model.getSecret();
+        name = model.getClientId();
+        this.realm = realm.getId();
+        enabled = model.isEnabled();
+        protocol = model.getProtocol();
+        attributes.putAll(model.getAttributes());
+        notBefore = model.getNotBefore();
+        directGrantsOnly = model.isDirectGrantsOnly();
+        frontchannelLogout = model.isFrontchannelLogout();
+        publicClient = model.isPublicClient();
+        fullScopeAllowed = model.isFullScopeAllowed();
+        redirectUris.addAll(model.getRedirectUris());
+        webOrigins.addAll(model.getWebOrigins());
+        for (RoleModel role : model.getScopeMappings())  {
+            scope.add(role.getId());
+        }
+        this.identityProviders = model.getIdentityProviders();
+        for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
+            this.protocolMappers.add(mapper);
+        }
         surrogateAuthRequired = model.isSurrogateAuthRequired();
         managementUrl = model.getManagementUrl();
         baseUrl = model.getBaseUrl();
         defaultRoles.addAll(model.getDefaultRoles());
         bearerOnly = model.isBearerOnly();
+        consentRequired = model.isConsentRequired();
         for (RoleModel role : model.getRoles()) {
             roles.put(role.getName(), role.getId());
             cache.addCachedRole(new CachedApplicationRole(id, role, realm));
@@ -41,6 +85,93 @@ public class CachedApplication extends CachedClient {
         nodeReRegistrationTimeout = model.getNodeReRegistrationTimeout();
         registeredNodes = new TreeMap<String, Integer>(model.getRegisteredNodes());
     }
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getRealm() {
+        return realm;
+    }
+
+    public Set<String> getRedirectUris() {
+        return redirectUris;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public String getSecret() {
+        return secret;
+    }
+
+    public boolean isPublicClient() {
+        return publicClient;
+    }
+
+    public boolean isDirectGrantsOnly() {
+        return directGrantsOnly;
+    }
+
+    public int getNotBefore() {
+        return notBefore;
+    }
+
+    public Set<String> getScope() {
+        return scope;
+    }
+
+    public Set<String> getWebOrigins() {
+        return webOrigins;
+    }
+
+    public boolean isFullScopeAllowed() {
+        return fullScopeAllowed;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public boolean isFrontchannelLogout() {
+        return frontchannelLogout;
+    }
+
+    public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
+        return this.identityProviders;
+    }
+
+    public boolean hasIdentityProvider(String providerId) {
+        for (ClientIdentityProviderMappingModel model : getIdentityProviders()) {
+            if (model.getIdentityProvider().equals(providerId)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public Set<ProtocolMapperModel> getProtocolMappers() {
+        return protocolMappers;
+    }
+
+    public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
+        for (ClientIdentityProviderMappingModel model : getIdentityProviders()) {
+            if (model.getIdentityProvider().equals(providerId)) {
+                return model.isRetrieveToken();
+            }
+        }
+
+        return false;
+    }
 
     public boolean isSurrogateAuthRequired() {
         return surrogateAuthRequired;
@@ -62,6 +193,10 @@ public class CachedApplication extends CachedClient {
         return bearerOnly;
     }
 
+    public boolean isConsentRequired() {
+        return consentRequired;
+    }
+
     public Map<String, String> getRoles() {
         return roles;
     }
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 a88cf47..baafe43 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,392 +1,385 @@
-package org.keycloak.models.cache.entities;
-
-import org.keycloak.enums.SslRequired;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.IdentityProviderMapperModel;
-import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.models.OAuthClientModel;
-import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RealmProvider;
-import org.keycloak.models.RequiredCredentialModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserFederationProviderModel;
-import org.keycloak.models.cache.RealmCache;
-import org.keycloak.util.MultivaluedHashMap;
-
-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 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 Set<String> enabledEventTypes = 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>();
-    private boolean internationalizationEnabled;
-    private Set<String> supportedLocales = new HashSet<String>();
-    private String defaultLocale;
-    private MultivaluedHashMap<String, IdentityProviderMapperModel> identityProviderMappers = new MultivaluedHashMap<>();
-
-    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<>();
-
-        for (IdentityProviderModel identityProviderModel : model.getIdentityProviders()) {
-            this.identityProviders.add(new IdentityProviderModel(identityProviderModel));
-        }
-
-        for (IdentityProviderMapperModel mapper : model.getIdentityProviderMappers()) {
-            identityProviderMappers.add(mapper.getIdentityProviderAlias(), mapper);
-        }
-
-
-
-        smtpConfig.putAll(model.getSmtpConfig());
-        browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders());
-
-        eventsEnabled = model.isEventsEnabled();
-        eventsExpiration = model.getEventsExpiration();
-        eventsListeners.addAll(model.getEventsListeners());
-        enabledEventTypes.addAll(model.getEnabledEventTypes());
-        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);
-        }
-
-        internationalizationEnabled = model.isInternationalizationEnabled();
-        supportedLocales.addAll(model.getSupportedLocales());
-        defaultLocale = model.getDefaultLocale();
-
-    }
-
-
-    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 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 Set<String> getEnabledEventTypes() {
-        return enabledEventTypes;
-    }
-
-    public List<UserFederationProviderModel> getUserFederationProviders() {
-        return userFederationProviders;
-    }
-
-    public String getCertificatePem() {
-        return certificatePem;
-    }
-
-    public List<IdentityProviderModel> getIdentityProviders() {
-        return identityProviders;
-    }
-
-    public boolean isInternationalizationEnabled() {
-        return internationalizationEnabled;
-    }
-
-    public Set<String> getSupportedLocales() {
-        return supportedLocales;
-    }
-
-    public String getDefaultLocale() {
-        return defaultLocale;
-    }
-
-    public MultivaluedHashMap<String, IdentityProviderMapperModel> getIdentityProviderMappers() {
-        return identityProviderMappers;
-    }
-}
+package org.keycloak.models.cache.entities;
+
+import org.keycloak.enums.SslRequired;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RealmProvider;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.cache.RealmCache;
+import org.keycloak.util.MultivaluedHashMap;
+
+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 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 Set<String> enabledEventTypes = 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>();
+    private boolean internationalizationEnabled;
+    private Set<String> supportedLocales = new HashSet<String>();
+    private String defaultLocale;
+    private MultivaluedHashMap<String, IdentityProviderMapperModel> identityProviderMappers = new MultivaluedHashMap<>();
+
+    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<>();
+
+        for (IdentityProviderModel identityProviderModel : model.getIdentityProviders()) {
+            this.identityProviders.add(new IdentityProviderModel(identityProviderModel));
+        }
+
+        for (IdentityProviderMapperModel mapper : model.getIdentityProviderMappers()) {
+            identityProviderMappers.add(mapper.getIdentityProviderAlias(), mapper);
+        }
+
+
+
+        smtpConfig.putAll(model.getSmtpConfig());
+        browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders());
+
+        eventsEnabled = model.isEventsEnabled();
+        eventsExpiration = model.getEventsExpiration();
+        eventsListeners.addAll(model.getEventsListeners());
+        enabledEventTypes.addAll(model.getEnabledEventTypes());
+        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 (ClientModel app : model.getClients()) {
+            applications.put(app.getClientId(), app.getId());
+            CachedApplication cachedApp = new CachedApplication(cache, delegate, model, app);
+            cache.addCachedApplication(cachedApp);
+        }
+
+        internationalizationEnabled = model.isInternationalizationEnabled();
+        supportedLocales.addAll(model.getSupportedLocales());
+        defaultLocale = model.getDefaultLocale();
+
+    }
+
+
+    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 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 Set<String> getEnabledEventTypes() {
+        return enabledEventTypes;
+    }
+
+    public List<UserFederationProviderModel> getUserFederationProviders() {
+        return userFederationProviders;
+    }
+
+    public String getCertificatePem() {
+        return certificatePem;
+    }
+
+    public List<IdentityProviderModel> getIdentityProviders() {
+        return identityProviders;
+    }
+
+    public boolean isInternationalizationEnabled() {
+        return internationalizationEnabled;
+    }
+
+    public Set<String> getSupportedLocales() {
+        return supportedLocales;
+    }
+
+    public String getDefaultLocale() {
+        return defaultLocale;
+    }
+
+    public MultivaluedHashMap<String, IdentityProviderMapperModel> getIdentityProviderMappers() {
+        return identityProviderMappers;
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryRealmCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryRealmCache.java
index 2373f9f..25064c6 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryRealmCache.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryRealmCache.java
@@ -1,7 +1,6 @@
 package org.keycloak.models.cache;
 
 import org.keycloak.models.cache.entities.CachedApplication;
-import org.keycloak.models.cache.entities.CachedOAuthClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRole;
 
@@ -16,7 +15,6 @@ public class MemoryRealmCache implements RealmCache {
     protected ConcurrentHashMap<String, CachedRealm> realmCache = new ConcurrentHashMap<String, CachedRealm>();
     protected ConcurrentHashMap<String, CachedRealm> realmCacheByName = new ConcurrentHashMap<String, CachedRealm>();
     protected ConcurrentHashMap<String, CachedApplication> applicationCache = new ConcurrentHashMap<String, CachedApplication>();
-    protected ConcurrentHashMap<String, CachedOAuthClient> clientCache = new ConcurrentHashMap<String, CachedOAuthClient>();
     protected ConcurrentHashMap<String, CachedRole> roleCache = new ConcurrentHashMap<String, CachedRole>();
     protected volatile boolean enabled = true;
 
@@ -25,7 +23,6 @@ public class MemoryRealmCache implements RealmCache {
         realmCache.clear();
         realmCacheByName.clear();
         applicationCache.clear();
-        clientCache.clear();
         roleCache.clear();
     }
 
@@ -97,28 +94,6 @@ public class MemoryRealmCache implements RealmCache {
     }
 
     @Override
-    public CachedOAuthClient getOAuthClient(String id) {
-        if (!enabled) return null;
-        return clientCache.get(id);
-    }
-
-    @Override
-    public void invalidateOAuthClient(CachedOAuthClient client) {
-        clientCache.remove(client.getId());
-    }
-
-    @Override
-    public void addCachedOAuthClient(CachedOAuthClient client) {
-        if (!enabled) return;
-        clientCache.put(client.getId(), client);
-    }
-
-    @Override
-    public void invalidateCachedOAuthClientById(String id) {
-        clientCache.remove(id);
-    }
-
-    @Override
     public CachedRole getRole(String id) {
         if (!enabled) return null;
         return roleCache.get(id);
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheRealmProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheRealmProvider.java
index e7b1551..12c28f6 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheRealmProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheRealmProvider.java
@@ -1,8 +1,7 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RoleModel;
@@ -51,10 +50,6 @@ public class NoCacheRealmProvider implements CacheRealmProvider {
     }
 
     @Override
-    public void registerOAuthClientInvalidation(String id) {
-    }
-
-    @Override
     public RealmModel createRealm(String name) {
         return getDelegate().createRealm(name);
     }
@@ -96,17 +91,7 @@ public class NoCacheRealmProvider implements CacheRealmProvider {
     }
 
     @Override
-    public ApplicationModel getApplicationById(String id, RealmModel realm) {
-        return getDelegate().getApplicationById(id, realm);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
-        return getDelegate().getOAuthClientById(id, realm);
-    }
-
-    @Override
-    public void registerUserInvalidation(String id) {
-        //To change body of implemented methods use File | Settings | File Templates.
+    public ClientModel getClientById(String id, RealmModel realm) {
+        return getDelegate().getClientById(id, realm);
     }
 }
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 ef18caa..1e51a0c 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
@@ -2,14 +2,10 @@ package org.keycloak.models.cache;
 
 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.IdentityProviderMapperModel;
 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;
@@ -476,39 +472,25 @@ public class RealmAdapter implements RealmModel {
     }
 
     @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>();
+    public Map<String, ClientModel> getClientNameMap() {
+        if (updated != null) return updated.getClientNameMap();
+        Map<String, ClientModel> map = new HashMap<String, ClientModel>();
         for (String id : cached.getApplications().values()) {
-            ApplicationModel model = cacheSession.getApplicationById(id, this);
+            ClientModel model = cacheSession.getClientById(id, this);
             if (model == null) {
                 throw new IllegalStateException("Cached application not found: " + id);
             }
-            map.put(model.getName(), model);
+            map.put(model.getClientId(), model);
         }
         return map;
     }
 
     @Override
-    public List<ApplicationModel> getApplications() {
-        if (updated != null) return updated.getApplications();
-        List<ApplicationModel> apps = new LinkedList<ApplicationModel>();
+    public List<ClientModel> getClients() {
+        if (updated != null) return updated.getClients();
+        List<ClientModel> apps = new LinkedList<ClientModel>();
         for (String id : cached.getApplications().values()) {
-            ApplicationModel model = cacheSession.getApplicationById(id, this);
+            ClientModel model = cacheSession.getClientById(id, this);
             if (model == null) {
                 throw new IllegalStateException("Cached application not found: " + id);
             }
@@ -519,40 +501,40 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public ApplicationModel addApplication(String name) {
+    public ClientModel addClient(String name) {
         getDelegateForUpdate();
-        ApplicationModel app = updated.addApplication(name);
+        ClientModel app = updated.addClient(name);
         cacheSession.registerApplicationInvalidation(app.getId());
         return app;
     }
 
     @Override
-    public ApplicationModel addApplication(String id, String name) {
+    public ClientModel addClient(String id, String clientId) {
         getDelegateForUpdate();
-        ApplicationModel app =  updated.addApplication(id, name);
+        ClientModel app =  updated.addClient(id, clientId);
         cacheSession.registerApplicationInvalidation(app.getId());
         return app;
     }
 
     @Override
-    public boolean removeApplication(String id) {
+    public boolean removeClient(String id) {
         cacheSession.registerApplicationInvalidation(id);
         getDelegateForUpdate();
-        return updated.removeApplication(id);
+        return updated.removeClient(id);
     }
 
     @Override
-    public ApplicationModel getApplicationById(String id) {
-        if (updated != null) return updated.getApplicationById(id);
-        return cacheSession.getApplicationById(id, this);
+    public ClientModel getClientById(String id) {
+        if (updated != null) return updated.getClientById(id);
+        return cacheSession.getClientById(id, this);
     }
 
     @Override
-    public ApplicationModel getApplicationByName(String name) {
-        if (updated != null) return updated.getApplicationByName(name);
-        String id = cached.getApplications().get(name);
+    public ClientModel getClientByClientId(String clientId) {
+        if (updated != null) return updated.getClientByClientId(clientId);
+        String id = cached.getApplications().get(clientId);
         if (id == null) return null;
-        return getApplicationById(id);
+        return getClientById(id);
     }
 
     @Override
@@ -562,57 +544,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @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();
@@ -821,12 +752,12 @@ public class RealmAdapter implements RealmModel {
     }
     
     @Override
-    public ApplicationModel getMasterAdminApp() {
-        return cacheSession.getRealm(Config.getAdminRealm()).getApplicationById(cached.getMasterAdminApp());
+    public ClientModel getMasterAdminApp() {
+        return cacheSession.getRealm(Config.getAdminRealm()).getClientById(cached.getMasterAdminApp());
     }
 
     @Override
-    public void setMasterAdminApp(ApplicationModel app) {
+    public void setMasterAdminApp(ClientModel app) {
         getDelegateForUpdate();
         updated.setMasterAdminApp(app);
     }
@@ -876,13 +807,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @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();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
index 246a6ea..3d66462 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
@@ -1,7 +1,6 @@
 package org.keycloak.models.cache;
 
 import org.keycloak.models.cache.entities.CachedApplication;
-import org.keycloak.models.cache.entities.CachedOAuthClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRole;
 
@@ -30,14 +29,6 @@ public interface RealmCache {
 
     void invalidateCachedApplicationById(String id);
 
-    CachedOAuthClient getOAuthClient(String id);
-
-    void invalidateOAuthClient(CachedOAuthClient client);
-
-    void addCachedOAuthClient(CachedOAuthClient client);
-
-    void invalidateCachedOAuthClientById(String id);
-
     CachedRole getRole(String id);
 
     void invalidateRole(CachedRole role);
@@ -46,7 +37,6 @@ public interface RealmCache {
 
     void invalidateCachedRoleById(String id);
 
-
     void invalidateRoleById(String id);
 
     boolean isEnabled();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RoleAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RoleAdapter.java
index 18f6422..0f30ecd 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RoleAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RoleAdapter.java
@@ -107,7 +107,7 @@ public class RoleAdapter implements RoleModel {
             return realm;
         } else {
             CachedApplicationRole appRole = (CachedApplicationRole)cached;
-            return realm.getApplicationById(appRole.getAppId());
+            return realm.getClientById(appRole.getAppId());
         }
     }
 
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
index 14aea05..e659837 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
@@ -1,6 +1,6 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
@@ -219,14 +219,14 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
+    public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
         if (updated != null) return updated.getApplicationRoleMappings(app);
         Set<RoleModel> roleMappings = getRoleMappings();
         Set<RoleModel> appMappings = new HashSet<RoleModel>();
         for (RoleModel role : roleMappings) {
             RoleContainerModel container = role.getContainer();
-            if (container instanceof ApplicationModel) {
-                if (((ApplicationModel) container).getId().equals(app.getId())) {
+            if (container instanceof ClientModel) {
+                if (((ClientModel) container).getId().equals(app.getId())) {
                     appMappings.add(role);
                 }
             }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index bd44308..4b41921 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -1,9 +1,8 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
@@ -22,8 +21,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 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;
@@ -32,15 +29,18 @@ import java.util.Set;
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public abstract class ClientAdapter implements ClientModel {
-    protected ClientEntity entity;
+public class ClientAdapter implements ClientModel {
+
+    protected KeycloakSession session;
     protected RealmModel realm;
     protected EntityManager em;
+    protected ClientEntity entity;
 
-    public ClientAdapter(RealmModel realm, ClientEntity entity, EntityManager em) {
+    public ClientAdapter(RealmModel realm, EntityManager em, KeycloakSession session, ClientEntity entity) {
+        this.session = session;
         this.realm = realm;
-        this.entity = entity;
         this.em = em;
+        this.entity = entity;
     }
 
     public ClientEntity getEntity() {
@@ -58,11 +58,6 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
-    public String getClientId() {
-        return entity.getName();
-    }
-
-    @Override
     public boolean isEnabled() {
         return entity.isEnabled();
     }
@@ -177,7 +172,7 @@ public abstract class ClientAdapter implements ClientModel {
     public Set<RoleModel> getRealmScopeMappings() {
         Set<RoleModel> roleMappings = getScopeMappings();
 
-        Set<RoleModel> appRoles = new HashSet<RoleModel>();
+        Set<RoleModel> appRoles = new HashSet<>();
         for (RoleModel role : roleMappings) {
             RoleContainerModel container = role.getContainer();
             if (container instanceof RealmModel) {
@@ -190,8 +185,6 @@ public abstract class ClientAdapter implements ClientModel {
         return appRoles;
     }
 
-
-
     @Override
     public Set<RoleModel> getScopeMappings() {
         TypedQuery<String> query = em.createNamedQuery("clientScopeMappingIds", String.class);
@@ -237,32 +230,6 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
-    public boolean hasScope(RoleModel role) {
-        if (isFullScopeAllowed()) return true;
-        Set<RoleModel> roles = getScopeMappings();
-        if (roles.contains(role)) return true;
-
-        for (RoleModel mapping : roles) {
-            if (mapping.hasRole(role)) return true;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!this.getClass().equals(o.getClass())) return false;
-
-        ClientAdapter that = (ClientAdapter) o;
-        return that.getId().equals(getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return entity.getId().hashCode();
-    }
-
-    @Override
     public String getProtocol() {
         return entity.getProtocol();
     }
@@ -281,7 +248,7 @@ public abstract class ClientAdapter implements ClientModel {
 
     @Override
     public void removeAttribute(String name) {
-       entity.getAttributes().remove(name);
+        entity.getAttributes().remove(name);
     }
 
     @Override
@@ -291,7 +258,7 @@ public abstract class ClientAdapter implements ClientModel {
 
     @Override
     public Map<String, String> getAttributes() {
-        Map<String, String> copy = new HashMap<String, String>();
+        Map<String, String> copy = new HashMap<>();
         copy.putAll(entity.getAttributes());
         return copy;
     }
@@ -299,8 +266,8 @@ public abstract class ClientAdapter implements ClientModel {
     @Override
     public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
         Collection<ClientIdentityProviderMappingEntity> entities = entity.getIdentityProviders();
-        Set<String> already = new HashSet<String>();
-        List<ClientIdentityProviderMappingEntity> remove = new ArrayList<ClientIdentityProviderMappingEntity>();
+        Set<String> already = new HashSet<>();
+        List<ClientIdentityProviderMappingEntity> remove = new ArrayList<>();
 
         for (ClientIdentityProviderMappingEntity entity : entities) {
             IdentityProviderEntity identityProvider = entity.getIdentityProvider();
@@ -500,4 +467,282 @@ public abstract class ClientAdapter implements ClientModel {
         mapping.setConfig(config);
         return mapping;
     }
+
+    @Override
+    public void updateApplication() {
+        em.flush();
+    }
+
+    @Override
+    public String getClientId() {
+        return entity.getName();
+    }
+
+    @Override
+    public void setClientId(String clientId) {
+        entity.setName(clientId);
+    }
+
+    @Override
+    public boolean isSurrogateAuthRequired() {
+        return entity.isSurrogateAuthRequired();
+    }
+
+    @Override
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        entity.setSurrogateAuthRequired(surrogateAuthRequired);
+    }
+
+    @Override
+    public String getManagementUrl() {
+        return entity.getManagementUrl();
+    }
+
+    @Override
+    public void setManagementUrl(String url) {
+        entity.setManagementUrl(url);
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return entity.getBaseUrl();
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        entity.setBaseUrl(url);
+    }
+
+    @Override
+    public boolean isBearerOnly() {
+        return entity.isBearerOnly();
+    }
+
+    @Override
+    public void setBearerOnly(boolean only) {
+        entity.setBearerOnly(only);
+    }
+
+    @Override
+    public boolean isConsentRequired() {
+        return entity.isConsentRequired();
+    }
+
+    @Override
+    public void setConsentRequired(boolean consentRequired) {
+        entity.setConsentRequired(consentRequired);
+    }
+
+    @Override
+    public boolean isDirectGrantsOnly() {
+        return entity.isDirectGrantsOnly();
+    }
+
+    @Override
+    public void setDirectGrantsOnly(boolean flag) {
+        entity.setDirectGrantsOnly(flag);
+    }
+
+    @Override
+    public RoleModel getRole(String name) {
+        TypedQuery<RoleEntity> query = em.createNamedQuery("getAppRoleByName", RoleEntity.class);
+        query.setParameter("name", name);
+        query.setParameter("application", entity);
+        List<RoleEntity> roles = query.getResultList();
+        if (roles.size() == 0) return null;
+        return new RoleAdapter(realm, 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 roleEntity = new RoleEntity();
+        roleEntity.setId(id);
+        roleEntity.setName(name);
+        roleEntity.setApplication(entity);
+        roleEntity.setApplicationRole(true);
+        roleEntity.setRealmId(realm.getId());
+        em.persist(roleEntity);
+        entity.getRoles().add(roleEntity);
+        em.flush();
+        return new RoleAdapter(realm, em, roleEntity);
+    }
+
+    @Override
+    public boolean removeRole(RoleModel roleModel) {
+        if (roleModel == null) {
+            return false;
+        }
+        if (!roleModel.getContainer().equals(this)) return false;
+
+        session.users().preRemove(getRealm(), roleModel);
+        RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em);
+        if (!role.isApplicationRole()) return false;
+
+        entity.getRoles().remove(role);
+        entity.getDefaultRoles().remove(role);
+        em.createNativeQuery("delete from COMPOSITE_ROLE where CHILD_ROLE = :role").setParameter("role", role).executeUpdate();
+        em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", role).executeUpdate();
+        role.setApplication(null);
+        em.flush();
+        em.remove(role);
+        em.flush();
+
+        return true;
+    }
+
+    @Override
+    public Set<RoleModel> getRoles() {
+        Set<RoleModel> list = new HashSet<RoleModel>();
+        Collection<RoleEntity> roles = entity.getRoles();
+        if (roles == null) return list;
+        for (RoleEntity entity : roles) {
+            list.add(new RoleAdapter(realm, em, entity));
+        }
+        return list;
+    }
+
+    @Override
+    public boolean hasScope(RoleModel role) {
+        if (isFullScopeAllowed()) return true;
+        Set<RoleModel> roles = getScopeMappings();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        roles = getRoles();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
+        Set<RoleModel> roleMappings = client.getScopeMappings();
+
+        Set<RoleModel> appRoles = new HashSet<RoleModel>();
+        for (RoleModel role : roleMappings) {
+            RoleContainerModel container = role.getContainer();
+            if (container instanceof RealmModel) {
+            } else {
+                ClientModel app = (ClientModel)container;
+                if (app.getId().equals(getId())) {
+                    appRoles.add(role);
+                }
+            }
+        }
+
+        return appRoles;
+    }
+
+
+
+
+    @Override
+    public List<String> getDefaultRoles() {
+        Collection<RoleEntity> entities = entity.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 = entity.getDefaultRoles();
+        for (RoleEntity entity : entities) {
+            if (entity.getId().equals(role.getId())) {
+                return;
+            }
+        }
+        RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
+        entities.add(roleEntity);
+        em.flush();
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        Collection<RoleEntity> entities = entity.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 int getNodeReRegistrationTimeout() {
+        return entity.getNodeReRegistrationTimeout();
+    }
+
+    @Override
+    public void setNodeReRegistrationTimeout(int timeout) {
+        entity.setNodeReRegistrationTimeout(timeout);
+    }
+
+    @Override
+    public Map<String, Integer> getRegisteredNodes() {
+        return entity.getRegisteredNodes();
+    }
+
+    @Override
+    public void registerNode(String nodeHost, int registrationTime) {
+        Map<String, Integer> currentNodes = getRegisteredNodes();
+        currentNodes.put(nodeHost, registrationTime);
+        em.flush();
+    }
+
+    @Override
+    public void unregisterNode(String nodeHost) {
+        Map<String, Integer> currentNodes = getRegisteredNodes();
+        currentNodes.remove(nodeHost);
+        em.flush();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof ClientModel)) return false;
+
+        ClientModel that = (ClientModel) o;
+        return that.getId().equals(getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return getId().hashCode();
+    }
+
+    public String toString() {
+        return getClientId();
+    }
+
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index e3c8bfd..a53a0d2 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -7,8 +7,6 @@ import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToOne;
@@ -28,9 +26,9 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 @Entity
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
 @Table(name="CLIENT", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "NAME"})})
-public abstract class ClientEntity {
+public class ClientEntity {
+
     @Id
     @Column(name="ID", length = 36)
     private String id;
@@ -77,6 +75,40 @@ public abstract class ClientEntity {
     @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "client")
     Collection<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
 
+    @Column(name="SURROGATE_AUTH_REQUIRED")
+    private boolean surrogateAuthRequired;
+
+    @Column(name="BASE_URL")
+    private String baseUrl;
+
+    @Column(name="MANAGEMENT_URL")
+    private String managementUrl;
+
+    @Column(name="DIRECT_GRANTS_ONLY")
+    protected boolean directGrantsOnly;
+
+    @Column(name="BEARER_ONLY")
+    private boolean bearerOnly;
+
+    @Column(name="CONSENT_REQUIRED")
+    private boolean consentRequired;
+
+    @Column(name="NODE_REREG_TIMEOUT")
+    private int nodeReRegistrationTimeout;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "application")
+    Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
+
+    @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
+    @JoinTable(name="APPLICATION_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="APPLICATION_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")})
+    Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
+
+    @ElementCollection
+    @MapKeyColumn(name="NAME")
+    @Column(name="VALUE")
+    @CollectionTable(name="APP_NODE_REGISTRATIONS", joinColumns={ @JoinColumn(name="APPLICATION_ID") })
+    Map<String, Integer> registeredNodes = new HashMap<String, Integer>();
+
     public RealmEntity getRealm() {
         return realm;
     }
@@ -196,4 +228,84 @@ public abstract class ClientEntity {
     public void setProtocolMappers(Collection<ProtocolMapperEntity> protocolMappers) {
         this.protocolMappers = protocolMappers;
     }
+
+    public boolean isSurrogateAuthRequired() {
+        return surrogateAuthRequired;
+    }
+
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        this.surrogateAuthRequired = surrogateAuthRequired;
+    }
+
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public void setBaseUrl(String baseUrl) {
+        this.baseUrl = baseUrl;
+    }
+
+    public String getManagementUrl() {
+        return managementUrl;
+    }
+
+    public void setManagementUrl(String managementUrl) {
+        this.managementUrl = managementUrl;
+    }
+
+    public Collection<RoleEntity> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(Collection<RoleEntity> roles) {
+        this.roles = roles;
+    }
+
+    public Collection<RoleEntity> getDefaultRoles() {
+        return defaultRoles;
+    }
+
+    public void setDefaultRoles(Collection<RoleEntity> defaultRoles) {
+        this.defaultRoles = defaultRoles;
+    }
+
+    public boolean isBearerOnly() {
+        return bearerOnly;
+    }
+
+    public void setBearerOnly(boolean bearerOnly) {
+        this.bearerOnly = bearerOnly;
+    }
+
+    public boolean isConsentRequired() {
+        return consentRequired;
+    }
+
+    public void setConsentRequired(boolean consentRequired) {
+        this.consentRequired = consentRequired;
+    }
+
+    public boolean isDirectGrantsOnly() {
+        return directGrantsOnly;
+    }
+
+    public void setDirectGrantsOnly(boolean directGrantsOnly) {
+        this.directGrantsOnly = directGrantsOnly;
+    }
+
+    public int getNodeReRegistrationTimeout() {
+        return nodeReRegistrationTimeout;
+    }
+
+    public void setNodeReRegistrationTimeout(int nodeReRegistrationTimeout) {
+        this.nodeReRegistrationTimeout = nodeReRegistrationTimeout;
+    }
+
+    public Map<String, Integer> getRegisteredNodes() {
+        return registeredNodes;
+    }
+
+    public void setRegisteredNodes(Map<String, Integer> registeredNodes) {
+        this.registeredNodes = registeredNodes;
+    }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
index 7b2c323..ccce0d9 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ProtocolMapperEntity.java
@@ -9,8 +9,6 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.MapKeyColumn;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 import java.util.Map;
 
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 a656f76..d39b62e 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
@@ -105,7 +105,7 @@ public class RealmEntity {
 
     @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
     @JoinTable(name="REALM_APPLICATION", joinColumns={ @JoinColumn(name="REALM_ID") }, inverseJoinColumns={ @JoinColumn(name="APPLICATION_ID") })
-    Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
+    Collection<ClientEntity> applications = new ArrayList<ClientEntity>();
 
     @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
     Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
@@ -137,7 +137,7 @@ public class RealmEntity {
 
     @OneToOne
     @JoinColumn(name="MASTER_ADMIN_APP")
-    protected ApplicationEntity masterAdminApp;
+    protected ClientEntity masterAdminApp;
 
     @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
     protected List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
@@ -318,11 +318,11 @@ public class RealmEntity {
         this.requiredCredentials = requiredCredentials;
     }
 
-    public Collection<ApplicationEntity> getApplications() {
+    public Collection<ClientEntity> getApplications() {
         return applications;
     }
 
-    public void setApplications(Collection<ApplicationEntity> applications) {
+    public void setApplications(Collection<ClientEntity> applications) {
         this.applications = applications;
     }
 
@@ -437,11 +437,11 @@ public class RealmEntity {
         this.enabledEventTypes = enabledEventTypes;
     }
     
-    public ApplicationEntity getMasterAdminApp() {
+    public ClientEntity getMasterAdminApp() {
         return masterAdminApp;
     }
 
-    public void setMasterAdminApp(ApplicationEntity masterAdminApp) {
+    public void setMasterAdminApp(ClientEntity masterAdminApp) {
         this.masterAdminApp = masterAdminApp;
     }
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
index db40cea..ffbd711 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
@@ -51,7 +51,7 @@ public class RoleEntity {
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "APPLICATION")
-    private ApplicationEntity application;
+    private ClientEntity application;
 
     // Hack to ensure that either name+application or name+realm are unique. Needed due to MS-SQL as it don't allow multiple NULL values in the column, which is part of constraint
     @Column(name="APP_REALM_CONSTRAINT", length = 36)
@@ -118,11 +118,11 @@ public class RoleEntity {
         this.appRealmConstraint = realm.getId();
     }
 
-    public ApplicationEntity getApplication() {
+    public ClientEntity getApplication() {
         return application;
     }
 
-    public void setApplication(ApplicationEntity application) {
+    public void setApplication(ClientEntity application) {
         this.application = application;
         if (application != null) {
             this.appRealmConstraint = application.getId();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
index 3091cc9..f887670 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
@@ -1,13 +1,11 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.jpa.entities.ApplicationEntity;
-import org.keycloak.models.jpa.entities.OAuthClientEntity;
+import org.keycloak.models.jpa.entities.ClientEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
 import org.keycloak.models.jpa.entities.RoleEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -93,12 +91,8 @@ public class JpaRealmProvider implements RealmProvider {
 
         RealmAdapter adapter = new RealmAdapter(session, em, realm);
         session.users().preRemove(adapter);
-        for (ApplicationEntity a : new LinkedList<ApplicationEntity>(realm.getApplications())) {
-            adapter.removeApplication(a.getId());
-        }
-
-        for (OAuthClientModel oauth : adapter.getOAuthClients()) {
-            adapter.removeOAuthClient(oauth.getId());
+        for (ClientEntity a : new LinkedList<>(realm.getApplications())) {
+            adapter.removeClient(a.getId());
         }
 
         em.remove(realm);
@@ -118,21 +112,12 @@ public class JpaRealmProvider implements RealmProvider {
     }
 
     @Override
-    public ApplicationModel getApplicationById(String id, RealmModel realm) {
-        ApplicationEntity app = em.find(ApplicationEntity.class, id);
+    public ClientModel getClientById(String id, RealmModel realm) {
+        ClientEntity app = em.find(ClientEntity.class, id);
 
         // Check if application belongs to this realm
         if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
-        return new ApplicationAdapter(realm, em, session, app);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
-        OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
-
-        // Check if client belongs to this realm
-        if (client == null || !realm.getId().equals(client.getRealm().getId())) return null;
-        return new OAuthClientAdapter(realm, client, em);
+        return new ClientAdapter(realm, em, session, app);
     }
 
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
index 2b00c1c..07d3f6f 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
@@ -1,6 +1,6 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.CredentialValidationOutput;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.KeycloakSession;
@@ -61,7 +61,7 @@ public class JpaUserProvider implements UserProvider {
                 userModel.grantRole(realm.getRole(r));
             }
 
-            for (ApplicationModel application : realm.getApplications()) {
+            for (ClientModel application : realm.getClients()) {
                 for (String r : application.getDefaultRoles()) {
                     userModel.grantRole(application.getRole(r));
                 }
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 1f45e48..251004a 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,1415 +1,1325 @@
-package org.keycloak.models.jpa;
-
-import org.keycloak.enums.SslRequired;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.IdentityProviderMapperModel;
-import org.keycloak.models.IdentityProviderModel;
-import org.keycloak.models.KeycloakSession;
-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;
-import org.keycloak.models.UserFederationProviderModel;
-import org.keycloak.models.jpa.entities.ApplicationEntity;
-import org.keycloak.models.jpa.entities.IdentityProviderEntity;
-import org.keycloak.models.jpa.entities.IdentityProviderMapperEntity;
-import org.keycloak.models.jpa.entities.OAuthClientEntity;
-import org.keycloak.models.jpa.entities.RealmAttributeEntity;
-import org.keycloak.models.jpa.entities.RealmEntity;
-import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
-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 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(roleEntity);
-        realm.getDefaultRoles().remove(roleEntity);
-
-        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 Set<String> getEnabledEventTypes() {
-        return realm.getEnabledEventTypes();
-    }
-
-    @Override
-    public void setEnabledEventTypes(Set<String> enabledEventTypes) {
-        realm.setEnabledEventTypes(enabledEventTypes);
-        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.setAlias(entity.getAlias());
-            identityProviderModel.setInternalId(entity.getInternalId());
-            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 getIdentityProviderByAlias(String alias) {
-        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
-            if (identityProviderModel.getAlias().equals(alias)) {
-                return identityProviderModel;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public void addIdentityProvider(IdentityProviderModel identityProvider) {
-        IdentityProviderEntity entity = new IdentityProviderEntity();
-
-        entity.setInternalId(KeycloakModelUtils.generateId());
-        entity.setAlias(identityProvider.getAlias());
-        entity.setProviderId(identityProvider.getProviderId());
-        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 removeIdentityProviderByAlias(String alias) {
-        for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
-            if (entity.getAlias().equals(alias)) {
-                em.remove(entity);
-                em.flush();
-            }
-        }
-    }
-
-    @Override
-    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
-        for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
-            if (entity.getInternalId().equals(identityProvider.getInternalId())) {
-                entity.setAlias(identityProvider.getAlias());
-                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();
-    }
-
-    @Override
-    public boolean isInternationalizationEnabled() {
-        return realm.isInternationalizationEnabled();
-    }
-
-    @Override
-    public void setInternationalizationEnabled(boolean enabled) {
-        realm.setInternationalizationEnabled(enabled);
-        em.flush();
-    }
-
-    @Override
-    public Set<String> getSupportedLocales() {
-        return realm.getSupportedLocales();
-    }
-
-    @Override
-    public void setSupportedLocales(Set<String> locales) {
-        realm.setSupportedLocales(locales);
-        em.flush();
-    }
-
-    @Override
-    public String getDefaultLocale() {
-        return realm.getDefaultLocale();
-    }
-
-    @Override
-    public void setDefaultLocale(String locale) {
-        realm.setDefaultLocale(locale);
-        em.flush();
-    }
-
-    @Override
-    public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
-        Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
-            mapping.setId(entity.getId());
-            mapping.setName(entity.getName());
-            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
-            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
-            Map<String, String> config = new HashMap<String, String>();
-            if (entity.getConfig() != null) {
-                config.putAll(entity.getConfig());
-            }
-            mapping.setConfig(config);
-            mappings.add(mapping);
-        }
-        return mappings;
-    }
-
-    @Override
-    public Set<IdentityProviderMapperModel> getIdentityProviderMappersByAlias(String brokerAlias) {
-        Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
-                continue;
-            }
-            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
-            mapping.setId(entity.getId());
-            mapping.setName(entity.getName());
-            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
-            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
-            Map<String, String> config = new HashMap<String, String>();
-            if (entity.getConfig() != null) {
-                config.putAll(entity.getConfig());
-            }
-            mapping.setConfig(config);
-            mappings.add(mapping);
-        }
-        return mappings;
-    }
-
-    @Override
-    public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
-        if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
-            throw new RuntimeException("protocol mapper name must be unique per protocol");
-        }
-        String id = KeycloakModelUtils.generateId();
-        IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
-        entity.setId(id);
-        entity.setName(model.getName());
-        entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
-        entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
-        entity.setRealm(this.realm);
-        entity.setConfig(model.getConfig());
-
-        em.persist(entity);
-        this.realm.getIdentityProviderMappers().add(entity);
-        return entityToModel(entity);
-    }
-
-    protected IdentityProviderMapperEntity getIdentityProviderMapperEntity(String id) {
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            if (entity.getId().equals(id)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-
-    protected IdentityProviderMapperEntity getIdentityProviderMapperEntityByName(String alias, String name) {
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
-            if (entity.getIdentityProviderAlias().equals(alias) && entity.getName().equals(name)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-
-    @Override
-    public void removeIdentityProviderMapper(IdentityProviderMapperModel mapping) {
-        IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
-        if (toDelete != null) {
-            this.realm.getIdentityProviderMappers().remove(toDelete);
-            em.remove(toDelete);
-        }
-
-    }
-
-    @Override
-    public void updateIdentityProviderMapper(IdentityProviderMapperModel mapping) {
-        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(mapping.getId());
-        entity.setIdentityProviderAlias(mapping.getIdentityProviderAlias());
-        entity.setIdentityProviderMapper(mapping.getIdentityProviderMapper());
-        if (entity.getConfig() == null) {
-            entity.setConfig(mapping.getConfig());
-        } else {
-            entity.getConfig().clear();
-            entity.getConfig().putAll(mapping.getConfig());
-        }
-        em.flush();
-
-    }
-
-    @Override
-    public IdentityProviderMapperModel getIdentityProviderMapperById(String id) {
-        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(id);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    @Override
-    public IdentityProviderMapperModel getIdentityProviderMapperByName(String alias, String name) {
-        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntityByName(alias, name);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    protected IdentityProviderMapperModel entityToModel(IdentityProviderMapperEntity entity) {
-        IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
-        mapping.setId(entity.getId());
-        mapping.setName(entity.getName());
-        mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
-        mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
-        Map<String, String> config = new HashMap<String, String>();
-        if (entity.getConfig() != null) config.putAll(entity.getConfig());
-        mapping.setConfig(config);
-        return mapping;
-    }
+package org.keycloak.models.jpa;
+
+import org.keycloak.enums.SslRequired;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
+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.jpa.entities.ClientEntity;
+import org.keycloak.models.jpa.entities.IdentityProviderEntity;
+import org.keycloak.models.jpa.entities.IdentityProviderMapperEntity;
+import org.keycloak.models.jpa.entities.RealmAttributeEntity;
+import org.keycloak.models.jpa.entities.RealmEntity;
+import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
+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 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 Map<String, ClientModel> getClientNameMap() {
+        Map<String, ClientModel> map = new HashMap<String, ClientModel>();
+        for (ClientModel app : getClients()) {
+            map.put(app.getClientId(), app);
+        }
+        return map;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<ClientModel> getClients() {
+        List<ClientModel> list = new ArrayList<ClientModel>();
+        if (realm.getApplications() == null) return list;
+        for (ClientEntity entity : realm.getApplications()) {
+            list.add(new ClientAdapter(this, em, session, entity));
+        }
+        return list;
+    }
+
+    @Override
+    public ClientModel addClient(String name) {
+        return this.addClient(KeycloakModelUtils.generateId(), name);
+    }
+
+    @Override
+    public ClientModel addClient(String id, String clientId) {
+        ClientEntity applicationData = new ClientEntity();
+        applicationData.setId(id);
+        applicationData.setName(clientId);
+        applicationData.setEnabled(true);
+        applicationData.setRealm(realm);
+        realm.getApplications().add(applicationData);
+        em.persist(applicationData);
+        em.flush();
+        final ClientModel resource = new ClientAdapter(this, em, session, applicationData);
+        em.flush();
+        session.getKeycloakSessionFactory().publish(new ClientCreationEvent() {
+            @Override
+            public ClientModel getCreatedClient() {
+                return resource;
+            }
+        });
+        return resource;
+    }
+
+    @Override
+    public boolean removeClient(String id) {
+        if (id == null) return false;
+        ClientModel application = getClientById(id);
+        if (application == null) return false;
+
+        for (RoleModel role : application.getRoles()) {
+            application.removeRole(role);
+        }
+
+        ClientEntity clientEntity = null;
+        Iterator<ClientEntity> it = realm.getApplications().iterator();
+        while (it.hasNext()) {
+            ClientEntity ae = it.next();
+            if (ae.getId().equals(id)) {
+                clientEntity = ae;
+                it.remove();
+                break;
+            }
+        }
+        for (ClientEntity a : realm.getApplications()) {
+            if (a.getId().equals(id)) {
+                clientEntity = a;
+            }
+        }
+        if (application == null) {
+            return false;
+        }
+        em.remove(clientEntity);
+        em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", clientEntity).executeUpdate();
+        em.flush();
+
+        return true;
+    }
+
+    @Override
+    public ClientModel getClientById(String id) {
+        return session.realms().getClientById(id, this);
+    }
+
+    @Override
+    public ClientModel getClientByClientId(String clientId) {
+        return getClientNameMap().get(clientId);
+    }
+
+    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(roleEntity);
+        realm.getDefaultRoles().remove(roleEntity);
+
+        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 Set<String> getEnabledEventTypes() {
+        return realm.getEnabledEventTypes();
+    }
+
+    @Override
+    public void setEnabledEventTypes(Set<String> enabledEventTypes) {
+        realm.setEnabledEventTypes(enabledEventTypes);
+        em.flush();
+    }
+
+    @Override
+    public ClientModel getMasterAdminApp() {
+        return new ClientAdapter(this, em, session, realm.getMasterAdminApp());
+    }
+
+    @Override
+    public void setMasterAdminApp(ClientModel app) {
+        ClientEntity appEntity = app!=null ? em.getReference(ClientEntity.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.setAlias(entity.getAlias());
+            identityProviderModel.setInternalId(entity.getInternalId());
+            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 getIdentityProviderByAlias(String alias) {
+        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+            if (identityProviderModel.getAlias().equals(alias)) {
+                return identityProviderModel;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void addIdentityProvider(IdentityProviderModel identityProvider) {
+        IdentityProviderEntity entity = new IdentityProviderEntity();
+
+        entity.setInternalId(KeycloakModelUtils.generateId());
+        entity.setAlias(identityProvider.getAlias());
+        entity.setProviderId(identityProvider.getProviderId());
+        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 removeIdentityProviderByAlias(String alias) {
+        for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
+            if (entity.getAlias().equals(alias)) {
+                em.remove(entity);
+                em.flush();
+            }
+        }
+    }
+
+    @Override
+    public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+        for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
+            if (entity.getInternalId().equals(identityProvider.getInternalId())) {
+                entity.setAlias(identityProvider.getAlias());
+                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();
+    }
+
+    @Override
+    public boolean isInternationalizationEnabled() {
+        return realm.isInternationalizationEnabled();
+    }
+
+    @Override
+    public void setInternationalizationEnabled(boolean enabled) {
+        realm.setInternationalizationEnabled(enabled);
+        em.flush();
+    }
+
+    @Override
+    public Set<String> getSupportedLocales() {
+        return realm.getSupportedLocales();
+    }
+
+    @Override
+    public void setSupportedLocales(Set<String> locales) {
+        realm.setSupportedLocales(locales);
+        em.flush();
+    }
+
+    @Override
+    public String getDefaultLocale() {
+        return realm.getDefaultLocale();
+    }
+
+    @Override
+    public void setDefaultLocale(String locale) {
+        realm.setDefaultLocale(locale);
+        em.flush();
+    }
+
+    @Override
+    public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
+        Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
+            mapping.setId(entity.getId());
+            mapping.setName(entity.getName());
+            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
+            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
+            Map<String, String> config = new HashMap<String, String>();
+            if (entity.getConfig() != null) {
+                config.putAll(entity.getConfig());
+            }
+            mapping.setConfig(config);
+            mappings.add(mapping);
+        }
+        return mappings;
+    }
+
+    @Override
+    public Set<IdentityProviderMapperModel> getIdentityProviderMappersByAlias(String brokerAlias) {
+        Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
+                continue;
+            }
+            IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
+            mapping.setId(entity.getId());
+            mapping.setName(entity.getName());
+            mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
+            mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
+            Map<String, String> config = new HashMap<String, String>();
+            if (entity.getConfig() != null) {
+                config.putAll(entity.getConfig());
+            }
+            mapping.setConfig(config);
+            mappings.add(mapping);
+        }
+        return mappings;
+    }
+
+    @Override
+    public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
+        if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getIdentityProviderMapper()) != null) {
+            throw new RuntimeException("protocol mapper name must be unique per protocol");
+        }
+        String id = KeycloakModelUtils.generateId();
+        IdentityProviderMapperEntity entity = new IdentityProviderMapperEntity();
+        entity.setId(id);
+        entity.setName(model.getName());
+        entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
+        entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
+        entity.setRealm(this.realm);
+        entity.setConfig(model.getConfig());
+
+        em.persist(entity);
+        this.realm.getIdentityProviderMappers().add(entity);
+        return entityToModel(entity);
+    }
+
+    protected IdentityProviderMapperEntity getIdentityProviderMapperEntity(String id) {
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            if (entity.getId().equals(id)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+    protected IdentityProviderMapperEntity getIdentityProviderMapperEntityByName(String alias, String name) {
+        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+            if (entity.getIdentityProviderAlias().equals(alias) && entity.getName().equals(name)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public void removeIdentityProviderMapper(IdentityProviderMapperModel mapping) {
+        IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
+        if (toDelete != null) {
+            this.realm.getIdentityProviderMappers().remove(toDelete);
+            em.remove(toDelete);
+        }
+
+    }
+
+    @Override
+    public void updateIdentityProviderMapper(IdentityProviderMapperModel mapping) {
+        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(mapping.getId());
+        entity.setIdentityProviderAlias(mapping.getIdentityProviderAlias());
+        entity.setIdentityProviderMapper(mapping.getIdentityProviderMapper());
+        if (entity.getConfig() == null) {
+            entity.setConfig(mapping.getConfig());
+        } else {
+            entity.getConfig().clear();
+            entity.getConfig().putAll(mapping.getConfig());
+        }
+        em.flush();
+
+    }
+
+    @Override
+    public IdentityProviderMapperModel getIdentityProviderMapperById(String id) {
+        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntity(id);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    @Override
+    public IdentityProviderMapperModel getIdentityProviderMapperByName(String alias, String name) {
+        IdentityProviderMapperEntity entity = getIdentityProviderMapperEntityByName(alias, name);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    protected IdentityProviderMapperModel entityToModel(IdentityProviderMapperEntity entity) {
+        IdentityProviderMapperModel mapping = new IdentityProviderMapperModel();
+        mapping.setId(entity.getId());
+        mapping.setName(entity.getName());
+        mapping.setIdentityProviderAlias(entity.getIdentityProviderAlias());
+        mapping.setIdentityProviderMapper(entity.getIdentityProviderMapper());
+        Map<String, String> config = new HashMap<String, String>();
+        if (entity.getConfig() != null) config.putAll(entity.getConfig());
+        mapping.setConfig(config);
+        return mapping;
+    }
 }
\ No newline at end of file
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
index 28a1f47..1687855 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
@@ -105,7 +105,7 @@ public class RoleAdapter implements RoleModel {
     @Override
     public RoleContainerModel getContainer() {
         if (role.isApplicationRole()) {
-            return realm.getApplicationById(role.getApplication().getId());
+            return realm.getClientById(role.getApplication().getId());
 
         } else {
             return realm;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 5ef06fa..c0263ed 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -1,6 +1,6 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
@@ -363,14 +363,14 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
+    public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
         Set<RoleModel> roleMappings = getRoleMappings();
 
         Set<RoleModel> roles = new HashSet<RoleModel>();
         for (RoleModel role : roleMappings) {
             RoleContainerModel container = role.getContainer();
-            if (container instanceof ApplicationModel) {
-                ApplicationModel appModel = (ApplicationModel)container;
+            if (container instanceof ClientModel) {
+                ClientModel appModel = (ClientModel)container;
                 if (appModel.getId().equals(app.getId())) {
                    roles.add(role);
                 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 38c40f8..adbef6e 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -1,445 +1,672 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ProtocolMapperModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RealmProvider;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.entities.ClientEntity;
-import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
-import org.keycloak.models.entities.ProtocolMapperEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
-import org.keycloak.models.mongo.utils.MongoModelUtils;
-import org.keycloak.models.utils.KeycloakModelUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends AbstractMongoAdapter<T> implements ClientModel {
-
-    protected final T clientEntity;
-    private final RealmModel realm;
-    protected  KeycloakSession session;
-
-    public ClientAdapter(KeycloakSession session, RealmModel realm, T clientEntity, MongoStoreInvocationContext invContext) {
-        super(invContext);
-        this.clientEntity = clientEntity;
-        this.realm = realm;
-        this.session = session;
-    }
-
-    @Override
-    public T getMongoEntity() {
-        return clientEntity;
-    }
-
-    // ClientEntity doesn't extend MongoIdentifiableEntity
-    public ClientEntity getMongoEntityAsClient() {
-        return (ClientEntity)getMongoEntity();
-    }
-
-    @Override
-    public String getId() {
-        return getMongoEntity().getId();
-    }
-
-    @Override
-    public String getClientId() {
-        return getMongoEntityAsClient().getName();
-    }
-
-    @Override
-    public Set<String> getWebOrigins() {
-        Set<String> result = new HashSet<String>();
-        if (getMongoEntityAsClient().getWebOrigins() != null) {
-            result.addAll(getMongoEntityAsClient().getWebOrigins());
-        }
-        return result;
-    }
-
-    @Override
-    public void setWebOrigins(Set<String> webOrigins) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(webOrigins);
-        getMongoEntityAsClient().setWebOrigins(result);
-        updateMongoEntity();
-    }
-
-    @Override
-    public void addWebOrigin(String webOrigin) {
-        getMongoStore().pushItemToList(clientEntity, "webOrigins", webOrigin, true, invocationContext);
-    }
-
-    @Override
-    public void removeWebOrigin(String webOrigin) {
-        getMongoStore().pullItemFromList(clientEntity, "webOrigins", webOrigin, invocationContext);
-    }
-
-    @Override
-    public Set<String> getRedirectUris() {
-        Set<String> result = new HashSet<String>();
-        if (getMongoEntityAsClient().getRedirectUris() != null) {
-            result.addAll(getMongoEntityAsClient().getRedirectUris());
-        }
-        return result;
-    }
-
-    @Override
-    public void setRedirectUris(Set<String> redirectUris) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(redirectUris);
-        getMongoEntityAsClient().setRedirectUris(result);
-        updateMongoEntity();
-    }
-
-    @Override
-    public void addRedirectUri(String redirectUri) {
-        getMongoStore().pushItemToList(clientEntity, "redirectUris", redirectUri, true, invocationContext);
-    }
-
-    @Override
-    public void removeRedirectUri(String redirectUri) {
-        getMongoStore().pullItemFromList(clientEntity, "redirectUris", redirectUri, invocationContext);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return getMongoEntityAsClient().isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        getMongoEntityAsClient().setEnabled(enabled);
-        updateMongoEntity();
-    }
-
-    @Override
-    public boolean validateSecret(String secret) {
-        return secret.equals(getMongoEntityAsClient().getSecret());
-    }
-
-    @Override
-    public String getSecret() {
-        return getMongoEntityAsClient().getSecret();
-    }
-
-    @Override
-    public void setSecret(String secret) {
-        getMongoEntityAsClient().setSecret(secret);
-        updateMongoEntity();
-    }
-
-    @Override
-    public boolean isPublicClient() {
-        return getMongoEntityAsClient().isPublicClient();
-    }
-
-    @Override
-    public void setPublicClient(boolean flag) {
-        getMongoEntityAsClient().setPublicClient(flag);
-        updateMongoEntity();
-    }
-
-
-    @Override
-    public boolean isFrontchannelLogout() {
-        return getMongoEntityAsClient().isFrontchannelLogout();
-    }
-
-    @Override
-    public void setFrontchannelLogout(boolean flag) {
-        getMongoEntityAsClient().setFrontchannelLogout(flag);
-        updateMongoEntity();
-    }
-
-    @Override
-    public boolean isFullScopeAllowed() {
-        return getMongoEntityAsClient().isFullScopeAllowed();
-    }
-
-    @Override
-    public void setFullScopeAllowed(boolean value) {
-        getMongoEntityAsClient().setFullScopeAllowed(value);
-        updateMongoEntity();
-
-    }
-
-    @Override
-    public RealmModel getRealm() {
-        return realm;
-    }
-
-    @Override
-    public int getNotBefore() {
-        return getMongoEntityAsClient().getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        getMongoEntityAsClient().setNotBefore(notBefore);
-        updateMongoEntity();
-    }
-
-    @Override
-    public Set<RoleModel> getScopeMappings() {
-        Set<RoleModel> result = new HashSet<RoleModel>();
-        List<MongoRoleEntity> roles = MongoModelUtils.getAllScopesOfClient(this, invocationContext);
-
-        for (MongoRoleEntity role : roles) {
-            if (realm.getId().equals(role.getRealmId())) {
-                result.add(new RoleAdapter(session, realm, role, realm, invocationContext));
-            } else {
-                // Likely applicationRole, but we don't have this application yet
-                result.add(new RoleAdapter(session, realm, role, invocationContext));
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public Set<RoleModel> getRealmScopeMappings() {
-        Set<RoleModel> allScopes = getScopeMappings();
-
-        // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user?
-        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
-        for (RoleModel role : allScopes) {
-            MongoRoleEntity roleEntity = ((RoleAdapter) role).getRole();
-
-            if (realm.getId().equals(roleEntity.getRealmId())) {
-                realmRoles.add(role);
-            }
-        }
-        return realmRoles;
-    }
-
-    @Override
-    public boolean hasScope(RoleModel role) {
-        if (isFullScopeAllowed()) return true;
-        Set<RoleModel> roles = getScopeMappings();
-        if (roles.contains(role)) return true;
-
-        for (RoleModel mapping : roles) {
-            if (mapping.hasRole(role)) return true;
-        }
-        return false;
-    }
-
-
-    @Override
-    public void addScopeMapping(RoleModel role) {
-        getMongoStore().pushItemToList(this.getMongoEntity(), "scopeIds", role.getId(), true, invocationContext);
-    }
-
-    @Override
-    public void deleteScopeMapping(RoleModel role) {
-        getMongoStore().pullItemFromList(this.getMongoEntity(), "scopeIds", role.getId(), invocationContext);
-    }
-
-    @Override
-    public String getProtocol() {
-        return getMongoEntityAsClient().getProtocol();
-    }
-
-    @Override
-    public void setProtocol(String protocol) {
-        getMongoEntityAsClient().setProtocol(protocol);
-        updateMongoEntity();
-
-    }
-
-    @Override
-    public void setAttribute(String name, String value) {
-        getMongoEntityAsClient().getAttributes().put(name, value);
-        updateMongoEntity();
-
-    }
-
-    @Override
-    public void removeAttribute(String name) {
-        getMongoEntityAsClient().getAttributes().remove(name);
-        updateMongoEntity();
-    }
-
-    @Override
-    public String getAttribute(String name) {
-        return getMongoEntityAsClient().getAttributes().get(name);
-    }
-
-    @Override
-    public Map<String, String> getAttributes() {
-        Map<String, String> copy = new HashMap<String, String>();
-        copy.putAll(getMongoEntityAsClient().getAttributes());
-        return copy;
-    }
-
-    @Override
-    public Set<ProtocolMapperModel> getProtocolMappers() {
-        Set<ProtocolMapperModel> result = new HashSet<ProtocolMapperModel>();
-        for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
-            ProtocolMapperModel mapping = new ProtocolMapperModel();
-            mapping.setId(entity.getId());
-            mapping.setName(entity.getName());
-            mapping.setProtocol(entity.getProtocol());
-            mapping.setProtocolMapper(entity.getProtocolMapper());
-            mapping.setConsentRequired(entity.isConsentRequired());
-            mapping.setConsentText(entity.getConsentText());
-            Map<String, String> config = new HashMap<String, String>();
-            if (entity.getConfig() != null) {
-                config.putAll(entity.getConfig());
-            }
-            mapping.setConfig(config);
-            result.add(mapping);
-        }
-        return result;
-    }
-
-    @Override
-    public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
-        if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
-            throw new RuntimeException("protocol mapper name must be unique per protocol");
-        }
-        ProtocolMapperEntity entity = new ProtocolMapperEntity();
-        entity.setId(KeycloakModelUtils.generateId());
-        entity.setProtocol(model.getProtocol());
-        entity.setName(model.getName());
-        entity.setProtocolMapper(model.getProtocolMapper());
-        entity.setConfig(model.getConfig());
-        entity.setConsentRequired(model.isConsentRequired());
-        entity.setConsentText(model.getConsentText());
-        getMongoEntityAsClient().getProtocolMappers().add(entity);
-        updateMongoEntity();
-        return entityToModel(entity);
-    }
-
-    @Override
-    public void removeProtocolMapper(ProtocolMapperModel mapping) {
-        for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
-            if (entity.getId().equals(mapping.getId())) {
-                getMongoEntityAsClient().getProtocolMappers().remove(entity);
-                updateMongoEntity();
-                break;
-            }
-        }
-
-    }
-
-    protected ProtocolMapperEntity getProtocolMapperyEntityById(String id) {
-        for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
-            if (entity.getId().equals(id)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-    protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
-        for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
-            if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
-                return entity;
-            }
-        }
-        return null;
-
-    }
-
-
-    @Override
-    public void updateProtocolMapper(ProtocolMapperModel mapping) {
-        ProtocolMapperEntity entity = getProtocolMapperyEntityById(mapping.getId());
-        entity.setProtocolMapper(mapping.getProtocolMapper());
-        entity.setConsentRequired(mapping.isConsentRequired());
-        entity.setConsentText(mapping.getConsentText());
-        if (entity.getConfig() != null) {
-            entity.getConfig().clear();
-            entity.getConfig().putAll(mapping.getConfig());
-        } else {
-            entity.setConfig(mapping.getConfig());
-        }
-        updateMongoEntity();
-
-    }
-
-    @Override
-    public ProtocolMapperModel getProtocolMapperById(String id) {
-        ProtocolMapperEntity entity = getProtocolMapperyEntityById(id);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    @Override
-    public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
-        ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
-        if (entity == null) return null;
-        return entityToModel(entity);
-    }
-
-    protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
-        ProtocolMapperModel mapping = new ProtocolMapperModel();
-        mapping.setId(entity.getId());
-        mapping.setName(entity.getName());
-        mapping.setProtocol(entity.getProtocol());
-        mapping.setProtocolMapper(entity.getProtocolMapper());
-        mapping.setConsentRequired(entity.isConsentRequired());
-        mapping.setConsentText(entity.getConsentText());
-        Map<String, String> config = new HashMap<String, String>();
-        if (entity.getConfig() != null) config.putAll(entity.getConfig());
-        mapping.setConfig(config);
-        return mapping;
-    }
-
-
-    @Override
-    public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
-        List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
-
-        for (ClientIdentityProviderMappingModel model : identityProviders) {
-            ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
-
-            entity.setId(model.getIdentityProvider());
-            entity.setRetrieveToken(model.isRetrieveToken());
-            stored.add(entity);
-        }
-
-        getMongoEntityAsClient().setIdentityProviders(stored);
-        updateMongoEntity();
-    }
-
-    @Override
-    public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
-        List<ClientIdentityProviderMappingModel> models = new ArrayList<ClientIdentityProviderMappingModel>();
-
-        for (ClientIdentityProviderMappingEntity entity : getMongoEntityAsClient().getIdentityProviders()) {
-            ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
-
-            model.setIdentityProvider(entity.getId());
-            model.setRetrieveToken(entity.isRetrieveToken());
-
-            models.add(model);
-        }
-
-        return models;
-    }
-
-    @Override
-    public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
-        for (ClientIdentityProviderMappingEntity identityProviderMappingModel : getMongoEntityAsClient().getIdentityProviders()) {
-            if (identityProviderMappingModel.getId().equals(providerId)) {
-                return identityProviderMappingModel.isRetrieveToken();
-            }
-        }
-
-        return false;
-    }
-
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
+import org.keycloak.models.entities.ProtocolMapperEntity;
+import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
+import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
+import org.keycloak.models.mongo.utils.MongoModelUtils;
+import org.keycloak.models.utils.KeycloakModelUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ClientAdapter extends AbstractMongoAdapter<MongoApplicationEntity> implements ClientModel {
+
+    protected final MongoApplicationEntity applicationEntity;
+    private final RealmModel realm;
+    protected  KeycloakSession session;
+
+    public ClientAdapter(KeycloakSession session, RealmModel realm, MongoApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) {
+        super(invContext);
+        this.session = session;
+        this.realm = realm;
+        this.applicationEntity = applicationEntity;
+    }
+
+    @Override
+    public MongoApplicationEntity getMongoEntity() {
+        return applicationEntity;
+    }
+
+    @Override
+    public void updateApplication() {
+        updateMongoEntity();
+    }
+
+
+    @Override
+    public String getId() {
+        return getMongoEntity().getId();
+    }
+
+    @Override
+    public String getClientId() {
+        return getMongoEntity().getName();
+    }
+
+    @Override
+    public void setClientId(String clientId) {
+        getMongoEntity().setName(clientId);
+        updateMongoEntity();
+    }
+
+    @Override
+    public Set<String> getWebOrigins() {
+        Set<String> result = new HashSet<String>();
+        if (getMongoEntity().getWebOrigins() != null) {
+            result.addAll(getMongoEntity().getWebOrigins());
+        }
+        return result;
+    }
+
+    @Override
+    public void setWebOrigins(Set<String> webOrigins) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(webOrigins);
+        getMongoEntity().setWebOrigins(result);
+        updateMongoEntity();
+    }
+
+    @Override
+    public void addWebOrigin(String webOrigin) {
+        getMongoStore().pushItemToList(applicationEntity, "webOrigins", webOrigin, true, invocationContext);
+    }
+
+    @Override
+    public void removeWebOrigin(String webOrigin) {
+        getMongoStore().pullItemFromList(applicationEntity, "webOrigins", webOrigin, invocationContext);
+    }
+
+    @Override
+    public Set<String> getRedirectUris() {
+        Set<String> result = new HashSet<String>();
+        if (getMongoEntity().getRedirectUris() != null) {
+            result.addAll(getMongoEntity().getRedirectUris());
+        }
+        return result;
+    }
+
+    @Override
+    public void setRedirectUris(Set<String> redirectUris) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(redirectUris);
+        getMongoEntity().setRedirectUris(result);
+        updateMongoEntity();
+    }
+
+    @Override
+    public void addRedirectUri(String redirectUri) {
+        getMongoStore().pushItemToList(applicationEntity, "redirectUris", redirectUri, true, invocationContext);
+    }
+
+    @Override
+    public void removeRedirectUri(String redirectUri) {
+        getMongoStore().pullItemFromList(applicationEntity, "redirectUris", redirectUri, invocationContext);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return getMongoEntity().isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        getMongoEntity().setEnabled(enabled);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean validateSecret(String secret) {
+        return secret.equals(getMongoEntity().getSecret());
+    }
+
+    @Override
+    public String getSecret() {
+        return getMongoEntity().getSecret();
+    }
+
+    @Override
+    public void setSecret(String secret) {
+        getMongoEntity().setSecret(secret);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean isPublicClient() {
+        return getMongoEntity().isPublicClient();
+    }
+
+    @Override
+    public void setPublicClient(boolean flag) {
+        getMongoEntity().setPublicClient(flag);
+        updateMongoEntity();
+    }
+
+
+    @Override
+    public boolean isFrontchannelLogout() {
+        return getMongoEntity().isFrontchannelLogout();
+    }
+
+    @Override
+    public void setFrontchannelLogout(boolean flag) {
+        getMongoEntity().setFrontchannelLogout(flag);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean isFullScopeAllowed() {
+        return getMongoEntity().isFullScopeAllowed();
+    }
+
+    @Override
+    public void setFullScopeAllowed(boolean value) {
+        getMongoEntity().setFullScopeAllowed(value);
+        updateMongoEntity();
+
+    }
+
+    @Override
+    public RealmModel getRealm() {
+        return realm;
+    }
+
+    @Override
+    public int getNotBefore() {
+        return getMongoEntity().getNotBefore();
+    }
+
+    @Override
+    public void setNotBefore(int notBefore) {
+        getMongoEntity().setNotBefore(notBefore);
+        updateMongoEntity();
+    }
+
+    @Override
+    public Set<RoleModel> getScopeMappings() {
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        List<MongoRoleEntity> roles = MongoModelUtils.getAllScopesOfClient(this, invocationContext);
+
+        for (MongoRoleEntity role : roles) {
+            if (realm.getId().equals(role.getRealmId())) {
+                result.add(new RoleAdapter(session, realm, role, realm, invocationContext));
+            } else {
+                // Likely applicationRole, but we don't have this application yet
+                result.add(new RoleAdapter(session, realm, role, invocationContext));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Set<RoleModel> getRealmScopeMappings() {
+        Set<RoleModel> allScopes = getScopeMappings();
+
+        // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user?
+        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
+        for (RoleModel role : allScopes) {
+            MongoRoleEntity roleEntity = ((RoleAdapter) role).getRole();
+
+            if (realm.getId().equals(roleEntity.getRealmId())) {
+                realmRoles.add(role);
+            }
+        }
+        return realmRoles;
+    }
+
+    @Override
+    public void addScopeMapping(RoleModel role) {
+        getMongoStore().pushItemToList(this.getMongoEntity(), "scopeIds", role.getId(), true, invocationContext);
+    }
+
+    @Override
+    public void deleteScopeMapping(RoleModel role) {
+        getMongoStore().pullItemFromList(this.getMongoEntity(), "scopeIds", role.getId(), invocationContext);
+    }
+
+    @Override
+    public String getProtocol() {
+        return getMongoEntity().getProtocol();
+    }
+
+    @Override
+    public void setProtocol(String protocol) {
+        getMongoEntity().setProtocol(protocol);
+        updateMongoEntity();
+
+    }
+
+    @Override
+    public void setAttribute(String name, String value) {
+        getMongoEntity().getAttributes().put(name, value);
+        updateMongoEntity();
+
+    }
+
+    @Override
+    public void removeAttribute(String name) {
+        getMongoEntity().getAttributes().remove(name);
+        updateMongoEntity();
+    }
+
+    @Override
+    public String getAttribute(String name) {
+        return getMongoEntity().getAttributes().get(name);
+    }
+
+    @Override
+    public Map<String, String> getAttributes() {
+        Map<String, String> copy = new HashMap<String, String>();
+        copy.putAll(getMongoEntity().getAttributes());
+        return copy;
+    }
+
+    @Override
+    public Set<ProtocolMapperModel> getProtocolMappers() {
+        Set<ProtocolMapperModel> result = new HashSet<ProtocolMapperModel>();
+        for (ProtocolMapperEntity entity : getMongoEntity().getProtocolMappers()) {
+            ProtocolMapperModel mapping = new ProtocolMapperModel();
+            mapping.setId(entity.getId());
+            mapping.setName(entity.getName());
+            mapping.setProtocol(entity.getProtocol());
+            mapping.setProtocolMapper(entity.getProtocolMapper());
+            mapping.setConsentRequired(entity.isConsentRequired());
+            mapping.setConsentText(entity.getConsentText());
+            Map<String, String> config = new HashMap<String, String>();
+            if (entity.getConfig() != null) {
+                config.putAll(entity.getConfig());
+            }
+            mapping.setConfig(config);
+            result.add(mapping);
+        }
+        return result;
+    }
+
+    @Override
+    public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
+        if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
+            throw new RuntimeException("protocol mapper name must be unique per protocol");
+        }
+        ProtocolMapperEntity entity = new ProtocolMapperEntity();
+        entity.setId(KeycloakModelUtils.generateId());
+        entity.setProtocol(model.getProtocol());
+        entity.setName(model.getName());
+        entity.setProtocolMapper(model.getProtocolMapper());
+        entity.setConfig(model.getConfig());
+        entity.setConsentRequired(model.isConsentRequired());
+        entity.setConsentText(model.getConsentText());
+        getMongoEntity().getProtocolMappers().add(entity);
+        updateMongoEntity();
+        return entityToModel(entity);
+    }
+
+    @Override
+    public void removeProtocolMapper(ProtocolMapperModel mapping) {
+        for (ProtocolMapperEntity entity : getMongoEntity().getProtocolMappers()) {
+            if (entity.getId().equals(mapping.getId())) {
+                getMongoEntity().getProtocolMappers().remove(entity);
+                updateMongoEntity();
+                break;
+            }
+        }
+
+    }
+
+    protected ProtocolMapperEntity getProtocolMapperyEntityById(String id) {
+        for (ProtocolMapperEntity entity : getMongoEntity().getProtocolMappers()) {
+            if (entity.getId().equals(id)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+    protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
+        for (ProtocolMapperEntity entity : getMongoEntity().getProtocolMappers()) {
+            if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
+                return entity;
+            }
+        }
+        return null;
+
+    }
+
+
+    @Override
+    public void updateProtocolMapper(ProtocolMapperModel mapping) {
+        ProtocolMapperEntity entity = getProtocolMapperyEntityById(mapping.getId());
+        entity.setProtocolMapper(mapping.getProtocolMapper());
+        entity.setConsentRequired(mapping.isConsentRequired());
+        entity.setConsentText(mapping.getConsentText());
+        if (entity.getConfig() != null) {
+            entity.getConfig().clear();
+            entity.getConfig().putAll(mapping.getConfig());
+        } else {
+            entity.setConfig(mapping.getConfig());
+        }
+        updateMongoEntity();
+
+    }
+
+    @Override
+    public ProtocolMapperModel getProtocolMapperById(String id) {
+        ProtocolMapperEntity entity = getProtocolMapperyEntityById(id);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    @Override
+    public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
+        ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
+        if (entity == null) return null;
+        return entityToModel(entity);
+    }
+
+    protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
+        ProtocolMapperModel mapping = new ProtocolMapperModel();
+        mapping.setId(entity.getId());
+        mapping.setName(entity.getName());
+        mapping.setProtocol(entity.getProtocol());
+        mapping.setProtocolMapper(entity.getProtocolMapper());
+        mapping.setConsentRequired(entity.isConsentRequired());
+        mapping.setConsentText(entity.getConsentText());
+        Map<String, String> config = new HashMap<String, String>();
+        if (entity.getConfig() != null) config.putAll(entity.getConfig());
+        mapping.setConfig(config);
+        return mapping;
+    }
+
+
+    @Override
+    public void updateIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
+        List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();
+
+        for (ClientIdentityProviderMappingModel model : identityProviders) {
+            ClientIdentityProviderMappingEntity entity = new ClientIdentityProviderMappingEntity();
+
+            entity.setId(model.getIdentityProvider());
+            entity.setRetrieveToken(model.isRetrieveToken());
+            stored.add(entity);
+        }
+
+        getMongoEntity().setIdentityProviders(stored);
+        updateMongoEntity();
+    }
+
+    @Override
+    public List<ClientIdentityProviderMappingModel> getIdentityProviders() {
+        List<ClientIdentityProviderMappingModel> models = new ArrayList<ClientIdentityProviderMappingModel>();
+
+        for (ClientIdentityProviderMappingEntity entity : getMongoEntity().getIdentityProviders()) {
+            ClientIdentityProviderMappingModel model = new ClientIdentityProviderMappingModel();
+
+            model.setIdentityProvider(entity.getId());
+            model.setRetrieveToken(entity.isRetrieveToken());
+
+            models.add(model);
+        }
+
+        return models;
+    }
+
+    @Override
+    public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {
+        for (ClientIdentityProviderMappingEntity identityProviderMappingModel : getMongoEntity().getIdentityProviders()) {
+            if (identityProviderMappingModel.getId().equals(providerId)) {
+                return identityProviderMappingModel.isRetrieveToken();
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isSurrogateAuthRequired() {
+        return getMongoEntity().isSurrogateAuthRequired();
+    }
+
+    @Override
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        getMongoEntity().setSurrogateAuthRequired(surrogateAuthRequired);
+        updateMongoEntity();
+    }
+
+    @Override
+    public String getManagementUrl() {
+        return getMongoEntity().getManagementUrl();
+    }
+
+    @Override
+    public void setManagementUrl(String url) {
+        getMongoEntity().setManagementUrl(url);
+        updateMongoEntity();
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        getMongoEntity().setBaseUrl(url);
+        updateMongoEntity();
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return getMongoEntity().getBaseUrl();
+    }
+
+    @Override
+    public boolean isBearerOnly() {
+        return getMongoEntity().isBearerOnly();
+    }
+
+    @Override
+    public void setBearerOnly(boolean only) {
+        getMongoEntity().setBearerOnly(only);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean isConsentRequired() {
+        return getMongoEntity().isConsentRequired();
+    }
+
+    @Override
+    public void setConsentRequired(boolean consentRequired) {
+        getMongoEntity().setConsentRequired(consentRequired);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean isDirectGrantsOnly() {
+        return getMongoEntity().isDirectGrantsOnly();
+    }
+
+    @Override
+    public void setDirectGrantsOnly(boolean flag) {
+        getMongoEntity().setDirectGrantsOnly(flag);
+        updateMongoEntity();
+    }
+
+    @Override
+    public RoleAdapter getRole(String name) {
+        DBObject query = new QueryBuilder()
+                .and("name").is(name)
+                .and("applicationId").is(getId())
+                .get();
+        MongoRoleEntity role = getMongoStore().loadSingleEntity(MongoRoleEntity.class, query, invocationContext);
+        if (role == null) {
+            return null;
+        } else {
+            return new RoleAdapter(session, getRealm(), role, invocationContext);
+        }
+    }
+
+    @Override
+    public RoleAdapter addRole(String name) {
+        return this.addRole(null, name);
+    }
+
+    @Override
+    public RoleAdapter addRole(String id, String name) {
+        MongoRoleEntity roleEntity = new MongoRoleEntity();
+        roleEntity.setId(id);
+        roleEntity.setName(name);
+        roleEntity.setClientId(getId());
+
+        getMongoStore().insertEntity(roleEntity, invocationContext);
+
+        return new RoleAdapter(session, getRealm(), roleEntity, this, invocationContext);
+    }
+
+    @Override
+    public boolean removeRole(RoleModel role) {
+        session.users().preRemove(getRealm(), role);
+        return getMongoStore().removeEntity(MongoRoleEntity.class, role.getId(), invocationContext);
+    }
+
+    @Override
+    public Set<RoleModel> getRoles() {
+        DBObject query = new QueryBuilder()
+                .and("applicationId").is(getId())
+                .get();
+        List<MongoRoleEntity> roles = getMongoStore().loadEntities(MongoRoleEntity.class, query, invocationContext);
+
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        for (MongoRoleEntity role : roles) {
+            result.add(new RoleAdapter(session, getRealm(), role, this, invocationContext));
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean hasScope(RoleModel role) {
+        if (isFullScopeAllowed()) return true;
+        Set<RoleModel> roles = getScopeMappings();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+
+        roles = getRoles();
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        List<MongoRoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
+
+        for (MongoRoleEntity role : roles) {
+            if (getId().equals(role.getClientId())) {
+                result.add(new RoleAdapter(session, getRealm(), role, this, invocationContext));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        return getMongoEntity().getDefaultRoles();
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        RoleModel role = getRole(name);
+        if (role == null) {
+            addRole(name);
+        }
+
+        getMongoStore().pushItemToList(getMongoEntity(), "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);
+        }
+
+        getMongoEntity().setDefaultRoles(roleNames);
+        updateMongoEntity();
+    }
+
+    @Override
+    public int getNodeReRegistrationTimeout() {
+        return getMongoEntity().getNodeReRegistrationTimeout();
+    }
+
+    @Override
+    public void setNodeReRegistrationTimeout(int timeout) {
+        getMongoEntity().setNodeReRegistrationTimeout(timeout);
+        updateMongoEntity();
+    }
+
+    @Override
+    public Map<String, Integer> getRegisteredNodes() {
+        return getMongoEntity().getRegisteredNodes() == null ? Collections.<String, Integer>emptyMap() : Collections.unmodifiableMap(getMongoEntity().getRegisteredNodes());
+    }
+
+    @Override
+    public void registerNode(String nodeHost, int registrationTime) {
+        MongoApplicationEntity entity = getMongoEntity();
+        if (entity.getRegisteredNodes() == null) {
+            entity.setRegisteredNodes(new HashMap<String, Integer>());
+        }
+
+        entity.getRegisteredNodes().put(nodeHost, registrationTime);
+        updateMongoEntity();
+    }
+
+    @Override
+    public void unregisterNode(String nodeHost) {
+        MongoApplicationEntity entity = getMongoEntity();
+        if (entity.getRegisteredNodes() == null) return;
+
+        entity.getRegisteredNodes().remove(nodeHost);
+        updateMongoEntity();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof ClientModel)) return false;
+
+        ClientModel that = (ClientModel) o;
+        return that.getId().equals(getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return getId().hashCode();
+    }
+
+
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
index 61865d6..3b5f8a0 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
@@ -5,14 +5,12 @@ import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.MongoStore;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -107,12 +105,12 @@ public class MongoRealmProvider implements RealmProvider {
         MongoRoleEntity role = getMongoStore().loadEntity(MongoRoleEntity.class, id, invocationContext);
         if (role == null) return null;
         if (role.getRealmId() != null && !role.getRealmId().equals(realm.getId())) return null;
-        if (role.getApplicationId() != null && realm.getApplicationById(role.getApplicationId()) == null) return null;
+        if (role.getClientId() != null && realm.getClientById(role.getClientId()) == null) return null;
         return new RoleAdapter(session, realm, role, null, invocationContext);
     }
 
     @Override
-    public ApplicationModel getApplicationById(String id, RealmModel realm) {
+    public ClientModel getClientById(String id, RealmModel realm) {
         MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, id, invocationContext);
 
         // Check if application belongs to this realm
@@ -120,17 +118,7 @@ public class MongoRealmProvider implements RealmProvider {
             return null;
         }
 
-        return new ApplicationAdapter(session, realm, appData, invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
-        MongoOAuthClientEntity clientEntity = getMongoStore().loadEntity(MongoOAuthClientEntity.class, id, invocationContext);
-
-        // Check if client belongs to this realm
-        if (clientEntity == null || !realm.getId().equals(clientEntity.getRealmId())) return null;
-
-        return new OAuthClientAdapter(session, realm, clientEntity, invocationContext);
+        return new ClientAdapter(session, realm, appData, invocationContext);
     }
 
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
index bcae24d..862e387 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
@@ -5,7 +5,7 @@ import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.MongoStore;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.CredentialValidationOutput;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.KeycloakSession;
@@ -249,7 +249,7 @@ public class MongoUserProvider implements UserProvider {
                 userModel.grantRole(realm.getRole(r));
             }
 
-            for (ApplicationModel application : realm.getApplications()) {
+            for (ClientModel application : realm.getClients()) {
                 for (String r : application.getDefaultRoles()) {
                     userModel.grantRole(application.getRole(r));
                 }
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 eac9583..dcc73ad 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
@@ -4,12 +4,10 @@ import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.enums.SslRequired;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderMapperModel;
 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.RealmProvider;
@@ -21,7 +19,6 @@ import org.keycloak.models.entities.IdentityProviderMapperEntity;
 import org.keycloak.models.entities.RequiredCredentialEntity;
 import org.keycloak.models.entities.UserFederationProviderEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -579,80 +576,59 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public ClientModel findClient(String clientId) {
-        ClientModel model = getApplicationByName(clientId);
-        if (model != null) return model;
-        return getOAuthClient(clientId);
+    public ClientModel getClientById(String id) {
+        return model.getClientById(id, this);
     }
 
     @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) {
+    public ClientModel getClientByClientId(String clientId) {
         DBObject query = new QueryBuilder()
                 .and("realmId").is(getId())
-                .and("name").is(name)
+                .and("name").is(clientId)
                 .get();
         MongoApplicationEntity appEntity = getMongoStore().loadSingleEntity(MongoApplicationEntity.class, query, invocationContext);
-        return appEntity == null ? null : new ApplicationAdapter(session, this, appEntity, invocationContext);
+        return appEntity == null ? null : new ClientAdapter(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);
+    public Map<String, ClientModel> getClientNameMap() {
+        Map<String, ClientModel> resourceMap = new HashMap<String, ClientModel>();
+        for (ClientModel resource : getClients()) {
+            resourceMap.put(resource.getClientId(), resource);
         }
         return resourceMap;
     }
 
     @Override
-    public List<ApplicationModel> getApplications() {
+    public List<ClientModel> getClients() {
         DBObject query = new QueryBuilder()
                 .and("realmId").is(getId())
                 .get();
         List<MongoApplicationEntity> appDatas = getMongoStore().loadEntities(MongoApplicationEntity.class, query, invocationContext);
 
-        List<ApplicationModel> result = new ArrayList<ApplicationModel>();
+        List<ClientModel> result = new ArrayList<ClientModel>();
         for (MongoApplicationEntity appData : appDatas) {
-            result.add(new ApplicationAdapter(session, this, appData, invocationContext));
+            result.add(new ClientAdapter(session, this, appData, invocationContext));
         }
         return result;
     }
 
     @Override
-    public ApplicationModel addApplication(String name) {
-        return this.addApplication(null, name);
+    public ClientModel addClient(String name) {
+        return this.addClient(null, name);
     }
 
     @Override
-    public ApplicationModel addApplication(String id, String name) {
+    public ClientModel addClient(String id, String clientId) {
         MongoApplicationEntity appData = new MongoApplicationEntity();
         appData.setId(id);
-        appData.setName(name);
+        appData.setName(clientId);
         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;
-            }
-
+        final ClientModel model = new ClientAdapter(session, this, appData, invocationContext);
+        session.getKeycloakSessionFactory().publish(new ClientCreationEvent() {
             @Override
             public ClientModel getCreatedClient() {
                 return model;
@@ -662,72 +638,11 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public boolean removeApplication(String id) {
+    public boolean removeClient(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());
@@ -1063,13 +978,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public ApplicationModel getMasterAdminApp() {
+    public ClientModel getMasterAdminApp() {
         MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(), invocationContext);
-        return appData != null ? new ApplicationAdapter(session, this, appData, invocationContext) : null;
+        return appData != null ? new ClientAdapter(session, this, appData, invocationContext) : null;
     }
 
     @Override
-    public void setMasterAdminApp(ApplicationModel app) {
+    public void setMasterAdminApp(ClientModel app) {
         String adminAppId = app != null ? app.getId() : null;
         realm.setAdminAppId(adminAppId);
         updateRealm();
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
index c2a8317..b38410e 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
@@ -115,12 +115,12 @@ public class RoleAdapter extends AbstractMongoAdapter<MongoRoleEntity> implement
                     throw new IllegalStateException("Realm with id: " + role.getRealmId() + " doesn't exists");
                 }
                 roleContainer = new RealmAdapter(session, realm, invocationContext);
-            } else if (role.getApplicationId() != null) {
-                MongoApplicationEntity appEntity = getMongoStore().loadEntity(MongoApplicationEntity.class, role.getApplicationId(), invocationContext);
+            } else if (role.getClientId() != null) {
+                MongoApplicationEntity appEntity = getMongoStore().loadEntity(MongoApplicationEntity.class, role.getClientId(), invocationContext);
                 if (appEntity == null) {
-                    throw new IllegalStateException("Application with id: " + role.getApplicationId() + " doesn't exists");
+                    throw new IllegalStateException("Application with id: " + role.getClientId() + " doesn't exists");
                 }
-                roleContainer = new ApplicationAdapter(session, realm, appEntity, invocationContext);
+                roleContainer = new ClientAdapter(session, realm, appEntity, invocationContext);
             } else {
                 throw new IllegalStateException("Both realmId and applicationId are null for role: " + this);
             }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
index da26379..6e7994a 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
@@ -1,7 +1,7 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
@@ -316,12 +316,12 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
     }
 
     @Override
-    public Set<RoleModel> getApplicationRoleMappings(ApplicationModel app) {
+    public Set<RoleModel> getApplicationRoleMappings(ClientModel app) {
         Set<RoleModel> result = new HashSet<RoleModel>();
         List<MongoRoleEntity> roles = MongoModelUtils.getAllRolesOfUser(this, invocationContext);
 
         for (MongoRoleEntity role : roles) {
-            if (app.getId().equals(role.getApplicationId())) {
+            if (app.getId().equals(role.getClientId())) {
                 result.add(new RoleAdapter(session, realm, role, app, invocationContext));
             }
         }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java
index 2784352..d873ea2 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java
@@ -27,8 +27,5 @@ public class MongoRealmEntity extends RealmEntity implements MongoIdentifiableEn
 
         // Remove all applications of this realm
         context.getMongoStore().removeEntities(MongoApplicationEntity.class, query, context);
-
-        // Remove all clients of this realm
-        context.getMongoStore().removeEntities(MongoOAuthClientEntity.class, query, context);
     }
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java
index 4b4e80f..a889670 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java
@@ -24,7 +24,7 @@ public class MongoRoleEntity extends RoleEntity implements MongoIdentifiableEnti
     // TODO This is required as Mongo doesn't support sparse indexes with compound keys (see https://jira.mongodb.org/browse/SERVER-2193)
     public String getNameIndex() {
         String realmId = getRealmId();
-        String applicationId = getApplicationId();
+        String applicationId = getClientId();
         String name = getName();
 
         if (realmId != null) {
@@ -74,8 +74,8 @@ public class MongoRoleEntity extends RoleEntity implements MongoIdentifiableEnti
         }
 
         // Remove defaultRoles from application
-        if (getApplicationId() != null) {
-            MongoApplicationEntity appEntity = mongoStore.loadEntity(MongoApplicationEntity.class, getApplicationId(), invContext);
+        if (getClientId() != null) {
+            MongoApplicationEntity appEntity = mongoStore.loadEntity(MongoApplicationEntity.class, getClientId(), invContext);
 
             // Application might be already removed at this point
             if (appEntity != null) {
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java
index 63f0bfd..641d469 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java
@@ -5,7 +5,7 @@ import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.entities.ClientEntity;
+import org.keycloak.models.entities.ApplicationEntity;
 import org.keycloak.models.mongo.keycloak.adapters.ClientAdapter;
 import org.keycloak.models.mongo.keycloak.adapters.UserAdapter;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
@@ -36,7 +36,7 @@ public class MongoModelUtils {
 
     // Get everything including both application and realm scopes
     public static List<MongoRoleEntity> getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) {
-        ClientEntity scopedEntity = ((ClientAdapter)client).getMongoEntityAsClient();
+        ApplicationEntity scopedEntity = ((ClientAdapter)client).getMongoEntity();
         List<String> scopeIds = scopedEntity.getScopeIds();
 
         if (scopeIds == null || scopeIds.isEmpty()) {
diff --git a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/ClientSessionAdapter.java b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/ClientSessionAdapter.java
index 645a76f..e380441 100644
--- a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/ClientSessionAdapter.java
+++ b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/ClientSessionAdapter.java
@@ -43,7 +43,7 @@ public class ClientSessionAdapter implements ClientSessionModel {
 
     @Override
     public ClientModel getClient() {
-        return realm.findClientById(entity.getClient());
+        return realm.getClientById(entity.getClient());
     }
 
     @Override
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java
index 18b0332..ebb47b6 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java
@@ -82,7 +82,7 @@ public class ClientSessionAdapter implements ClientSessionModel {
 
     @Override
     public ClientModel getClient() {
-        return realm.findClientById(entity.getClientId());
+        return realm.getClientById(entity.getClientId());
     }
 
     @Override
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
index d70c326..0731de3 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
@@ -20,7 +20,6 @@ import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java
index 9981fb7..62a3246 100755
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java
@@ -41,7 +41,7 @@ public class ClientSessionAdapter implements ClientSessionModel {
 
     @Override
     public ClientModel getClient() {
-        return realm.findClientById(entity.getClientId());
+        return realm.getClientById(entity.getClientId());
     }
 
     @Override
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
index c185a0b..67a2180 100755
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
@@ -25,7 +25,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/ClientSessionAdapter.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/ClientSessionAdapter.java
index 2ab8630..12efd4a 100755
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/ClientSessionAdapter.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/ClientSessionAdapter.java
@@ -44,7 +44,7 @@ public class ClientSessionAdapter extends AbstractMongoAdapter<MongoClientSessio
 
     @Override
     public ClientModel getClient() {
-        return realm.findClientById(entity.getClientId());
+        return realm.getClientById(entity.getClientId());
     }
 
     @Override
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterService.java
index 68a7412..4ef05ea 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterService.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/EntityDescriptorImporterService.java
@@ -2,7 +2,7 @@ package org.keycloak.protocol.saml;
 
 import org.jboss.resteasy.plugins.providers.multipart.InputPart;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.services.resources.admin.RealmAuth;
@@ -79,7 +79,7 @@ public class EntityDescriptorImporterService {
         for (Object o : entities.getEntityDescriptor()) {
             EntityDescriptorType entity = (EntityDescriptorType)o;
             String entityId = entity.getEntityID();
-            ApplicationModel app = realm.addApplication(entityId);
+            ClientModel app = realm.addClient(entityId);
             app.setFullScopeAllowed(true);
             app.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
             app.setAttribute(SamlProtocol.SAML_SERVER_SIGNATURE, SamlProtocol.ATTRIBUTE_TRUE_VALUE); // default to true
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/RoleNameMapper.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/RoleNameMapper.java
index adde0b8..b9deb24 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/RoleNameMapper.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/mappers/RoleNameMapper.java
@@ -1,6 +1,6 @@
 package org.keycloak.protocol.saml.mappers;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
@@ -72,9 +72,9 @@ public class RoleNameMapper extends AbstractOIDCProtocolMapper implements SAMLRo
     @Override
     public String mapName(ProtocolMapperModel model, RoleModel roleModel) {
         RoleContainerModel container = roleModel.getContainer();
-        ApplicationModel app = null;
-        if (container instanceof ApplicationModel) {
-            app = ((ApplicationModel) container);
+        ClientModel app = null;
+        if (container instanceof ClientModel) {
+            app = ((ClientModel) container);
         }
         String role = model.getConfig().get(ROLE_CONFIG);
         String newName = model.getConfig().get(NEW_ROLE_NAME);
@@ -83,7 +83,7 @@ public class RoleNameMapper extends AbstractOIDCProtocolMapper implements SAMLRo
         if (scopeIndex > -1) {
             if (app == null) return null;
             appName = role.substring(0, scopeIndex);
-            if (!app.getName().equals(appName)) return null;
+            if (!app.getClientId().equals(appName)) return null;
             role = role.substring(scopeIndex + 1);
         } else {
             if (app != null) return null;
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index 3c3ada6..b38d5b9 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -4,8 +4,10 @@ import org.jboss.logging.Logger;
 import org.jboss.resteasy.client.ClientRequest;
 import org.jboss.resteasy.client.ClientResponse;
 import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
+import org.keycloak.dom.saml.v2.protocol.ResponseType;
 import org.keycloak.events.EventBuilder;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
@@ -18,20 +20,17 @@ import org.keycloak.protocol.ProtocolMapper;
 import org.keycloak.protocol.saml.mappers.SAMLAttributeStatementMapper;
 import org.keycloak.protocol.saml.mappers.SAMLLoginResponseMapper;
 import org.keycloak.protocol.saml.mappers.SAMLRoleListMapper;
+import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
+import org.keycloak.saml.common.exceptions.ConfigurationException;
+import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.exceptions.ProcessingException;
 import org.keycloak.services.managers.ClientSessionCode;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.admin.ClientAttributeCertificateResource;
 import org.keycloak.services.resources.flows.Flows;
-import org.keycloak.saml.common.constants.GeneralConstants;
-import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
-import org.keycloak.saml.common.exceptions.ConfigurationException;
-import org.keycloak.saml.common.exceptions.ParsingException;
-import org.keycloak.saml.common.exceptions.ProcessingException;
-import org.keycloak.dom.saml.v2.assertion.AssertionType;
-import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
-import org.keycloak.dom.saml.v2.protocol.ResponseType;
 import org.w3c.dom.Document;
 
 import javax.ws.rs.core.HttpHeaders;
@@ -429,7 +428,7 @@ public class SamlProtocol implements LoginProtocol {
         } else {
             logoutServiceUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);
         }
-        if (logoutServiceUrl == null && client instanceof ApplicationModel) logoutServiceUrl = ((ApplicationModel)client).getManagementUrl();
+        if (logoutServiceUrl == null && client instanceof ClientModel) logoutServiceUrl = ((ClientModel)client).getManagementUrl();
         if (logoutServiceUrl == null || logoutServiceUrl.trim().equals("")) return null;
         return ResourceAdminManager.resolveUri(uriInfo.getRequestUri(), logoutServiceUrl);
 
@@ -438,7 +437,7 @@ public class SamlProtocol implements LoginProtocol {
     @Override
     public Response frontchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) {
         ClientModel client = clientSession.getClient();
-        if (!(client instanceof ApplicationModel)) return null;
+        if (!(client instanceof ClientModel)) return null;
         try {
             if (isLogoutPostBindingForClient(clientSession)) {
                 String bindingUri = getLogoutServiceUrl(uriInfo, client, SAML_POST_BINDING);
@@ -500,8 +499,6 @@ public class SamlProtocol implements LoginProtocol {
     @Override
     public void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) {
         ClientModel client = clientSession.getClient();
-        if (!(client instanceof ApplicationModel)) return;
-        ApplicationModel app = (ApplicationModel)client;
         String logoutUrl = getLogoutServiceUrl(uriInfo, client, SAML_POST_BINDING);
         if (logoutUrl == null) {
             logger.warnv("Can't do backchannel logout. No SingleLogoutService POST Binding registered for client: {1}", client.getClientId());
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
index 6a4c313..11007c8 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
@@ -2,11 +2,11 @@ package org.keycloak.protocol.saml;
 
 import org.keycloak.VerificationException;
 import org.keycloak.models.ClientModel;
-import org.keycloak.util.PemUtils;
 import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.exceptions.ProcessingException;
 import org.keycloak.saml.processing.api.saml.v2.sig.SAML2Signature;
 import org.keycloak.saml.processing.web.util.RedirectBindingUtil;
+import org.keycloak.util.PemUtils;
 import org.w3c.dom.Document;
 
 import javax.ws.rs.core.MultivaluedMap;
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
index b6dfebb..3b1ff99 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java
@@ -11,7 +11,6 @@ import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
 import org.keycloak.login.LoginFormsProvider;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
@@ -165,7 +164,7 @@ public class SamlService {
 
             RequestAbstractType requestAbstractType = (RequestAbstractType)samlObject;
             String issuer = requestAbstractType.getIssuer().getValue();
-            ClientModel client = realm.findClient(issuer);
+            ClientModel client = realm.getClientByClientId(issuer);
 
             if (client == null) {
                 event.event(EventType.LOGIN);
@@ -178,7 +177,7 @@ public class SamlService {
                 event.error(Errors.CLIENT_DISABLED);
                 return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
             }
-            if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
+            if ((client instanceof ClientModel) && ((ClientModel)client).isBearerOnly()) {
                 event.event(EventType.LOGIN);
                 event.error(Errors.NOT_ALLOWED);
                 return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.BEARER_ONLY);
@@ -241,8 +240,8 @@ public class SamlService {
                 } else {
                     redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
                 }
-                if (redirect == null && client instanceof ApplicationModel) {
-                    redirect = ((ApplicationModel)client).getManagementUrl();
+                if (redirect == null && client instanceof ClientModel) {
+                    redirect = ((ClientModel)client).getManagementUrl();
                 }
 
             }
@@ -368,8 +367,8 @@ public class SamlService {
 
             String redirectUri = null;
 
-            if (client instanceof ApplicationModel) {
-                redirectUri = ((ApplicationModel)client).getBaseUrl();
+            if (client instanceof ClientModel) {
+                redirectUri = ((ClientModel)client).getBaseUrl();
             }
 
             if (redirectUri != null) {
@@ -404,7 +403,6 @@ public class SamlService {
 
     protected class PostBindingProtocol extends BindingProtocol {
 
-
         @Override
         protected void verifySignature(SAMLDocumentHolder documentHolder, ClientModel client) throws VerificationException {
             SamlProtocolUtils.verifyDocumentSignature(client, documentHolder.getSamlDocument());
diff --git a/services/src/main/java/org/keycloak/protocol/AbstractLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/AbstractLoginProtocolFactory.java
index f009c6b..aa86a26 100755
--- a/services/src/main/java/org/keycloak/protocol/AbstractLoginProtocolFactory.java
+++ b/services/src/main/java/org/keycloak/protocol/AbstractLoginProtocolFactory.java
@@ -1,24 +1,18 @@
 package org.keycloak.protocol;
 
-import org.jboss.logging.Logger;
 import org.keycloak.Config;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
 import org.keycloak.provider.ProviderEvent;
 import org.keycloak.provider.ProviderEventListener;
 
-import java.util.List;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public abstract class AbstractLoginProtocolFactory implements LoginProtocolFactory {
 
-    private static final Logger logger = Logger.getLogger(AbstractLoginProtocolFactory.class);
-
     @Override
     public void init(Config.Scope config) {
     }
@@ -34,8 +28,6 @@ public abstract class AbstractLoginProtocolFactory implements LoginProtocolFacto
                 }
             }
         });
-
-
     }
 
     protected abstract void addDefaults(ClientModel realm);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
index dfe6b2f..e33cb67 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
@@ -11,7 +11,6 @@ import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
 import org.keycloak.login.LoginFormsProvider;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.IdentityProviderModel;
@@ -168,13 +167,13 @@ public class AuthorizationEndpoint {
 
         event.client(clientId);
 
-        client = realm.findClient(clientId);
+        client = realm.getClientByClientId(clientId);
         if (client == null) {
             event.error(Errors.CLIENT_NOT_FOUND);
             throw new ErrorPageException(session, realm, uriInfo, headers, Messages.CLIENT_NOT_FOUND );
         }
 
-        if ((client instanceof ApplicationModel) && ((ApplicationModel) client).isBearerOnly()) {
+        if ((client instanceof ClientModel) && ((ClientModel) client).isBearerOnly()) {
             event.error(Errors.NOT_ALLOWED);
             throw new ErrorPageException(session, realm, uriInfo, headers, Messages.BEARER_ONLY );
         }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java
index 30359d1..156ee44 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java
@@ -42,7 +42,7 @@ public class LoginStatusIframeEndpoint {
             throw new BadRequestException("Invalid origin");
         }
 
-        ClientModel client = realm.findClient(client_id);
+        ClientModel client = realm.getClientByClientId(client_id);
         if (client == null) {
             throw new NotFoundException("could not find client");
         }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java
index a61c811..582de38 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java
@@ -10,7 +10,6 @@ import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -191,7 +190,7 @@ public class LogoutEndpoint {
     private ClientModel authorizeClient(String authorizationHeader, MultivaluedMap<String, String> formData, EventBuilder event) {
         ClientModel client = AuthorizeClientUtil.authorizeClient(authorizationHeader, formData, event, realm);
 
-        if ( (client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
+        if ( (client instanceof ClientModel) && ((ClientModel)client).isBearerOnly()) {
             throw new ErrorResponseException("invalid_client", "Bearer-only not allowed", Response.Status.BAD_REQUEST);
         }
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
index bd211e4..331dbec 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
@@ -10,7 +10,6 @@ import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
@@ -20,7 +19,6 @@ import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.protocol.oidc.utils.AuthorizeClientUtil;
 import org.keycloak.representations.AccessToken;
@@ -31,7 +29,6 @@ import org.keycloak.services.managers.ClientSessionCode;
 import org.keycloak.services.resources.Cors;
 import org.keycloak.services.resources.flows.Urls;
 
-import javax.ws.rs.Consumes;
 import javax.ws.rs.OPTIONS;
 import javax.ws.rs.POST;
 import javax.ws.rs.core.Context;
@@ -147,7 +144,7 @@ public class TokenEndpoint {
         String authorizationHeader = headers.getRequestHeaders().getFirst(HttpHeaders.AUTHORIZATION);
         client = AuthorizeClientUtil.authorizeClient(authorizationHeader, formParams, event, realm);
 
-        if ((client instanceof ApplicationModel) && ((ApplicationModel) client).isBearerOnly()) {
+        if ((client instanceof ClientModel) && ((ClientModel) client).isBearerOnly()) {
             throw new ErrorResponseException("invalid_client", "Bearer-only not allowed", Response.Status.BAD_REQUEST);
         }
     }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
index e4f5c41..ba2f99c 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java
@@ -122,7 +122,7 @@ public class UserInfoEndpoint {
         }
 
         UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState());
-        ClientModel clientModel = realm.findClient(token.getIssuedFor());
+        ClientModel clientModel = realm.getClientByClientId(token.getIssuedFor());
         UserModel userModel = userSession.getUser();
         AccessToken userInfo = new AccessToken();
         tokenManager.transformAccessToken(session, userInfo, realm, clientModel, userModel, userSession, null);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 5815037..88525db 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -27,7 +27,7 @@ import org.keycloak.OAuth2Constants;
 import org.keycloak.events.Details;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -164,8 +164,8 @@ public class OIDCLoginProtocol implements LoginProtocol {
 
     @Override
     public void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) {
-        if (!(clientSession.getClient() instanceof ApplicationModel)) return;
-        ApplicationModel app = (ApplicationModel)clientSession.getClient();
+        if (!(clientSession.getClient() instanceof ClientModel)) return;
+        ClientModel app = (ClientModel)clientSession.getClient();
         ApacheHttpClient4Executor executor = ResourceAdminManager.createExecutor();
 
         try {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index e21d091..6a27c55 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -8,7 +8,6 @@ import org.keycloak.events.EventBuilder;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.crypto.RSAProvider;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
@@ -233,8 +232,8 @@ public class TokenManager {
         if (client.isFullScopeAllowed()) return roleMappings;
 
         Set<RoleModel> scopeMappings = client.getScopeMappings();
-        if (client instanceof ApplicationModel) {
-            scopeMappings.addAll(((ApplicationModel) client).getRoles());
+        if (client instanceof ClientModel) {
+            scopeMappings.addAll(((ClientModel) client).getRoles());
         }
 
         for (RoleModel role : roleMappings) {
@@ -339,10 +338,10 @@ public class TokenManager {
                 return;
 
         } else {
-            ApplicationModel app = (ApplicationModel) role.getContainer();
-            access = token.getResourceAccess(app.getName());
+            ClientModel app = (ClientModel) role.getContainer();
+            access = token.getResourceAccess(app.getClientId());
             if (access == null) {
-                access = token.addAccess(app.getName());
+                access = token.addAccess(app.getClientId());
                 if (app.isSurrogateAuthRequired()) access.verifyCaller(true);
             } else if (access.isUserInRole(role.getName())) return;
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java
index 1a78b64..4b97c97 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/AuthorizeClientUtil.java
@@ -44,7 +44,7 @@ public class AuthorizeClientUtil {
 
         event.client(client_id);
 
-        ClientModel client = realm.findClient(client_id);
+        ClientModel client = realm.getClientByClientId(client_id);
         if (client == null) {
             Map<String, String> error = new HashMap<String, String>();
             error.put(OAuth2Constants.ERROR, "invalid_client");
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
index 2fa3aee..68da825 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java
@@ -1,10 +1,8 @@
 package org.keycloak.protocol.oidc.utils;
 
 import org.jboss.logging.Logger;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.services.resources.flows.Urls;
 
@@ -46,12 +44,7 @@ public class RedirectUtils {
 
     private static Set<String> getValidateRedirectUris(RealmModel realm) {
         Set<String> redirects = new HashSet<String>();
-        for (ApplicationModel client : realm.getApplications()) {
-            for (String redirect : client.getRedirectUris()) {
-                redirects.add(redirect);
-            }
-        }
-        for (OAuthClientModel client : realm.getOAuthClients()) {
+        for (ClientModel client : realm.getClients()) {
             for (String redirect : client.getRedirectUris()) {
                 redirects.add(redirect);
             }
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 96d97e3..3caa713 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -4,7 +4,7 @@ import org.jboss.logging.Logger;
 import org.keycloak.Config;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
@@ -71,7 +71,7 @@ public class ApplianceBootstrap {
         RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
         adminUser.grantRole(adminRole);
 
-        ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
+        ClientModel accountApp = realm.getClientNameMap().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/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index 5463f39..b7baf9a 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -3,7 +3,7 @@ package org.keycloak.services.managers;
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.annotate.JsonPropertyOrder;
 import org.jboss.logging.Logger;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -36,12 +36,12 @@ public class ApplicationManager {
     public ApplicationManager() {
     }
 
-    public ApplicationModel createApplication(RealmModel realm, String name) {
+    public ClientModel createApplication(RealmModel realm, String name) {
         return KeycloakModelUtils.createApplication(realm, name);
     }
 
-    public boolean removeApplication(RealmModel realm, ApplicationModel application) {
-        if (realm.removeApplication(application.getId())) {
+    public boolean removeApplication(RealmModel realm, ClientModel application) {
+        if (realm.removeClient(application.getId())) {
             UserSessionProvider sessions = realmManager.getSession().sessions();
             if (sessions != null) {
                 sessions.onClientRemoved(realm, application);
@@ -52,7 +52,7 @@ public class ApplicationManager {
         }
     }
 
-    public Set<String> validateRegisteredNodes(ApplicationModel application) {
+    public Set<String> validateRegisteredNodes(ClientModel application) {
         Map<String, Integer> registeredNodes = application.getRegisteredNodes();
         if (registeredNodes == null || registeredNodes.isEmpty()) {
             return Collections.emptySet();
@@ -141,22 +141,22 @@ public class ApplicationManager {
     }
 
 
-    public InstallationAdapterConfig toInstallationRepresentation(RealmModel realmModel, ApplicationModel applicationModel, URI baseUri) {
+    public InstallationAdapterConfig toInstallationRepresentation(RealmModel realmModel, ClientModel clientModel, URI baseUri) {
         InstallationAdapterConfig rep = new InstallationAdapterConfig();
         rep.setRealm(realmModel.getName());
         rep.setRealmKey(realmModel.getPublicKeyPem());
         rep.setSslRequired(realmModel.getSslRequired().name().toLowerCase());
 
-        if (applicationModel.isPublicClient() && !applicationModel.isBearerOnly()) rep.setPublicClient(true);
-        if (applicationModel.isBearerOnly()) rep.setBearerOnly(true);
-        if (!applicationModel.isBearerOnly()) rep.setAuthServerUrl(baseUri.toString());
-        if (applicationModel.getRoles().size() > 0) rep.setUseResourceRoleMappings(true);
+        if (clientModel.isPublicClient() && !clientModel.isBearerOnly()) rep.setPublicClient(true);
+        if (clientModel.isBearerOnly()) rep.setBearerOnly(true);
+        if (!clientModel.isBearerOnly()) rep.setAuthServerUrl(baseUri.toString());
+        if (clientModel.getRoles().size() > 0) rep.setUseResourceRoleMappings(true);
 
-        rep.setResource(applicationModel.getName());
+        rep.setResource(clientModel.getClientId());
 
-        if (!applicationModel.isBearerOnly() && !applicationModel.isPublicClient()) {
+        if (!clientModel.isBearerOnly() && !clientModel.isPublicClient()) {
             Map<String, String> creds = new HashMap<String, String>();
-            String cred = applicationModel.getSecret();
+            String cred = clientModel.getSecret();
             creds.put(CredentialRepresentation.SECRET, cred);
             rep.setCredentials(creds);
         }
@@ -164,27 +164,27 @@ public class ApplicationManager {
         return rep;
     }
 
-    public String toJBossSubsystemConfig(RealmModel realmModel, ApplicationModel applicationModel, URI baseUri) {
+    public String toJBossSubsystemConfig(RealmModel realmModel, ClientModel clientModel, URI baseUri) {
         StringBuffer buffer = new StringBuffer();
         buffer.append("<secure-deployment name=\"WAR MODULE NAME.war\">\n");
         buffer.append("    <realm>").append(realmModel.getName()).append("</realm>\n");
         buffer.append("    <realm-public-key>").append(realmModel.getPublicKeyPem()).append("</realm-public-key>\n");
-        if (applicationModel.isBearerOnly()){
+        if (clientModel.isBearerOnly()){
             buffer.append("    <bearer-only>true</bearer-only>\n");
 
         } else {
             buffer.append("    <auth-server-url>").append(baseUri.toString()).append("</auth-server-url>\n");
-            if (applicationModel.isPublicClient() && !applicationModel.isBearerOnly()) {
+            if (clientModel.isPublicClient() && !clientModel.isBearerOnly()) {
                 buffer.append("    <public-client>true</public-client>\n");
             }
         }
         buffer.append("    <ssl-required>").append(realmModel.getSslRequired().name()).append("</ssl-required>\n");
-        buffer.append("    <resource>").append(applicationModel.getName()).append("</resource>\n");
-        String cred = applicationModel.getSecret();
-        if (!applicationModel.isBearerOnly() && !applicationModel.isPublicClient()) {
+        buffer.append("    <resource>").append(clientModel.getClientId()).append("</resource>\n");
+        String cred = clientModel.getSecret();
+        if (!clientModel.isBearerOnly() && !clientModel.isPublicClient()) {
             buffer.append("    <credential name=\"secret\">").append(cred).append("</credential>\n");
         }
-        if (applicationModel.getRoles().size() > 0) {
+        if (clientModel.getRoles().size() > 0) {
             buffer.append("    <use-resource-role-mappings>true</use-resource-role-mappings>\n");
         }
         buffer.append("</secure-deployment>\n");
diff --git a/services/src/main/java/org/keycloak/services/managers/Auth.java b/services/src/main/java/org/keycloak/services/managers/Auth.java
index 1527ea5..ecaf0d9 100755
--- a/services/src/main/java/org/keycloak/services/managers/Auth.java
+++ b/services/src/main/java/org/keycloak/services/managers/Auth.java
@@ -1,6 +1,5 @@
 package org.keycloak.services.managers;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.RealmModel;
@@ -81,16 +80,16 @@ public class Auth {
         return false;
     }
 
-    public boolean hasAppRole(ApplicationModel app, String role) {
+    public boolean hasAppRole(ClientModel app, String role) {
         if (cookie) {
             return user.hasRole(app.getRole(role));
         } else {
-            AccessToken.Access access = token.getResourceAccess(app.getName());
+            AccessToken.Access access = token.getResourceAccess(app.getClientId());
             return access != null && access.isUserInRole(role);
         }
     }
 
-    public boolean hasOneOfAppRole(ApplicationModel app, String... roles) {
+    public boolean hasOneOfAppRole(ClientModel app, String... roles) {
         for (String r : roles) {
             if (hasAppRole(app, r)) {
                 return true;
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 8ebcf74..8cd9483 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -12,7 +12,6 @@ import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.login.LoginFormsProvider;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
@@ -111,7 +110,7 @@ public class AuthenticationManager {
 
         for (ClientSessionModel clientSession : userSession.getClientSessions()) {
             ClientModel client = clientSession.getClient();
-            if (client instanceof ApplicationModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) {
+            if (client instanceof ClientModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) {
                 String authMethod = clientSession.getAuthMethod();
                 if (authMethod == null) continue; // must be a keycloak service like account
                 LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
@@ -145,7 +144,7 @@ public class AuthenticationManager {
                 redirectClients.add(clientSession);
                 continue;
             }
-            if (client instanceof ApplicationModel && !client.isFrontchannelLogout()) {
+            if (client instanceof ClientModel && !client.isFrontchannelLogout()) {
                 String authMethod = clientSession.getAuthMethod();
                 if (authMethod == null) continue; // must be a keycloak service like account
                 LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
@@ -381,13 +380,9 @@ public class AuthenticationManager {
         isEmailVerificationRequired(realm, user);
         ClientModel client = clientSession.getClient();
 
-        boolean isResource = client instanceof ApplicationModel;
         ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession);
 
-
-        logger.debugv("processAccessCode: isResource: {0}", isResource);
-        logger.debugv("processAccessCode: go to oauth page?: {0}",
-                !isResource);
+        logger.debugv("processAccessCode: go to oauth page?: {0}", client.isConsentRequired());
 
         event.detail(Details.CODE_ID, clientSession.getId());
 
@@ -417,7 +412,7 @@ public class AuthenticationManager {
             }
         }
 
-        if (!isResource) {
+        if (client.isConsentRequired()) {
             accessCode.setAction(ClientSessionModel.Action.OAUTH_GRANT);
 
             List<RoleModel> realmRoles = new LinkedList<RoleModel>();
@@ -426,7 +421,7 @@ public class AuthenticationManager {
                 if (r.getContainer() instanceof RealmModel) {
                     realmRoles.add(r);
                 } else {
-                    resourceRoles.add(((ApplicationModel) r.getContainer()).getName(), r);
+                    resourceRoles.add(((ClientModel) r.getContainer()).getClientId(), r);
                 }
             }
 
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 138b0e4..f372bbd 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -6,7 +6,7 @@ import org.keycloak.enums.SslRequired;
 import org.keycloak.exportimport.util.ImportUtils;
 import org.keycloak.models.AccountRoles;
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.BrowserSecurityHeaders;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -25,7 +25,6 @@ import org.keycloak.timer.TimerProvider;
 
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -91,7 +90,7 @@ public class RealmManager {
     }
 
     protected void setupAdminConsole(RealmModel realm) {
-        ApplicationModel adminConsole = realm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+        ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
         if (adminConsole == null) adminConsole = new ApplicationManager(this).createApplication(realm, Constants.ADMIN_CONSOLE_APPLICATION);
         String baseUrl = contextPath + "/admin/" + realm.getName() + "/console";
         adminConsole.setBaseUrl(baseUrl + "/index.html");
@@ -105,7 +104,7 @@ public class RealmManager {
             adminRole = realm.getRole(AdminRoles.ADMIN);
         } else {
             String realmAdminApplicationName = getRealmAdminApplicationName(realm);
-            ApplicationModel realmAdminApp = realm.getApplicationByName(realmAdminApplicationName);
+            ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName);
             adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
         }
         adminConsole.addScopeMapping(adminRole);
@@ -178,7 +177,7 @@ public class RealmManager {
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
 
         String realmAdminApplicationName = getRealmAdminApplicationName(realm);
-        ApplicationModel realmAdminApp = realm.getApplicationByName(realmAdminApplicationName);
+        ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationName);
         if (realmAdminApp == null) {
             realmAdminApp = applicationManager.createApplication(realm, realmAdminApplicationName);
         }
@@ -196,7 +195,7 @@ public class RealmManager {
 
 
     private void setupAccountManagement(RealmModel realm) {
-        ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
+        ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
         if (application == null) {
             application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_MANAGEMENT_APP);
             application.setEnabled(true);
diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
index 1bd7fdc..5c4e443 100755
--- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
@@ -7,7 +7,6 @@ import org.jboss.resteasy.client.ClientResponse;
 import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
 import org.keycloak.TokenIdGenerator;
 import org.keycloak.constants.AdapterConstants;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
@@ -58,7 +57,7 @@ public class ResourceAdminManager {
 
    }
 
-    public static String getManagementUrl(URI requestUri, ApplicationModel application) {
+    public static String getManagementUrl(URI requestUri, ClientModel application) {
         String mgmtUrl = application.getManagementUrl();
         if (mgmtUrl == null || mgmtUrl.equals("")) {
             return null;
@@ -73,7 +72,7 @@ public class ResourceAdminManager {
 
     // For non-cluster setup, return just single configured managementUrls
     // For cluster setup, return the management Urls corresponding to all registered cluster nodes
-    private List<String> getAllManagementUrls(URI requestUri, ApplicationModel application) {
+    private List<String> getAllManagementUrls(URI requestUri, ClientModel application) {
         String baseMgmtUrl = getManagementUrl(requestUri, application);
         if (baseMgmtUrl == null) {
             return Collections.emptyList();
@@ -106,7 +105,7 @@ public class ResourceAdminManager {
 
         try {
             // Map from "app" to clientSessions for this app
-            MultivaluedHashMap<ApplicationModel, ClientSessionModel> clientSessions = new MultivaluedHashMap<ApplicationModel, ClientSessionModel>();
+            MultivaluedHashMap<ClientModel, ClientSessionModel> clientSessions = new MultivaluedHashMap<ClientModel, ClientSessionModel>();
             for (UserSessionModel userSession : userSessions) {
                 putClientSessions(clientSessions, userSession);
             }
@@ -114,7 +113,7 @@ public class ResourceAdminManager {
             logger.debugv("logging out {0} resources ", clientSessions.size());
             //logger.infov("logging out resources: {0}", clientSessions);
 
-            for (Map.Entry<ApplicationModel, List<ClientSessionModel>> entry : clientSessions.entrySet()) {
+            for (Map.Entry<ClientModel, List<ClientSessionModel>> entry : clientSessions.entrySet()) {
                 logoutClientSessions(requestUri, realm, entry.getKey(), entry.getValue(), executor);
             }
         } finally {
@@ -122,23 +121,21 @@ public class ResourceAdminManager {
         }
     }
 
-    private void putClientSessions(MultivaluedHashMap<ApplicationModel, ClientSessionModel> clientSessions, UserSessionModel userSession) {
+    private void putClientSessions(MultivaluedHashMap<ClientModel, ClientSessionModel> clientSessions, UserSessionModel userSession) {
         for (ClientSessionModel clientSession : userSession.getClientSessions()) {
             ClientModel client = clientSession.getClient();
-            if (client instanceof ApplicationModel) {
-                clientSessions.add((ApplicationModel)client, clientSession);
-            }
+            clientSessions.add(client, clientSession);
         }
     }
 
-    public void logoutUserFromApplication(URI requestUri, RealmModel realm, ApplicationModel resource, UserModel user, KeycloakSession session) {
+    public void logoutUserFromApplication(URI requestUri, RealmModel realm, ClientModel resource, UserModel user, KeycloakSession session) {
         ApacheHttpClient4Executor executor = createExecutor();
 
         try {
             List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
             List<ClientSessionModel> ourAppClientSessions = null;
             if (userSessions != null) {
-                MultivaluedHashMap<ApplicationModel, ClientSessionModel> clientSessions = new MultivaluedHashMap<ApplicationModel, ClientSessionModel>();
+                MultivaluedHashMap<ClientModel, ClientSessionModel> clientSessions = new MultivaluedHashMap<ClientModel, ClientSessionModel>();
                 for (UserSessionModel userSession : userSessions) {
                     putClientSessions(clientSessions, userSession);
                 }
@@ -152,11 +149,11 @@ public class ResourceAdminManager {
 
     }
 
-    public boolean logoutClientSession(URI requestUri, RealmModel realm, ApplicationModel resource, ClientSessionModel clientSession, ApacheHttpClient4Executor client) {
+    public boolean logoutClientSession(URI requestUri, RealmModel realm, ClientModel resource, ClientSessionModel clientSession, ApacheHttpClient4Executor client) {
         return logoutClientSessions(requestUri, realm, resource, Arrays.asList(clientSession), client);
     }
 
-    protected boolean logoutClientSessions(URI requestUri, RealmModel realm, ApplicationModel resource, List<ClientSessionModel> clientSessions, ApacheHttpClient4Executor client) {
+    protected boolean logoutClientSessions(URI requestUri, RealmModel realm, ClientModel resource, List<ClientSessionModel> clientSessions, ApacheHttpClient4Executor client) {
         String managementUrl = getManagementUrl(requestUri, resource);
         if (managementUrl != null) {
 
@@ -176,7 +173,7 @@ public class ResourceAdminManager {
             }
 
             if (adapterSessionIds == null || adapterSessionIds.isEmpty()) {
-                logger.debugv("Can't logout {0}: no logged adapter sessions", resource.getName());
+                logger.debugv("Can't logout {0}: no logged adapter sessions", resource.getClientId());
                 return false;
             }
 
@@ -201,7 +198,7 @@ public class ResourceAdminManager {
                 return sendLogoutRequest(realm, resource, allSessionIds, userSessions, client, 0, managementUrl);
             }
         } else {
-            logger.debugv("Can't logout {0}: no management url", resource.getName());
+            logger.debugv("Can't logout {0}: no management url", resource.getClientId());
             return false;
         }
     }
@@ -213,11 +210,11 @@ public class ResourceAdminManager {
 
         try {
             realm.setNotBefore(Time.currentTime());
-            List<ApplicationModel> resources = realm.getApplications();
+            List<ClientModel> resources = realm.getClients();
             logger.debugv("logging out {0} resources ", resources.size());
 
             GlobalRequestResult finalResult = new GlobalRequestResult();
-            for (ApplicationModel resource : resources) {
+            for (ClientModel resource : resources) {
                 GlobalRequestResult currentResult = logoutApplication(requestUri, realm, resource, executor, realm.getNotBefore());
                 finalResult.addAll(currentResult);
             }
@@ -227,7 +224,7 @@ public class ResourceAdminManager {
         }
     }
 
-    public GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ApplicationModel resource) {
+    public GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ClientModel resource) {
         ApacheHttpClient4Executor executor = createExecutor();
         try {
             resource.setNotBefore(Time.currentTime());
@@ -238,10 +235,10 @@ public class ResourceAdminManager {
     }
 
 
-    protected GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ApplicationModel resource, ApacheHttpClient4Executor executor, int notBefore) {
+    protected GlobalRequestResult logoutApplication(URI requestUri, RealmModel realm, ClientModel resource, ApacheHttpClient4Executor executor, int notBefore) {
         List<String> mgmtUrls = getAllManagementUrls(requestUri, resource);
         if (mgmtUrls.isEmpty()) {
-            logger.debug("No management URL or no registered cluster nodes for the application " + resource.getName());
+            logger.debug("No management URL or no registered cluster nodes for the application " + resource.getClientId());
             return new GlobalRequestResult();
         }
 
@@ -259,16 +256,16 @@ public class ResourceAdminManager {
         return result;
     }
 
-    protected boolean sendLogoutRequest(RealmModel realm, ApplicationModel resource, List<String> adapterSessionIds, List<String> userSessions, ApacheHttpClient4Executor client, int notBefore, String managementUrl) {
-        LogoutAction adminAction = new LogoutAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getName(), adapterSessionIds, notBefore, userSessions);
+    protected boolean sendLogoutRequest(RealmModel realm, ClientModel resource, List<String> adapterSessionIds, List<String> userSessions, ApacheHttpClient4Executor client, int notBefore, String managementUrl) {
+        LogoutAction adminAction = new LogoutAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getClientId(), adapterSessionIds, notBefore, userSessions);
         String token = new TokenManager().encodeToken(realm, adminAction);
-        if (logger.isDebugEnabled()) logger.debugv("logout resource {0} url: {1} sessionIds: " + adapterSessionIds, resource.getName(), managementUrl);
+        if (logger.isDebugEnabled()) logger.debugv("logout resource {0} url: {1} sessionIds: " + adapterSessionIds, resource.getClientId(), managementUrl);
         ClientRequest request = client.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_LOGOUT).build().toString());
         ClientResponse response;
         try {
             response = request.body(MediaType.TEXT_PLAIN_TYPE, token).post();
         } catch (Exception e) {
-            logger.warn("Logout for application '" + resource.getName() + "' failed", e);
+            logger.warn("Logout for application '" + resource.getClientId() + "' failed", e);
             return false;
         }
         try {
@@ -285,7 +282,7 @@ public class ResourceAdminManager {
 
         try {
             GlobalRequestResult finalResult = new GlobalRequestResult();
-            for (ApplicationModel application : realm.getApplications()) {
+            for (ClientModel application : realm.getClients()) {
                 GlobalRequestResult currentResult = pushRevocationPolicy(requestUri, realm, application, realm.getNotBefore(), executor);
                 finalResult.addAll(currentResult);
             }
@@ -295,7 +292,7 @@ public class ResourceAdminManager {
         }
     }
 
-    public GlobalRequestResult pushApplicationRevocationPolicy(URI requestUri, RealmModel realm, ApplicationModel application) {
+    public GlobalRequestResult pushApplicationRevocationPolicy(URI requestUri, RealmModel realm, ClientModel application) {
         ApacheHttpClient4Executor executor = createExecutor();
 
         try {
@@ -306,10 +303,10 @@ public class ResourceAdminManager {
     }
 
 
-    protected GlobalRequestResult pushRevocationPolicy(URI requestUri, RealmModel realm, ApplicationModel resource, int notBefore, ApacheHttpClient4Executor executor) {
+    protected GlobalRequestResult pushRevocationPolicy(URI requestUri, RealmModel realm, ClientModel resource, int notBefore, ApacheHttpClient4Executor executor) {
         List<String> mgmtUrls = getAllManagementUrls(requestUri, resource);
         if (mgmtUrls.isEmpty()) {
-            logger.debugf("No management URL or no registered cluster nodes for the application %s", resource.getName());
+            logger.debugf("No management URL or no registered cluster nodes for the application %s", resource.getClientId());
             return new GlobalRequestResult();
         }
 
@@ -327,10 +324,10 @@ public class ResourceAdminManager {
         return result;
     }
 
-    protected boolean sendPushRevocationPolicyRequest(RealmModel realm, ApplicationModel resource, int notBefore, ApacheHttpClient4Executor client, String managementUrl) {
-        PushNotBeforeAction adminAction = new PushNotBeforeAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getName(), notBefore);
+    protected boolean sendPushRevocationPolicyRequest(RealmModel realm, ClientModel resource, int notBefore, ApacheHttpClient4Executor client, String managementUrl) {
+        PushNotBeforeAction adminAction = new PushNotBeforeAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getClientId(), notBefore);
         String token = new TokenManager().encodeToken(realm, adminAction);
-        logger.infov("pushRevocation resource: {0} url: {1}", resource.getName(), managementUrl);
+        logger.infov("pushRevocation resource: {0} url: {1}", resource.getClientId(), managementUrl);
         ClientRequest request = client.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_PUSH_NOT_BEFORE).build().toString());
         ClientResponse response;
         try {
@@ -348,10 +345,10 @@ public class ResourceAdminManager {
         }
     }
 
-    public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ApplicationModel application) {
+    public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ClientModel application) {
         List<String> mgmtUrls = getAllManagementUrls(requestUri, application);
         if (mgmtUrls.isEmpty()) {
-            logger.debug("No management URL or no registered cluster nodes for the application " + application.getName());
+            logger.debug("No management URL or no registered cluster nodes for the application " + application.getClientId());
             return new GlobalRequestResult();
         }
 
@@ -375,10 +372,10 @@ public class ResourceAdminManager {
         }
     }
 
-    protected boolean sendTestNodeAvailabilityRequest(RealmModel realm, ApplicationModel application, ApacheHttpClient4Executor client, String managementUrl) {
-        TestAvailabilityAction adminAction = new TestAvailabilityAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, application.getName());
+    protected boolean sendTestNodeAvailabilityRequest(RealmModel realm, ClientModel application, ApacheHttpClient4Executor client, String managementUrl) {
+        TestAvailabilityAction adminAction = new TestAvailabilityAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, application.getClientId());
         String token = new TokenManager().encodeToken(realm, adminAction);
-        logger.debugv("testNodes availability resource: {0} url: {1}", application.getName(), managementUrl);
+        logger.debugv("testNodes availability resource: {0} url: {1}", application.getClientId(), managementUrl);
         ClientRequest request = client.createRequest(UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_TEST_AVAILABLE).build().toString());
         ClientResponse response;
         try {
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 906e3e2..d3e979b 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -131,14 +131,14 @@ public class AccountService {
     private KeycloakSession session;
 
     private final AppAuthManager authManager;
-    private final ApplicationModel application;
+    private final ClientModel application;
     private EventBuilder event;
     private AccountProvider account;
     private Auth auth;
     private EventStoreProvider eventStore;
     private String stateChecker;
 
-    public AccountService(RealmModel realm, ApplicationModel application, EventBuilder event) {
+    public AccountService(RealmModel realm, ClientModel application, EventBuilder event) {
         this.realm = realm;
         this.application = application;
         this.event = event;
@@ -813,7 +813,7 @@ public class AccountService {
 
         String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri");
 
-        ApplicationModel application = realm.getApplicationByName(referrer);
+        ClientModel application = realm.getClientByClientId(referrer);
         if (application != null) {
             if (referrerUri != null) {
                 referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, application);
@@ -825,7 +825,7 @@ public class AccountService {
                 return new String[]{referrer, referrerUri};
             }
         } else if (referrerUri != null) {
-            ClientModel client = realm.getOAuthClient(referrer);
+            ClientModel client = realm.getClientByClientId(referrer);
             if (client != null) {
                 referrerUri = RedirectUtils.verifyRedirectUri(uriInfo, referrerUri, realm, application);
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
index ca7dece..3dd1123 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminAuth.java
@@ -1,6 +1,5 @@
 package org.keycloak.services.resources.admin;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
@@ -43,7 +42,7 @@ public class AdminAuth {
 
 
     public boolean hasRealmRole(String role) {
-        if (client instanceof ApplicationModel) {
+        if (client instanceof ClientModel) {
             RoleModel roleModel = realm.getRole(role);
             return user.hasRole(roleModel) && client.hasScope(roleModel);
         } else {
@@ -61,17 +60,17 @@ public class AdminAuth {
         return false;
     }
 
-    public boolean hasAppRole(ApplicationModel app, String role) {
-        if (client instanceof ApplicationModel) {
+    public boolean hasAppRole(ClientModel app, String role) {
+        if (client instanceof ClientModel) {
             RoleModel roleModel = app.getRole(role);
             return user.hasRole(roleModel) && client.hasScope(roleModel);
         } else {
-            AccessToken.Access access = token.getResourceAccess(app.getName());
+            AccessToken.Access access = token.getResourceAccess(app.getClientId());
             return access != null && access.isUserInRole(role);
         }
     }
 
-    public boolean hasOneOfAppRole(ApplicationModel app, String... roles) {
+    public boolean hasOneOfAppRole(ClientModel app, String... roles) {
         for (String r : roles) {
             if (hasAppRole(app, r)) {
                 return true;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
index 8ed297a..3dcffde 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
@@ -14,7 +14,7 @@ import org.keycloak.freemarker.FreeMarkerUtil;
 import org.keycloak.freemarker.Theme;
 import org.keycloak.freemarker.ThemeProvider;
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -154,7 +154,7 @@ public class AdminConsole {
     @Produces("application/json")
     @NoCache
     public ApplicationManager.InstallationAdapterConfig config() {
-        ApplicationModel consoleApp = realm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+        ClientModel consoleApp = realm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
         if (consoleApp == null) {
             throw new NotFoundException("Could not find admin console application");
         }
@@ -208,7 +208,7 @@ public class AdminConsole {
 
     private void addRealmAccess(RealmModel realm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
         RealmManager realmManager = new RealmManager(session);
-        ApplicationModel realmAdminApp = realm.getApplicationByName(realmManager.getRealmAdminApplicationName(realm));
+        ClientModel realmAdminApp = realm.getClientByClientId(realmManager.getRealmAdminApplicationName(realm));
         Set<RoleModel> roles = realmAdminApp.getRoles();
         for (RoleModel role : roles) {
             if (!user.hasRole(role)) continue;
@@ -223,7 +223,7 @@ public class AdminConsole {
     private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
         List<RealmModel> realms = session.realms().getRealms();
         for (RealmModel realm : realms) {
-            ApplicationModel realmAdminApp = realm.getMasterAdminApp();
+            ClientModel realmAdminApp = realm.getMasterAdminApp();
             Set<RoleModel> roles = realmAdminApp.getRoles();
             for (RoleModel role : roles) {
                 if (!user.hasRole(role)) continue;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index c049ac4..2ece39b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -149,7 +149,7 @@ public class AdminRoot {
             throw new UnauthorizedException("Bearer");
         }
 
-        ClientModel client = realm.findClient(token.getIssuedFor());
+        ClientModel client = realm.getClientByClientId(token.getIssuedFor());
         if (client == null) {
             throw new NotFoundException("Could not find client for authorization");
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index 0ee416c..7a5e2b5 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -5,7 +5,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
@@ -57,7 +57,7 @@ public class ApplicationResource {
     protected static final Logger logger = Logger.getLogger(ApplicationResource.class);
     protected RealmModel realm;
     private RealmAuth auth;
-    protected ApplicationModel application;
+    protected ClientModel application;
     protected KeycloakSession session;
     
     @Context
@@ -70,13 +70,13 @@ public class ApplicationResource {
         return keycloak;
     }
 
-    public ApplicationResource(RealmModel realm, RealmAuth auth, ApplicationModel applicationModel, KeycloakSession session) {
+    public ApplicationResource(RealmModel realm, RealmAuth auth, ClientModel clientModel, KeycloakSession session) {
         this.realm = realm;
         this.auth = auth;
-        this.application = applicationModel;
+        this.application = clientModel;
         this.session = session;
 
-        auth.init(RealmAuth.Resource.APPLICATION);
+        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     @Path("protocol-mappers")
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java
index fc93f01..d4b8f8f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsByIdResource.java
@@ -1,6 +1,6 @@
 package org.keycloak.services.resources.admin;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 
 /**
@@ -13,13 +13,13 @@ public class ApplicationsByIdResource extends ApplicationsResource {
     }
 
     @Override
-    protected ApplicationModel getApplicationByPathParam(String id) {
-        return realm.getApplicationById(id);
+    protected ClientModel getApplicationByPathParam(String id) {
+        return realm.getClientById(id);
     }
 
     @Override
-    protected String getApplicationPath(ApplicationModel applicationModel) {
-        return applicationModel.getId();
+    protected String getApplicationPath(ClientModel clientModel) {
+        return clientModel.getId();
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index 13e7061..66ce8a8 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -4,7 +4,7 @@ import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
@@ -44,7 +44,7 @@ public class ApplicationsResource {
         this.realm = realm;
         this.auth = auth;
         
-        auth.init(RealmAuth.Resource.APPLICATION);
+        auth.init(RealmAuth.Resource.CLIENT);
     }
 
     /**
@@ -59,15 +59,15 @@ public class ApplicationsResource {
         auth.requireAny();
 
         List<ApplicationRepresentation> rep = new ArrayList<ApplicationRepresentation>();
-        List<ApplicationModel> applicationModels = realm.getApplications();
+        List<ClientModel> clientModels = realm.getClients();
 
         boolean view = auth.hasView();
-        for (ApplicationModel applicationModel : applicationModels) {
+        for (ClientModel clientModel : clientModels) {
             if (view) {
-                rep.add(ModelToRepresentation.toRepresentation(applicationModel));
+                rep.add(ModelToRepresentation.toRepresentation(clientModel));
             } else {
                 ApplicationRepresentation app = new ApplicationRepresentation();
-                app.setName(applicationModel.getName());
+                app.setName(clientModel.getClientId());
                 rep.add(app);
             }
         }
@@ -88,15 +88,15 @@ public class ApplicationsResource {
         auth.requireManage();
 
         try {
-            ApplicationModel applicationModel = RepresentationToModel.createApplication(session, realm, rep, true);
-            return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(applicationModel)).build()).build();
+            ClientModel clientModel = RepresentationToModel.createApplication(session, realm, rep, true);
+            return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(clientModel)).build()).build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Application " + rep.getName() + " already exists");
         }
     }
 
-    protected String getApplicationPath(ApplicationModel applicationModel) {
-        return applicationModel.getName();
+    protected String getApplicationPath(ClientModel clientModel) {
+        return clientModel.getClientId();
     }
 
     /**
@@ -107,18 +107,18 @@ public class ApplicationsResource {
      */
     @Path("{app-name}")
     public ApplicationResource getApplication(final @PathParam("app-name") String name) {
-        ApplicationModel applicationModel = getApplicationByPathParam(name);
-        if (applicationModel == null) {
+        ClientModel clientModel = getApplicationByPathParam(name);
+        if (clientModel == null) {
             throw new NotFoundException("Could not find application: " + name);
         }
-        ApplicationResource applicationResource = new ApplicationResource(realm, auth, applicationModel, session);
+        ApplicationResource applicationResource = new ApplicationResource(realm, auth, clientModel, session);
         ResteasyProviderFactory.getInstance().injectProperties(applicationResource);
         //resourceContext.initResource(applicationResource);
         return applicationResource;
     }
 
-    protected ApplicationModel getApplicationByPathParam(String name) {
-        return realm.getApplicationByName(name);
+    protected ClientModel getApplicationByPathParam(String name) {
+        return realm.getClientByClientId(name);
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
index 1140627..b1ec4d1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
@@ -6,8 +6,6 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
 import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.NotAcceptableException;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.events.EventBuilder;
-import org.keycloak.events.EventType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
index 07444af..97c56f1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -4,8 +4,8 @@ import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.keycloak.broker.provider.IdentityProvider;
 import org.keycloak.broker.provider.IdentityProviderFactory;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
@@ -65,8 +65,7 @@ public class IdentityProviderResource {
     public Response delete() {
         this.auth.requireManage();
 
-        removeClientIdentityProviders(this.realm.getApplications(), this.identityProviderModel);
-        removeClientIdentityProviders(this.realm.getOAuthClients(), this.identityProviderModel);
+        removeClientIdentityProviders(this.realm.getClients(), this.identityProviderModel);
 
         this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias());
 
@@ -90,8 +89,7 @@ public class IdentityProviderResource {
                 // Admin changed the ID (alias) of identity provider. We must update all clients and users
                 logger.debug("Changing providerId in all clients and linked users. oldProviderId=" + oldProviderId + ", newProviderId=" + newProviderId);
 
-                updateClientsAfterProviderAliasChange(this.realm.getApplications(), oldProviderId, newProviderId);
-                updateClientsAfterProviderAliasChange(this.realm.getOAuthClients(), oldProviderId, newProviderId);
+                updateClientsAfterProviderAliasChange(this.realm.getClients(), oldProviderId, newProviderId);
                 updateUsersAfterProviderAliasChange(this.session.users().getUsers(this.realm), oldProviderId, newProviderId);
             }
 
@@ -113,7 +111,7 @@ public class IdentityProviderResource {
         return null;
     }
 
-    private void updateClientsAfterProviderAliasChange(List<? extends ClientModel> clients, String oldProviderId, String newProviderId) {
+    private void updateClientsAfterProviderAliasChange(List<ClientModel> clients, String oldProviderId, String newProviderId) {
         for (ClientModel client : clients) {
             List<ClientIdentityProviderMappingModel> clientIdentityProviders = client.getIdentityProviders();
             boolean found = true;
@@ -175,11 +173,11 @@ public class IdentityProviderResource {
     }
 
 
-    private void removeClientIdentityProviders(List<? extends ClientModel> clients, IdentityProviderModel identityProvider) {
+    private void removeClientIdentityProviders(List<ClientModel> clients, IdentityProviderModel identityProvider) {
         for (ClientModel clientModel : clients) {
             List<ClientIdentityProviderMappingModel> identityProviders = clientModel.getIdentityProviders();
 
-            for (ClientIdentityProviderMappingModel providerMappingModel : new ArrayList<ClientIdentityProviderMappingModel>(identityProviders)) {
+            for (ClientIdentityProviderMappingModel providerMappingModel : new ArrayList<>(identityProviders)) {
                 if (providerMappingModel.getIdentityProvider().equals(identityProvider.getAlias())) {
                     identityProviders.remove(providerMappingModel);
                     clientModel.updateIdentityProviders(identityProviders);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
index 717a116..d4cedda 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
@@ -21,7 +21,6 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-
 import java.util.LinkedList;
 import java.util.List;
 
@@ -147,6 +146,4 @@ public class ProtocolMappersResource {
         client.removeProtocolMapper(model);
     }
 
-
-
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 34cd97e..b178882 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -10,7 +10,7 @@ import org.keycloak.events.EventQuery;
 import org.keycloak.events.EventStoreProvider;
 import org.keycloak.events.EventType;
 import org.keycloak.exportimport.ApplicationImporter;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
@@ -46,7 +46,6 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -123,32 +122,6 @@ public class RealmAdminResource {
     }
 
     /**
-     * base path for managing oauth clients in this realm uses name of client
-     *
-     * @return
-     */
-    @Path("oauth-clients")
-    public OAuthClientsResource getOAuthClients() {
-        OAuthClientsResource oauth = new OAuthClientsResource(realm, auth, session);
-        ResteasyProviderFactory.getInstance().injectProperties(oauth);
-        //resourceContext.initResource(oauth);
-        return oauth;
-    }
-
-    /**
-     * base path for managing oauth clients in this realm uses ids
-     *
-     * @return
-     */
-    @Path("oauth-clients-by-id")
-    public OAuthClientsByIdResource getOAuthClientsById() {
-        OAuthClientsByIdResource oauth = new OAuthClientsByIdResource(realm, auth, session);
-        ResteasyProviderFactory.getInstance().injectProperties(oauth);
-        //resourceContext.initResource(oauth);
-        return oauth;
-    }
-
-    /**
      * base path for managing realm-level roles of this realm
      *
      * @return
@@ -327,10 +300,10 @@ public class RealmAdminResource {
     public Map<String, Integer> getApplicationSessionStats() {
         auth.requireView();
         Map<String, Integer> stats = new HashMap<String, Integer>();
-        for (ApplicationModel application : realm.getApplications()) {
+        for (ClientModel application : realm.getClients()) {
             int size = session.sessions().getActiveUserSessions(application.getRealm(), application);
             if (size == 0) continue;
-            stats.put(application.getName(), size);
+            stats.put(application.getClientId(), size);
         }
         return stats;
     }
@@ -348,12 +321,12 @@ public class RealmAdminResource {
     public List<Map<String, String>> getApplicationByIdSessionStats() {
         auth.requireView();
         List<Map<String, String>> data = new LinkedList<Map<String, String>>();
-        for (ApplicationModel application : realm.getApplications()) {
+        for (ClientModel application : realm.getClients()) {
             int size = session.sessions().getActiveUserSessions(application.getRealm(), application);
             if (size == 0) continue;
             Map<String, String> map = new HashMap<String, String>();
             map.put("id", application.getId());
-            map.put("name", application.getName());
+            map.put("name", application.getClientId());
             map.put("active", size + "");
             data.add(map);
         }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
index 20238f1..f93e8c7 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
@@ -1,7 +1,7 @@
 package org.keycloak.services.resources.admin;
 
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.services.ForbiddenException;
 
 
@@ -13,13 +13,13 @@ public class RealmAuth {
     private Resource resource;
 
     public enum Resource {
-        APPLICATION, CLIENT, USER, REALM, EVENTS, IDENTITY_PROVIDER
+        CLIENT, USER, REALM, EVENTS, IDENTITY_PROVIDER
     }
 
     private AdminAuth auth;
-    private ApplicationModel realmAdminApp;
+    private ClientModel realmAdminApp;
 
-    public RealmAuth(AdminAuth auth, ApplicationModel realmAdminApp) {
+    public RealmAuth(AdminAuth auth, ClientModel realmAdminApp) {
         this.auth = auth;
         this.realmAdminApp = realmAdminApp;
     }
@@ -57,8 +57,6 @@ public class RealmAuth {
 
     private String getViewRole(Resource resource) {
         switch (resource) {
-            case APPLICATION:
-                return AdminRoles.VIEW_APPLICATIONS;
             case CLIENT:
                 return AdminRoles.VIEW_CLIENTS;
             case USER:
@@ -76,8 +74,6 @@ public class RealmAuth {
 
     private String getManageRole(Resource resource) {
         switch (resource) {
-            case APPLICATION:
-                return AdminRoles.MANAGE_APPLICATIONS;
             case CLIENT:
                 return AdminRoles.MANAGE_CLIENTS;
             case USER:
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index 07b29b2..963bd6a 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -4,11 +4,10 @@ import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.plugins.providers.multipart.InputPart;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
-import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
@@ -85,14 +84,14 @@ public class RealmsAdminResource {
                 addRealmRep(reps, realm, realm.getMasterAdminApp());
             }
         } else {
-            ApplicationModel adminApp = auth.getRealm().getApplicationByName(realmManager.getRealmAdminApplicationName(auth.getRealm()));
+            ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminApplicationName(auth.getRealm()));
             addRealmRep(reps, auth.getRealm(), adminApp);
         }
         logger.debug(("getRealms()"));
         return reps;
     }
 
-    protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ApplicationModel realmManagementApplication) {
+    protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ClientModel realmManagementApplication) {
         if (auth.hasAppRole(realmManagementApplication, AdminRoles.MANAGE_REALM)) {
             reps.add(ModelToRepresentation.toRepresentation(realm, false));
         } else if (auth.hasOneOfAppRole(realmManagementApplication, AdminRoles.ALL_REALM_ROLES)) {
@@ -187,7 +186,7 @@ public class RealmsAdminResource {
         }
 
         RealmModel adminRealm = new RealmManager(session).getKeycloakAdminstrationRealm();
-        ApplicationModel realmAdminApp = realm.getMasterAdminApp();
+        ClientModel realmAdminApp = realm.getMasterAdminApp();
         for (String r : AdminRoles.ALL_REALM_ROLES) {
             RoleModel role = realmAdminApp.getRole(r);
             auth.getUser().grantRole(role);
@@ -217,7 +216,7 @@ public class RealmsAdminResource {
         if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
             realmAuth = new RealmAuth(auth, realm.getMasterAdminApp());
         } else {
-            realmAuth = new RealmAuth(auth, realm.getApplicationByName(realmManager.getRealmAdminApplicationName(auth.getRealm())));
+            realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminApplicationName(auth.getRealm())));
         }
 
         RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
index 41ede41..710f065 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
@@ -3,9 +3,8 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -70,9 +69,7 @@ public class RoleByIdResource extends RoleResource {
         RealmAuth.Resource r = null;
         if (roleModel.getContainer() instanceof RealmModel) {
             r = RealmAuth.Resource.REALM;
-        } else if (roleModel.getContainer() instanceof ApplicationModel) {
-            r = RealmAuth.Resource.APPLICATION;
-        } else if (roleModel.getContainer() instanceof OAuthClientModel) {
+        } else if (roleModel.getContainer() instanceof ClientModel) {
             r = RealmAuth.Resource.CLIENT;
         } else if (roleModel.getContainer() instanceof UserModel) {
             r = RealmAuth.Resource.USER;
@@ -175,7 +172,7 @@ public class RoleByIdResource extends RoleResource {
                                                                 final @PathParam("app") String appName) {
         RoleModel role = getRoleModel(id);
         auth.requireView();
-        ApplicationModel app = realm.getApplicationByName(appName);
+        ClientModel app = realm.getClientByClientId(appName);
         if (app == null) {
             throw new NotFoundException("Could not find application: " + appName);
 
@@ -198,7 +195,7 @@ public class RoleByIdResource extends RoleResource {
                                                                 final @PathParam("appId") String appId) {
         RoleModel role = getRoleModel(id);
         auth.requireView();
-        ApplicationModel app = realm.getApplicationById(appId);
+        ClientModel app = realm.getClientById(appId);
         if (app == null) {
             throw new NotFoundException("Could not find application: " + appId);
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index 3ddeafb..e1d5c28 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -2,7 +2,7 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
@@ -225,7 +225,7 @@ public class RoleContainerResource extends RoleResource {
         if (role == null) {
             throw new NotFoundException("Could not find role: " + roleName);
         }
-        ApplicationModel app = realm.getApplicationByName(appName);
+        ClientModel app = realm.getClientByClientId(appName);
         if (app == null) {
             throw new NotFoundException("Could not find application: " + appName);
 
@@ -253,7 +253,7 @@ public class RoleContainerResource extends RoleResource {
         if (role == null) {
             throw new NotFoundException("Could not find role: " + roleName);
         }
-        ApplicationModel app = realm.getApplicationById(appId);
+        ClientModel app = realm.getClientById(appId);
         if (app == null) {
             throw new NotFoundException("Could not find application: " + appId);
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index 8d6fd44..80b6b42 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -1,7 +1,7 @@
 package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.utils.ModelToRepresentation;
@@ -69,7 +69,7 @@ public abstract class RoleResource {
         return composites;
     }
 
-    protected Set<RoleRepresentation> getApplicationRoleComposites(ApplicationModel app, RoleModel role) {
+    protected Set<RoleRepresentation> getApplicationRoleComposites(ClientModel app, RoleModel role) {
         if (!role.isComposite() || role.getComposites().size() == 0) return Collections.emptySet();
 
         Set<RoleRepresentation> composites = new HashSet<RoleRepresentation>(role.getComposites().size());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java
index e61e6a0..9035ef0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedApplicationResource.java
@@ -2,7 +2,6 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -15,7 +14,6 @@ import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import java.util.ArrayList;
 import java.util.List;
@@ -30,9 +28,9 @@ public class ScopeMappedApplicationResource {
     private RealmAuth auth;
     protected ClientModel client;
     protected KeycloakSession session;
-    protected ApplicationModel app;
+    protected ClientModel app;
 
-    public ScopeMappedApplicationResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, ApplicationModel app) {
+    public ScopeMappedApplicationResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, ClientModel app) {
         this.realm = realm;
         this.auth = auth;
         this.client = client;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
index 8084c44..2dda52b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
@@ -2,7 +2,6 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -65,21 +64,21 @@ public class ScopeMappedResource {
             all.setRealmMappings(realmRep);
         }
 
-        List<ApplicationModel> applications = realm.getApplications();
+        List<ClientModel> applications = realm.getClients();
         if (applications.size() > 0) {
             Map<String, ApplicationMappingsRepresentation> appMappings = new HashMap<String, ApplicationMappingsRepresentation>();
-            for (ApplicationModel app : applications) {
+            for (ClientModel app : applications) {
                 Set<RoleModel> roleMappings = app.getApplicationScopeMappings(client);
                 if (roleMappings.size() > 0) {
                     ApplicationMappingsRepresentation mappings = new ApplicationMappingsRepresentation();
                     mappings.setApplicationId(app.getId());
-                    mappings.setApplication(app.getName());
+                    mappings.setApplication(app.getClientId());
                     List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
                     mappings.setMappings(roles);
                     for (RoleModel role : roleMappings) {
                         roles.add(ModelToRepresentation.toRepresentation(role));
                     }
-                    appMappings.put(app.getName(), mappings);
+                    appMappings.put(app.getClientId(), mappings);
                     all.setApplicationMappings(appMappings);
                 }
             }
@@ -210,7 +209,7 @@ public class ScopeMappedResource {
 
     @Path("applications/{app}")
     public ScopeMappedApplicationResource getApplicationScopeMappings(@PathParam("app") String appName) {
-        ApplicationModel app = realm.getApplicationByName(appName);
+        ClientModel app = realm.getClientByClientId(appName);
 
         if (app == null) {
             throw new NotFoundException("Role not found");
@@ -221,7 +220,7 @@ public class ScopeMappedResource {
 
     @Path("applications-by-id/{appId}")
     public ScopeMappedApplicationResource getApplicationByIdScopeMappings(@PathParam("appId") String appId) {
-        ApplicationModel app = realm.getApplicationById(appId);
+        ClientModel app = realm.getClientById(appId);
 
         if (app == null) {
             throw new NotFoundException("Application not found");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java
index 4c5b7d6..2149ef9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserApplicationRoleMappingsResource.java
@@ -3,14 +3,11 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.ClientConnection;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.ModelToRepresentation;
-import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.representations.idm.RoleRepresentation;
 
 import javax.ws.rs.Consumes;
@@ -18,10 +15,7 @@ import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -37,9 +31,9 @@ public class UserApplicationRoleMappingsResource {
     protected RealmModel realm;
     protected RealmAuth auth;
     protected UserModel user;
-    protected ApplicationModel application;
+    protected ClientModel application;
 
-    public UserApplicationRoleMappingsResource(RealmModel realm, RealmAuth auth, UserModel user, ApplicationModel application) {
+    public UserApplicationRoleMappingsResource(RealmModel realm, RealmAuth auth, UserModel user, ClientModel application) {
         this.realm = realm;
         this.auth = auth;
         this.user = user;
@@ -155,8 +149,8 @@ public class UserApplicationRoleMappingsResource {
         if (roles == null) {
             Set<RoleModel> roleModels = user.getApplicationRoleMappings(application);
             for (RoleModel roleModel : roleModels) {
-                if (!(roleModel.getContainer() instanceof ApplicationModel)) {
-                    ApplicationModel app = (ApplicationModel) roleModel.getContainer();
+                if (!(roleModel.getContainer() instanceof ClientModel)) {
+                    ClientModel app = (ClientModel) roleModel.getContainer();
                     if (!app.getId().equals(application.getId())) continue;
                 }
                 user.deleteRoleMapping(roleModel);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index ff5370b..e424175 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -7,7 +7,6 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.ClientConnection;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
@@ -440,21 +439,21 @@ public class UsersResource {
             all.setRealmMappings(realmRep);
         }
 
-        List<ApplicationModel> applications = realm.getApplications();
+        List<ClientModel> applications = realm.getClients();
         if (applications.size() > 0) {
             Map<String, ApplicationMappingsRepresentation> appMappings = new HashMap<String, ApplicationMappingsRepresentation>();
-            for (ApplicationModel application : applications) {
+            for (ClientModel application : applications) {
                 Set<RoleModel> roleMappings = user.getApplicationRoleMappings(application);
                 if (roleMappings.size() > 0) {
                     ApplicationMappingsRepresentation mappings = new ApplicationMappingsRepresentation();
                     mappings.setApplicationId(application.getId());
-                    mappings.setApplication(application.getName());
+                    mappings.setApplication(application.getClientId());
                     List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
                     mappings.setMappings(roles);
                     for (RoleModel role : roleMappings) {
                         roles.add(ModelToRepresentation.toRepresentation(role));
                     }
-                    appMappings.put(application.getName(), mappings);
+                    appMappings.put(application.getClientId(), mappings);
                     all.setApplicationMappings(appMappings);
                 }
             }
@@ -609,7 +608,7 @@ public class UsersResource {
             throw new NotFoundException("User not found");
         }
 
-        ApplicationModel application = realm.getApplicationByName(appName);
+        ClientModel application = realm.getClientByClientId(appName);
 
         if (application == null) {
             throw new NotFoundException("Application not found");
@@ -625,7 +624,7 @@ public class UsersResource {
             throw new NotFoundException("User not found");
         }
 
-        ApplicationModel application = realm.getApplicationById(appId);
+        ClientModel application = realm.getClientById(appId);
 
         if (application == null) {
             throw new NotFoundException("Application not found");
@@ -720,7 +719,7 @@ public class UsersResource {
             clientId = Constants.ACCOUNT_MANAGEMENT_APP;
         }
 
-        ClientModel client = realm.findClient(clientId);
+        ClientModel client = realm.getClientByClientId(clientId);
         if (client == null || !client.isEnabled()) {
             return Flows.errors().error(clientId + " not enabled", Response.Status.INTERNAL_SERVER_ERROR);
         }
diff --git a/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java b/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java
index 1761138..beca17d 100755
--- a/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java
+++ b/services/src/main/java/org/keycloak/services/resources/ClientsManagementService.java
@@ -1,20 +1,5 @@
 package org.keycloak.services.resources;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.ws.rs.HeaderParam;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-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.BadRequestException;
 import org.jboss.resteasy.spi.HttpRequest;
@@ -26,15 +11,27 @@ import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.protocol.oidc.utils.AuthorizeClientUtil;
 import org.keycloak.services.ForbiddenException;
 import org.keycloak.util.Time;
 
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+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.HashMap;
+import java.util.Map;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
@@ -105,11 +102,11 @@ public class ClientsManagementService {
             throw new UnauthorizedException("Realm not enabled");
         }
 
-        ApplicationModel application = authorizeApplication(authorizationHeader, formData);
+        ClientModel application = authorizeApplication(authorizationHeader, formData);
         String nodeHost = getApplicationClusterHost(formData);
 
         event.client(application).detail(Details.NODE_HOST, nodeHost);
-        logger.debugf("Registering cluster host '%s' for client '%s'", nodeHost, application.getName());
+        logger.debugf("Registering cluster host '%s' for client '%s'", nodeHost, application.getClientId());
 
         application.registerNode(nodeHost, Time.currentTime());
 
@@ -141,11 +138,11 @@ public class ClientsManagementService {
             throw new UnauthorizedException("Realm not enabled");
         }
 
-        ApplicationModel application = authorizeApplication(authorizationHeader, formData);
+        ClientModel application = authorizeApplication(authorizationHeader, formData);
         String nodeHost = getApplicationClusterHost(formData);
 
         event.client(application).detail(Details.NODE_HOST, nodeHost);
-        logger.debugf("Unregistering cluster host '%s' for client '%s'", nodeHost, application.getName());
+        logger.debugf("Unregistering cluster host '%s' for client '%s'", nodeHost, application.getClientId());
 
         application.unregisterNode(nodeHost);
 
@@ -154,7 +151,7 @@ public class ClientsManagementService {
         return Response.noContent().build();
     }
 
-    protected ApplicationModel authorizeApplication(String authorizationHeader, MultivaluedMap<String, String> formData) {
+    protected ClientModel authorizeApplication(String authorizationHeader, MultivaluedMap<String, String> formData) {
         ClientModel client = AuthorizeClientUtil.authorizeClient(authorizationHeader, formData, event, realm);
 
         if (client.isPublicClient()) {
@@ -165,7 +162,7 @@ public class ClientsManagementService {
             throw new BadRequestException("Public clients not allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
         }
 
-        if (!(client instanceof ApplicationModel)) {
+        if (!(client instanceof ClientModel)) {
             Map<String, String> error = new HashMap<String, String>();
             error.put(OAuth2Constants.ERROR, "invalid_client");
             error.put(OAuth2Constants.ERROR_DESCRIPTION, "Just applications are allowed");
@@ -173,7 +170,7 @@ public class ClientsManagementService {
             throw new BadRequestException("ust applications are allowed", javax.ws.rs.core.Response.status(javax.ws.rs.core.Response.Status.BAD_REQUEST).entity(error).type("application/json").build());
         }
 
-        return (ApplicationModel)client;
+        return (ClientModel)client;
     }
 
     protected String getApplicationClusterHost(MultivaluedMap<String, String> formData) {
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 df9771f..a26b279 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -35,11 +35,9 @@ import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.provider.ProviderFactory;
 import org.keycloak.services.managers.AppAuthManager;
@@ -181,7 +179,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
 
             if (authResult != null) {
                 String audience = authResult.getToken().getAudience();
-                ClientModel clientModel = this.realmModel.findClient(audience);
+                ClientModel clientModel = this.realmModel.getClientByClientId(audience);
 
                 if (clientModel == null) {
                     return badRequest("Invalid client.");
@@ -191,7 +189,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
                     return corsResponse(badRequest("Client [" + audience + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
                 }
 
-                if (OAuthClientModel.class.isInstance(clientModel) && !forceRetrieval) {
+                if (clientModel.isConsentRequired()) {
                     return corsResponse(Flows.forms(this.session, this.realmModel, clientModel, this.uriInfo, headers)
                             .setClientSessionCode(authManager.extractAuthorizationHeaderToken(this.request.getHttpHeaders()))
                             .setAccessRequest("Your information from " + providerId + " identity provider.")
@@ -329,7 +327,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
             return redirectToErrorPage(Messages.ACCOUNT_DISABLED);
         }
 
-        if (!authenticatedUser.hasRole(this.realmModel.getApplicationByName(ACCOUNT_MANAGEMENT_APP).getRole(MANAGE_ACCOUNT))) {
+        if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(ACCOUNT_MANAGEMENT_APP).getRole(MANAGE_ACCOUNT))) {
             fireErrorEvent(Errors.NOT_ALLOWED);
             return redirectToErrorPage(Messages.INSUFFICIENT_PERMISSION);
         }
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 078e408..106be1c 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -36,7 +36,6 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelException;
-import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.UserCredentialModel;
@@ -73,8 +72,6 @@ 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.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
@@ -320,7 +317,6 @@ public class LoginActionsService {
             event.detail(Details.REMEMBER_ME, "true");
         }
 
-
         ClientModel client = clientSession.getClient();
         if (client == null) {
             event.error(Errors.CLIENT_NOT_FOUND);
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index daed1e0..4989fbc 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -5,7 +5,7 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.ClientConnection;
 import org.keycloak.events.EventBuilder;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -157,7 +157,7 @@ public class RealmsResource {
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = locateRealm(name, realmManager);
 
-        ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
+        ClientModel application = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_APP);
         if (application == null || !application.isEnabled()) {
             logger.debug("account management not enabled");
             throw new NotFoundException("account management not enabled");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index ce61d33..8e22acf 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -31,7 +31,7 @@ import org.junit.Test;
 import org.keycloak.events.Details;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventType;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
@@ -75,7 +75,7 @@ public class AccountTest {
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
             UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
 
-            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
+            ClientModel accountApp = appRealm.getClientNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
 
             UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
             user2.setEnabled(true);
@@ -157,11 +157,6 @@ public class AccountTest {
         });
     }
 
-    //@Test @Ignore
-    public void runit() throws Exception {
-        Thread.sleep(10000000);
-    }
-
     @Test
     public void returnToAppFromQueryParam() {
         driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
index 97e2095..a189032 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
@@ -12,7 +12,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.models.AccountRoles;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
@@ -54,7 +53,7 @@ public class ProfileTest {
             user.setAttribute("key1", "value1");
             user.setAttribute("key2", "value2");
 
-            ApplicationModel accountApp = appRealm.getApplicationByName(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
+            ClientModel accountApp = appRealm.getClientByClientId(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
 
             UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
             user2.setEnabled(true);
@@ -66,12 +65,12 @@ public class ProfileTest {
             creds.setValue("password");
             user2.updateCredential(creds);
 
-            ApplicationModel app = appRealm.getApplicationByName("test-app");
+            ClientModel app = appRealm.getClientByClientId("test-app");
             app.addScopeMapping(accountApp.getRole(AccountRoles.VIEW_PROFILE));
             app.addRedirectUri("http://localhost:8081/app/*");
             app.addWebOrigin("http://localtest.me:8081");
 
-            ClientModel thirdParty = appRealm.findClient("third-party");
+            ClientModel thirdParty = appRealm.getClientByClientId("third-party");
             thirdParty.addScopeMapping(accountApp.getRole(AccountRoles.VIEW_PROFILE));
         }
     });
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index 8feaac5..8ec896e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -29,7 +29,7 @@ import org.keycloak.OAuth2Constants;
 import org.keycloak.Version;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.constants.AdapterConstants;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -41,7 +41,6 @@ import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.resources.admin.AdminRoot;
@@ -65,7 +64,6 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import java.net.URI;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -139,7 +137,7 @@ public class AdapterTestStrategy extends ExternalResource {
             RealmManager manager = new RealmManager(session);
 
             RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
-            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+            ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
@@ -539,7 +537,7 @@ public class AdapterTestStrategy extends ExternalResource {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel demoRealm) {
-                ApplicationModel sessionPortal = demoRealm.getApplicationByName("session-portal");
+                ClientModel sessionPortal = demoRealm.getClientByClientId("session-portal");
                 sessionPortal.setManagementUrl(null);
 
                 origTokenLifespan.set(demoRealm.getAccessTokenLifespan());
@@ -571,7 +569,7 @@ public class AdapterTestStrategy extends ExternalResource {
 
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel demoRealm) {
-                ApplicationModel sessionPortal = demoRealm.getApplicationByName("session-portal");
+                ClientModel sessionPortal = demoRealm.getClientByClientId("session-portal");
                 sessionPortal.setManagementUrl(APP_SERVER_BASE_URL + "/session-portal");
 
                 demoRealm.setAccessTokenLifespan(origTokenLifespan.get());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
index 5c6ed7b..b56232e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/RelativeUriAdapterTest.java
@@ -26,7 +26,7 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -85,7 +85,7 @@ public class RelativeUriAdapterTest {
             deployApplication("customer-db", "/customer-db", CustomerDatabaseServlet.class, url.getPath(), "user");
             url = getClass().getResource("/adapter-test/product-keycloak-relative.json");
             deployApplication("product-portal", "/product-portal", ProductServlet.class, url.getPath(), "user");
-            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+            ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             ClientSessionModel clientSession = session.sessions().createClientSession(realm, adminConsole);
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 d72664a..ff73d79 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
@@ -25,7 +25,7 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.keycloak.Config;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -77,7 +77,7 @@ public class AdminAPITest {
             RealmManager manager = new RealmManager(session);
 
             RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
-            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+            ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
index e1902f9..55e17e6 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
@@ -4,17 +4,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.ApplicationResource;
 import org.keycloak.admin.client.resource.ProtocolMappersResource;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.RealmModel;
 import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.rule.KeycloakRule;
 import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
@@ -22,7 +17,6 @@ import org.openqa.selenium.WebDriver;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
 
-import java.util.LinkedList;
 import java.util.List;
 
 import static org.junit.Assert.assertArrayEquals;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
index 5e757cc..9026ebc 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
@@ -17,6 +17,11 @@
  */
 package org.keycloak.testsuite.broker;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.junit.After;
 import org.junit.Before;
@@ -24,7 +29,6 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.FederatedIdentityModel;
@@ -45,7 +49,6 @@ import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
 import org.keycloak.testsuite.pages.OAuthGrantPage;
 import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
-import org.keycloak.testsuite.rule.WebRule.HtmlUnitDriver;
 import org.openqa.selenium.By;
 import org.openqa.selenium.NoSuchElementException;
 import org.openqa.selenium.WebDriver;
@@ -60,18 +63,17 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
-
 import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
-import static com.thoughtworks.selenium.SeleneseTestBase.fail;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * @author pedroigor
@@ -278,10 +280,10 @@ public abstract class AbstractIdentityProviderTest {
     public void testProviderOnLoginPage() {
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
         RealmModel realm = getRealm();
-        ApplicationModel applicationModel = realm.getApplicationByName("test-app");
+        ClientModel clientModel = realm.getClientByClientId("test-app");
 
         // This client doesn't have any specific identity providers settings
-        ClientModel client2 = realm.findClient("test-app");
+        ClientModel client2 = realm.getClientByClientId("test-app");
         assertEquals(0, client2.getIdentityProviders().size());
 
         // Provider button is available on login page
@@ -295,7 +297,7 @@ public abstract class AbstractIdentityProviderTest {
         mapping.setIdentityProvider(getProviderId());
         mapping.setRetrieveToken(true);
         appIdentityProviders.add(mapping);
-        applicationModel.updateIdentityProviders(appIdentityProviders);
+        clientModel.updateIdentityProviders(appIdentityProviders);
 
         // Provider button still available on login page
         this.driver.navigate().to("http://localhost:8081/test-app/");
@@ -437,7 +439,7 @@ public abstract class AbstractIdentityProviderTest {
 
         assertNotNull(identityModel.getToken());
 
-        configureRetrieveToken(realm.findClient("test-app"), getProviderId(), false);
+        configureRetrieveToken(realm.getClientByClientId("test-app"), getProviderId(), false);
 
         UserSessionStatus userSessionStatus = retrieveSessionStatus();
         String accessToken = userSessionStatus.getAccessTokenString();
@@ -455,7 +457,7 @@ public abstract class AbstractIdentityProviderTest {
 
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
 
-        configureRetrieveToken(getRealm().findClient("test-app"), getProviderId(), true);
+        configureRetrieveToken(getRealm().getClientByClientId("test-app"), getProviderId(), true);
 
         client = ClientBuilder.newBuilder().register(authFilter).build();
         tokenEndpoint = client.target(tokenEndpointUrl);
@@ -505,26 +507,30 @@ public abstract class AbstractIdentityProviderTest {
 
         assertTrue(oauth.getCurrentQuery().containsKey(OAuth2Constants.CODE));
 
-        ClientModel clientModel = getRealm().findClient("third-party");
+        ClientModel clientModel = getRealm().getClientByClientId("third-party");
         assertEquals(0, clientModel.getIdentityProviders().size());
 
         configureRetrieveToken(clientModel, getProviderId(), true);
 
         AccessTokenResponse accessToken = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
-        URI tokenEndpointUrl = Urls.identityProviderRetrieveToken(BASE_URI, getProviderId(), getRealm().getName());
-        String authHeader = "Bearer " + accessToken.getAccessToken();
-        HtmlUnitDriver htmlUnitDriver = (WebRule.HtmlUnitDriver) this.driver;
 
-        htmlUnitDriver.getWebClient().addRequestHeader(HttpHeaders.AUTHORIZATION, authHeader);
+        doTokenRequest(accessToken.getAccessToken());
+    }
 
-        htmlUnitDriver.navigate().to(tokenEndpointUrl.toString());
+    public void doTokenRequest(String token) {
+        try {
+            HttpClient client = new DefaultHttpClient();
+            HttpGet get = new HttpGet(Urls.identityProviderRetrieveToken(BASE_URI, getProviderId(), getRealm().getName()));
 
-        grantPage.assertCurrent();
-        grantPage.accept();
+            get.setHeader("Authorization", "Bearer " + token);
 
-        assertNotNull(driver.getPageSource());
+            HttpResponse response = client.execute(get);
+            assertEquals(200, response.getStatusLine().getStatusCode());
 
-        doAssertTokenRetrieval(driver.getPageSource());
+            assertNotNull(IOUtils.toString(response.getEntity().getContent()));
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
     }
 
     private void configureRetrieveToken(ClientModel clientModel, String providerId, boolean retrieveToken) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
index eda8b69..a1f8245 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
@@ -30,8 +30,8 @@ import org.keycloak.broker.oidc.OIDCIdentityProviderFactory;
 import org.keycloak.broker.saml.SAMLIdentityProvider;
 import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
 import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
-import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientIdentityProviderMappingModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -122,7 +122,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
     public void testApplicationIdentityProviders() throws Exception {
         RealmModel realm = installTestRealm();
 
-        ClientModel client = realm.findClient("test-app-with-allowed-providers");
+        ClientModel client = realm.getClientByClientId("test-app-with-allowed-providers");
         List<ClientIdentityProviderMappingModel> identityProviders = client.getIdentityProviders();
 
         assertEquals(1, identityProviders.size());
@@ -136,7 +136,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
 
         client.updateIdentityProviders(identityProviders);
 
-        client = realm.findClientById(client.getId());
+        client = realm.getClientById(client.getId());
         identityProviders = client.getIdentityProviders();
 
         assertEquals(0, identityProviders.size());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
index b661d5a..fc8bf15 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
@@ -27,7 +27,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.enums.SslRequired;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
@@ -85,7 +85,7 @@ public class CompositeRoleTest {
             realmRole1User.updateCredential(UserCredentialModel.password("password"));
             realmRole1User.grantRole(realmRole1);
 
-            final ApplicationModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION");
+            final ClientModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION");
             realmComposite1Application.setFullScopeAllowed(false);
             realmComposite1Application.setEnabled(true);
             realmComposite1Application.addScopeMapping(realmComposite1);
@@ -94,7 +94,7 @@ public class CompositeRoleTest {
             realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout");
             realmComposite1Application.setSecret("password");
 
-            final ApplicationModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION");
+            final ClientModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION");
             realmRole1Application.setFullScopeAllowed(false);
             realmRole1Application.setEnabled(true);
             realmRole1Application.addScopeMapping(realmRole1);
@@ -104,7 +104,7 @@ public class CompositeRoleTest {
             realmRole1Application.setSecret("password");
 
 
-            final ApplicationModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION");
+            final ClientModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION");
             appRoleApplication.setFullScopeAllowed(false);
             appRoleApplication.setEnabled(true);
             appRoleApplication.addRedirectUri("http://localhost:8081/app/*");
@@ -127,7 +127,7 @@ public class CompositeRoleTest {
             realmAppRoleUser.updateCredential(UserCredentialModel.password("password"));
             realmAppRoleUser.grantRole(appRole2);
 
-            final ApplicationModel appCompositeApplication = new ApplicationManager(manager).createApplication(realm, "APP_COMPOSITE_APPLICATION");
+            final ClientModel appCompositeApplication = new ApplicationManager(manager).createApplication(realm, "APP_COMPOSITE_APPLICATION");
             appCompositeApplication.setFullScopeAllowed(false);
             appCompositeApplication.setEnabled(true);
             appCompositeApplication.addRedirectUri("http://localhost:8081/app/*");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java
index af994f4..2580242 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java
@@ -21,7 +21,7 @@ import org.keycloak.adapters.HttpClientBuilder;
 import org.keycloak.events.Details;
 import org.keycloak.federation.kerberos.CommonKerberosConfig;
 import org.keycloak.constants.KerberosConstants;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.LDAPConstants;
 import org.keycloak.models.ProtocolMapperModel;
@@ -183,7 +183,7 @@ public abstract class AbstractKerberosTest {
                         true, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
                         true, false);
 
-                ApplicationModel kerberosApp = appRealm.getApplicationByName("kerberos-app");
+                ClientModel kerberosApp = appRealm.getClientByClientId("kerberos-app");
                 kerberosApp.addProtocolMapper(protocolMapper);
             }
 
@@ -202,7 +202,7 @@ public abstract class AbstractKerberosTest {
 
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                ApplicationModel kerberosApp = appRealm.getApplicationByName("kerberos-app");
+                ClientModel kerberosApp = appRealm.getClientByClientId("kerberos-app");
                 ProtocolMapperModel toRemove = kerberosApp.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME);
                 kerberosApp.removeProtocolMapper(toRemove);
             }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsBasicAuthTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsBasicAuthTest.java
index 252a253..1b5a249 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsBasicAuthTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsBasicAuthTest.java
@@ -19,10 +19,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExternalResource;
 import org.keycloak.adapters.HttpClientBuilder;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.Constants;
 import org.keycloak.testsuite.rule.KeycloakRule;
@@ -44,7 +42,7 @@ public class JaxrsBasicAuthTest {
 
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            ApplicationModel app = appRealm.addApplication("jaxrs-app");
+            ClientModel app = appRealm.addClient("jaxrs-app");
             app.setEnabled(true);
             app.setSecret("password");
             app.setFullScopeAllowed(true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java
index 2ff046c..5d59735 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/jaxrs/JaxrsFilterTest.java
@@ -23,7 +23,7 @@ import org.keycloak.TokenIdGenerator;
 import org.keycloak.adapters.CorsHeaders;
 import org.keycloak.constants.AdapterConstants;
 import org.keycloak.adapters.HttpClientBuilder;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -53,7 +53,7 @@ public class JaxrsFilterTest {
 
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            ApplicationModel app = appRealm.addApplication("jaxrs-app");
+            ClientModel app = appRealm.addClient("jaxrs-app");
             app.setEnabled(true);
             RoleModel role = app.addRole("jaxrs-app-user");
             UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java
index a2ebb91..e7440ab 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java
@@ -4,10 +4,9 @@ import org.junit.Assert;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.FederatedIdentityModel;
 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;
@@ -16,7 +15,6 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
-import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
@@ -153,15 +151,6 @@ public class AdapterTest extends AbstractModelTest {
     }
 
     @Test
-    public void testOAuthClient() throws Exception {
-        test1CreateRealm();
-
-        RepresentationToModel.createOAuthClient(null, "oauth-client", realmModel);
-        OAuthClientModel oauth = realmModel.getOAuthClient("oauth-client");
-        Assert.assertNotNull(oauth);
-    }
-
-    @Test
     public void testDeleteUser() throws Exception {
         test1CreateRealm();
 
@@ -172,7 +161,7 @@ public class AdapterTest extends AbstractModelTest {
         RoleModel testRole = realmModel.addRole("test");
         user.grantRole(testRole);
 
-        ApplicationModel app = realmModel.addApplication("test-app");
+        ClientModel app = realmModel.addClient("test-app");
         RoleModel appRole = app.addRole("test");
         user.grantRole(appRole);
 
@@ -197,9 +186,9 @@ public class AdapterTest extends AbstractModelTest {
 
         UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
 
-        OAuthClientModel client = realmModel.addOAuthClient("client");
+        ClientModel client = realmModel.addClient("client");
 
-        ApplicationModel app = realmModel.addApplication("test-app");
+        ClientModel app = realmModel.addClient("test-app");
 
         RoleModel appRole = app.addRole("test");
         user.grantRole(appRole);
@@ -208,9 +197,9 @@ public class AdapterTest extends AbstractModelTest {
         RoleModel realmRole = realmModel.addRole("test");
         app.addScopeMapping(realmRole);
 
-        Assert.assertTrue(realmModel.removeApplication(app.getId()));
-        Assert.assertFalse(realmModel.removeApplication(app.getId()));
-        assertNull(realmModel.getApplicationById(app.getId()));
+        Assert.assertTrue(realmModel.removeClient(app.getId()));
+        Assert.assertFalse(realmModel.removeClient(app.getId()));
+        assertNull(realmModel.getClientById(app.getId()));
     }
 
 
@@ -225,9 +214,9 @@ public class AdapterTest extends AbstractModelTest {
         cred.setValue("password");
         user.updateCredential(cred);
 
-        OAuthClientModel client = realmModel.addOAuthClient("client");
+        ClientModel client = realmModel.addClient("client");
 
-        ApplicationModel app = realmModel.addApplication("test-app");
+        ClientModel app = realmModel.addClient("test-app");
 
         RoleModel appRole = app.addRole("test");
         user.grantRole(appRole);
@@ -255,9 +244,9 @@ public class AdapterTest extends AbstractModelTest {
 
         UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
 
-        OAuthClientModel client = realmModel.addOAuthClient("client");
+        ClientModel client = realmModel.addClient("client");
 
-        ApplicationModel app = realmModel.addApplication("test-app");
+        ClientModel app = realmModel.addClient("test-app");
 
         RoleModel appRole = app.addRole("test");
         user.grantRole(appRole);
@@ -268,7 +257,7 @@ public class AdapterTest extends AbstractModelTest {
 
         commit();
         realmModel = model.getRealm("JUGGLER");
-        app = realmModel.getApplicationByName("test-app");
+        app = realmModel.getClientByClientId("test-app");
 
         Assert.assertTrue(realmModel.removeRoleById(realmRole.getId()));
         Assert.assertFalse(realmModel.removeRoleById(realmRole.getId()));
@@ -458,7 +447,7 @@ public class AdapterTest extends AbstractModelTest {
         assertRolesEquals(found, realmUserRole);
 
         // Test app roles
-        ApplicationModel application = realmModel.addApplication("app1");
+        ClientModel application = realmModel.addClient("app1");
         application.addRole("user");
         application.addRole("bar");
         Set<RoleModel> appRoles = application.getRoles();
@@ -506,23 +495,23 @@ public class AdapterTest extends AbstractModelTest {
         test1CreateRealm();
         RoleModel realmRole = realmModel.addRole("realm");
 
-        ApplicationModel app1 = realmModel.addApplication("app1");
+        ClientModel app1 = realmModel.addClient("app1");
         RoleModel appRole = app1.addRole("app");
 
-        ApplicationModel app2 = realmModel.addApplication("app2");
+        ClientModel app2 = realmModel.addClient("app2");
         app2.addScopeMapping(realmRole);
         app2.addScopeMapping(appRole);
 
-        OAuthClientModel client = realmModel.addOAuthClient("client");
+        ClientModel client = realmModel.addClient("client");
         client.addScopeMapping(realmRole);
         client.addScopeMapping(appRole);
 
         commit();
 
         realmModel = model.getRealmByName("JUGGLER");
-        app1 = realmModel.getApplicationByName("app1");
-        app2 = realmModel.getApplicationByName("app2");
-        client = realmModel.getOAuthClient("client");
+        app1 = realmModel.getClientByClientId("app1");
+        app2 = realmModel.getClientByClientId("app2");
+        client = realmModel.getClientByClientId("client");
 
         Set<RoleModel> scopeMappings = app2.getScopeMappings();
         Assert.assertEquals(2, scopeMappings.size());
@@ -565,14 +554,14 @@ public class AdapterTest extends AbstractModelTest {
 
     @Test
     public void testAppNameCollisions() throws Exception {
-        realmManager.createRealm("JUGGLER1").addApplication("app1");
-        realmManager.createRealm("JUGGLER2").addApplication("app1");
+        realmManager.createRealm("JUGGLER1").addClient("app1");
+        realmManager.createRealm("JUGGLER2").addClient("app1");
 
         commit();
 
         // Try to create app with duplicate name
         try {
-            realmManager.getRealmByName("JUGGLER1").addApplication("app1");
+            realmManager.getRealmByName("JUGGLER1").addClient("app1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -580,10 +569,10 @@ public class AdapterTest extends AbstractModelTest {
         commit(true);
 
         // Ty to rename app to duplicate name
-        realmManager.getRealmByName("JUGGLER1").addApplication("app2");
+        realmManager.getRealmByName("JUGGLER1").addClient("app2");
         commit();
         try {
-            realmManager.getRealmByName("JUGGLER1").getApplicationByName("app2").setName("app1");
+            realmManager.getRealmByName("JUGGLER1").getClientByClientId("app2").setClientId("app1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -594,14 +583,14 @@ public class AdapterTest extends AbstractModelTest {
 
     @Test
     public void testClientNameCollisions() throws Exception {
-        realmManager.createRealm("JUGGLER1").addOAuthClient("client1");
-        realmManager.createRealm("JUGGLER2").addOAuthClient("client1");
+        realmManager.createRealm("JUGGLER1").addClient("client1");
+        realmManager.createRealm("JUGGLER2").addClient("client1");
 
         commit();
 
         // Try to create app with duplicate name
         try {
-            realmManager.getRealmByName("JUGGLER1").addOAuthClient("client1");
+            realmManager.getRealmByName("JUGGLER1").addClient("client1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -609,10 +598,10 @@ public class AdapterTest extends AbstractModelTest {
         commit(true);
 
         // Ty to rename app to duplicate name
-        realmManager.getRealmByName("JUGGLER1").addOAuthClient("client2");
+        realmManager.getRealmByName("JUGGLER1").addClient("client2");
         commit();
         try {
-            realmManager.getRealmByName("JUGGLER1").getOAuthClient("client2").setClientId("client1");
+            realmManager.getRealmByName("JUGGLER1").addClient("client2").setClientId("client1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -691,14 +680,14 @@ public class AdapterTest extends AbstractModelTest {
     @Test
     public void testAppRoleCollisions() throws Exception {
         realmManager.createRealm("JUGGLER1").addRole("role1");
-        realmManager.getRealmByName("JUGGLER1").addApplication("app1").addRole("role1");
-        realmManager.getRealmByName("JUGGLER1").addApplication("app2").addRole("role1");
+        realmManager.getRealmByName("JUGGLER1").addClient("app1").addRole("role1");
+        realmManager.getRealmByName("JUGGLER1").addClient("app2").addRole("role1");
 
         commit();
 
         // Try to add role with same name
         try {
-            realmManager.getRealmByName("JUGGLER1").getApplicationByName("app1").addRole("role1");
+            realmManager.getRealmByName("JUGGLER1").getClientByClientId("app1").addRole("role1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -706,10 +695,10 @@ public class AdapterTest extends AbstractModelTest {
         commit(true);
 
         // Ty to rename role to duplicate name
-        realmManager.getRealmByName("JUGGLER1").getApplicationByName("app1").addRole("role2");
+        realmManager.getRealmByName("JUGGLER1").getClientByClientId("app1").addRole("role2");
         commit();
         try {
-            realmManager.getRealmByName("JUGGLER1").getApplicationByName("app1").getRole("role2").setName("role1");
+            realmManager.getRealmByName("JUGGLER1").getClientByClientId("app1").getRole("role2").setName("role1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -721,8 +710,8 @@ public class AdapterTest extends AbstractModelTest {
     @Test
     public void testRealmRoleCollisions() throws Exception {
         realmManager.createRealm("JUGGLER1").addRole("role1");
-        realmManager.getRealmByName("JUGGLER1").addApplication("app1").addRole("role1");
-        realmManager.getRealmByName("JUGGLER1").addApplication("app2").addRole("role1");
+        realmManager.getRealmByName("JUGGLER1").addClient("app1").addRole("role1");
+        realmManager.getRealmByName("JUGGLER1").addClient("app2").addRole("role1");
 
         commit();
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
index f565825..1237cfa 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
@@ -3,7 +3,7 @@ package org.keycloak.testsuite.model;
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.testsuite.rule.KeycloakRule;
@@ -23,7 +23,7 @@ public class CacheTest {
             // load up cache
             KeycloakSession session = kc.startSession();
             RealmModel realm = session.realms().getRealmByName("test");
-            ApplicationModel testApp = realm.getApplicationByName("test-app");
+            ClientModel testApp = realm.getClientByClientId("test-app");
             Assert.assertNotNull(testApp);
             appId = testApp.getId();
             Assert.assertTrue(testApp.isEnabled());
@@ -35,7 +35,7 @@ public class CacheTest {
             RealmModel realm = session.realms().getRealmByName("test");
             Assert.assertTrue(realm instanceof org.keycloak.models.cache.RealmAdapter);
             realm.setAccessCodeLifespanLogin(200);
-            ApplicationModel testApp = realm.getApplicationByName("test-app");
+            ClientModel testApp = realm.getClientByClientId("test-app");
             Assert.assertNotNull(testApp);
             testApp.setEnabled(false);
             kc.stopSession(session, true);
@@ -44,7 +44,7 @@ public class CacheTest {
         {
             KeycloakSession session = kc.startSession();
             RealmModel realm = session.realms().getRealmByName("test");
-            ApplicationModel testApp = session.realms().getApplicationById(appId, realm);
+            ClientModel testApp = session.realms().getClientById(appId, realm);
             Assert.assertFalse(testApp.isEnabled());
             kc.stopSession(session, true);
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java
index b99c310..a23e048 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java
@@ -3,7 +3,7 @@ package org.keycloak.testsuite.model;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -58,7 +58,7 @@ public class CompositeRolesModelTest extends AbstractModelTest {
 
         RealmModel realm = realmManager.getRealm("TestComposites");
         UserModel user = realmManager.getSession().users().getUserByUsername(username, realm);
-        ApplicationModel application = realm.getApplicationByName(applicationName);
+        ClientModel application = realm.getClientByClientId(applicationName);
 
         Set<RoleModel> roleMappings = user.getRoleMappings();
         Set<RoleModel> scopeMappings = application.getScopeMappings();
@@ -95,7 +95,7 @@ public class CompositeRolesModelTest extends AbstractModelTest {
         if ("realm".equals(appName)) {
             return realm.getRole(roleName);
         }  else {
-            return realm.getApplicationByName(appName).getRole(roleName);
+            return realm.getClientByClientId(appName).getRole(roleName);
         }
     }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
index e4d20f8..13b019a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
@@ -5,7 +5,6 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 import org.keycloak.constants.KerberosConstants;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.FederatedIdentityModel;
@@ -81,26 +80,23 @@ public class ImportTest extends AbstractModelTest {
         Assert.assertNotNull(user);
         Assert.assertEquals(0,  session.users().getFederatedIdentities(user, realm).size());
 
-        List<ApplicationModel> resources = realm.getApplications();
-        for (ApplicationModel app : resources) {
-            System.out.println("app: " + app.getName());
-        }
-        Assert.assertEquals(5, resources.size());
+        List<ClientModel> resources = realm.getClients();
+        Assert.assertEquals(6, resources.size());
 
         // Test applications imported
-        ApplicationModel application = realm.getApplicationByName("Application");
-        ApplicationModel otherApp = realm.getApplicationByName("OtherApp");
-        ApplicationModel accountApp = realm.getApplicationByName(Constants.ACCOUNT_MANAGEMENT_APP);
-        ApplicationModel nonExisting = realm.getApplicationByName("NonExisting");
+        ClientModel application = realm.getClientByClientId("Application");
+        ClientModel otherApp = realm.getClientByClientId("OtherApp");
+        ClientModel accountApp = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_APP);
+        ClientModel nonExisting = realm.getClientByClientId("NonExisting");
         Assert.assertNotNull(application);
         Assert.assertNotNull(otherApp);
         Assert.assertNull(nonExisting);
-        Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
-        Assert.assertEquals(5, apps.size());
-        Assert.assertTrue(apps.values().contains(application));
-        Assert.assertTrue(apps.values().contains(otherApp));
-        Assert.assertTrue(apps.values().contains(accountApp));
-        realm.getApplications().containsAll(apps.values());
+        Map<String, ClientModel> clients = realm.getClientNameMap();
+        Assert.assertEquals(6, clients.size());
+        Assert.assertTrue(clients.values().contains(application));
+        Assert.assertTrue(clients.values().contains(otherApp));
+        Assert.assertTrue(clients.values().contains(accountApp));
+        realm.getClients().containsAll(clients.values());
 
         Assert.assertEquals(50, application.getNodeReRegistrationTimeout());
         Map<String, Integer> appRegisteredNodes = application.getRegisteredNodes();
@@ -109,8 +105,8 @@ public class ImportTest extends AbstractModelTest {
         Assert.assertTrue(20 == appRegisteredNodes.get("172.10.15.20"));
 
         // Test finding applications by ID
-        Assert.assertNull(realm.getApplicationById("982734"));
-        Assert.assertEquals(application, realm.getApplicationById(application.getId()));
+        Assert.assertNull(realm.getClientById("982734"));
+        Assert.assertEquals(application, realm.getClientById(application.getId()));
 
 
         // Test role mappings
@@ -139,7 +135,7 @@ public class ImportTest extends AbstractModelTest {
         Assert.assertEquals("app-admin", appRoles.iterator().next().getName());
 
         // Test client
-        ClientModel oauthClient = realm.findClient("oauthclient");
+        ClientModel oauthClient = realm.getClientByClientId("oauthclient");
         Assert.assertEquals("clientpassword", oauthClient.getSecret());
         Assert.assertEquals(true, oauthClient.isEnabled());
         Assert.assertNotNull(oauthClient);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java
index 023a6fb..1a4c660 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java
@@ -3,8 +3,7 @@ package org.keycloak.testsuite.model;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
@@ -66,17 +65,17 @@ public class MultipleRealmsTest extends AbstractModelTest {
         Assert.assertEquals(realm2, model.getRealm("id2"));
         Assert.assertEquals(realm2, model.getRealmByName("realm2"));
 
-        ApplicationModel r1app1 = realm1.getApplicationByName("app1");
-        ApplicationModel r1app2 = realm1.getApplicationByName("app2");
-        ApplicationModel r2app1 = realm2.getApplicationByName("app1");
-        ApplicationModel r2app2 = realm2.getApplicationByName("app2");
+        ClientModel r1app1 = realm1.getClientByClientId("app1");
+        ClientModel r1app2 = realm1.getClientByClientId("app2");
+        ClientModel r2app1 = realm2.getClientByClientId("app1");
+        ClientModel r2app2 = realm2.getClientByClientId("app2");
 
-        Assert.assertEquals(r1app1, realm1.getApplicationById(r1app1.getId()));
-        Assert.assertNull(realm2.getApplicationById(r1app1.getId()));
+        Assert.assertEquals(r1app1, realm1.getClientById(r1app1.getId()));
+        Assert.assertNull(realm2.getClientById(r1app1.getId()));
 
-        OAuthClientModel r2cl1 = realm2.getOAuthClient("cl1");
-        Assert.assertEquals(r2cl1.getId(), realm2.getOAuthClientById(r2cl1.getId()).getId());
-        Assert.assertNull(realm1.getOAuthClientById(r2cl1.getId()));
+        ClientModel r2cl1 = realm2.getClientByClientId("cl1");
+        Assert.assertEquals(r2cl1.getId(), realm2.getClientById(r2cl1.getId()).getId());
+        Assert.assertNull(realm1.getClientByClientId(r2cl1.getId()));
 
         RoleModel r1App1Role = r1app1.getRole("app1Role1");
         Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId()));
@@ -88,8 +87,8 @@ public class MultipleRealmsTest extends AbstractModelTest {
     }
 
     private void createObjects(RealmModel realm) {
-        ApplicationModel app1 = realm.addApplication("app1");
-        realm.addApplication("app2");
+        ClientModel app1 = realm.addClient("app1");
+        realm.addClient("app2");
 
         realmManager.getSession().users().addUser(realm, "user1");
         realmManager.getSession().users().addUser(realm, "user2");
@@ -100,7 +99,7 @@ public class MultipleRealmsTest extends AbstractModelTest {
         app1.addRole("app1Role1");
         app1.addScopeMapping(realm.getRole("role1"));
 
-        realm.addOAuthClient("cl1");
+        realm.addClient("cl1");
     }
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
index d01dc7f..b70e3ff 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
@@ -62,7 +62,7 @@ public class UserModelTest extends AbstractModelTest {
     @Test
     public void webOriginSetTest() {
         RealmModel realm = realmManager.createRealm("original");
-        ClientModel client = realm.addApplication("user");
+        ClientModel client = realm.addClient("user");
 
         Assert.assertTrue(client.getWebOrigins().isEmpty());
 
@@ -78,7 +78,7 @@ public class UserModelTest extends AbstractModelTest {
         client.removeWebOrigin("origin-1");
         Assert.assertTrue(client.getWebOrigins().isEmpty());
 
-        client = realm.addOAuthClient("oauthclient2");
+        client = realm.addClient("oauthclient2");
 
         Assert.assertTrue(client.getWebOrigins().isEmpty());
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
index 35cf6fc..b706203 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
@@ -83,7 +83,7 @@ public class UserSessionProviderTest {
         List<ClientSessionModel> clientSessions = session.sessions().getUserSession(realm, sessions[0].getId()).getClientSessions();
         assertEquals(2, clientSessions.size());
 
-        String client1 = realm.findClient("test-app").getId();
+        String client1 = realm.getClientByClientId("test-app").getId();
 
         ClientSessionModel session1;
 
@@ -94,7 +94,7 @@ public class UserSessionProviderTest {
         }
 
         assertEquals(null, session1.getAction());
-        assertEquals(realm.findClient("test-app").getClientId(), session1.getClient().getClientId());
+        assertEquals(realm.getClientByClientId("test-app").getClientId(), session1.getClient().getClientId());
         assertEquals(sessions[0].getId(), session1.getUserSession().getId());
         assertEquals("http://redirect", session1.getRedirectUri());
         assertEquals("state", session1.getNote(OIDCLoginProtocol.STATE_PARAM));
@@ -220,7 +220,7 @@ public class UserSessionProviderTest {
             }
         }
 
-        session.sessions().onClientRemoved(realm, realm.findClient("third-party"));
+        session.sessions().onClientRemoved(realm, realm.getClientByClientId("third-party"));
         resetSession();
 
         for (String c : clientSessionsRemoved) {
@@ -230,7 +230,7 @@ public class UserSessionProviderTest {
             assertNotNull(session.sessions().getClientSession(realm, c));
         }
 
-        session.sessions().onClientRemoved(realm, realm.findClient("test-app"));
+        session.sessions().onClientRemoved(realm, realm.getClientByClientId("test-app"));
         resetSession();
 
         for (String c : clientSessionsRemoved) {
@@ -244,7 +244,7 @@ public class UserSessionProviderTest {
     @Test
     public void testRemoveUserSessionsByExpired() {
         session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm));
-        ClientModel client = realm.findClient("test-app");
+        ClientModel client = realm.getClientByClientId("test-app");
 
         try {
             Set<String> expired = new HashSet<String>();
@@ -301,7 +301,7 @@ public class UserSessionProviderTest {
             realm.setAccessCodeLifespanLogin(30);
 
             // Login lifespan is largest
-            String clientSessionId = session.sessions().createClientSession(realm, realm.findClient("test-app")).getId();
+            String clientSessionId = session.sessions().createClientSession(realm, realm.getClientByClientId("test-app")).getId();
             resetSession();
 
             Time.setOffset(25);
@@ -320,7 +320,7 @@ public class UserSessionProviderTest {
             realm.setAccessCodeLifespanUserAction(40);
 
             Time.setOffset(0);
-            clientSessionId = session.sessions().createClientSession(realm, realm.findClient("test-app")).getId();
+            clientSessionId = session.sessions().createClientSession(realm, realm.getClientByClientId("test-app")).getId();
             resetSession();
 
             Time.setOffset(35);
@@ -339,7 +339,7 @@ public class UserSessionProviderTest {
             realm.setAccessCodeLifespan(50);
 
             Time.setOffset(0);
-            clientSessionId = session.sessions().createClientSession(realm, realm.findClient("test-app")).getId();
+            clientSessionId = session.sessions().createClientSession(realm, realm.getClientByClientId("test-app")).getId();
             resetSession();
 
             Time.setOffset(45);
@@ -367,8 +367,8 @@ public class UserSessionProviderTest {
     public void testGetByClient() {
         UserSessionModel[] sessions = createSessions();
 
-        assertSessions(session.sessions().getUserSessions(realm, realm.findClient("test-app")), sessions[0], sessions[1], sessions[2]);
-        assertSessions(session.sessions().getUserSessions(realm, realm.findClient("third-party")), sessions[0]);
+        assertSessions(session.sessions().getUserSessions(realm, realm.getClientByClientId("test-app")), sessions[0], sessions[1], sessions[2]);
+        assertSessions(session.sessions().getUserSessions(realm, realm.getClientByClientId("third-party")), sessions[0]);
     }
 
     @Test
@@ -377,7 +377,7 @@ public class UserSessionProviderTest {
             for (int i = 0; i < 25; i++) {
                 Time.setOffset(i);
                 UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0." + i, "form", false, null, null);
-                ClientSessionModel clientSession = session.sessions().createClientSession(realm, realm.findClient("test-app"));
+                ClientSessionModel clientSession = session.sessions().createClientSession(realm, realm.getClientByClientId("test-app"));
                 clientSession.setUserSession(userSession);
                 clientSession.setRedirectUri("http://redirect");
                 clientSession.setRoles(new HashSet<String>());
@@ -390,11 +390,11 @@ public class UserSessionProviderTest {
 
         resetSession();
 
-        assertPaginatedSession(realm, realm.findClient("test-app"), 0, 1, 1);
-        assertPaginatedSession(realm, realm.findClient("test-app"), 0, 10, 10);
-        assertPaginatedSession(realm, realm.findClient("test-app"), 10, 10, 10);
-        assertPaginatedSession(realm, realm.findClient("test-app"), 20, 10, 5);
-        assertPaginatedSession(realm, realm.findClient("test-app"), 30, 10, 0);
+        assertPaginatedSession(realm, realm.getClientByClientId("test-app"), 0, 1, 1);
+        assertPaginatedSession(realm, realm.getClientByClientId("test-app"), 0, 10, 10);
+        assertPaginatedSession(realm, realm.getClientByClientId("test-app"), 10, 10, 10);
+        assertPaginatedSession(realm, realm.getClientByClientId("test-app"), 20, 10, 5);
+        assertPaginatedSession(realm, realm.getClientByClientId("test-app"), 30, 10, 0);
     }
 
     private void assertPaginatedSession(RealmModel realm, ClientModel client, int start, int max, int expectedSize) {
@@ -416,8 +416,8 @@ public class UserSessionProviderTest {
     public void testGetCountByClient() {
         createSessions();
 
-        assertEquals(3, session.sessions().getActiveUserSessions(realm, realm.findClient("test-app")));
-        assertEquals(1, session.sessions().getActiveUserSessions(realm, realm.findClient("third-party")));
+        assertEquals(3, session.sessions().getActiveUserSessions(realm, realm.getClientByClientId("test-app")));
+        assertEquals(1, session.sessions().getActiveUserSessions(realm, realm.getClientByClientId("third-party")));
     }
 
     @Test
@@ -487,14 +487,14 @@ public class UserSessionProviderTest {
         roles.add("one");
         roles.add("two");
 
-        createClientSession(realm.findClient("test-app"), sessions[0], "http://redirect", "state", roles);
-        createClientSession(realm.findClient("third-party"), sessions[0], "http://redirect", "state", new HashSet<String>());
+        createClientSession(realm.getClientByClientId("test-app"), sessions[0], "http://redirect", "state", roles);
+        createClientSession(realm.getClientByClientId("third-party"), sessions[0], "http://redirect", "state", new HashSet<String>());
 
         sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true, null, null);
-        createClientSession(realm.findClient("test-app"), sessions[1], "http://redirect", "state", new HashSet<String>());
+        createClientSession(realm.getClientByClientId("test-app"), sessions[1], "http://redirect", "state", new HashSet<String>());
 
         sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true, null, null);
-        createClientSession(realm.findClient("test-app"), sessions[2], "http://redirect", "state", new HashSet<String>());
+        createClientSession(realm.getClientByClientId("test-app"), sessions[2], "http://redirect", "state", new HashSet<String>());
 
         resetSession();
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 7120b36..1fd4528 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -32,7 +32,6 @@ import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.Event;
 import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ProtocolMapperModel;
@@ -41,7 +40,6 @@ import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
 import org.keycloak.protocol.oidc.mappers.AddressMapper;
-import org.keycloak.protocol.oidc.mappers.FullNameMapper;
 import org.keycloak.protocol.oidc.mappers.HardcodedClaim;
 import org.keycloak.protocol.oidc.mappers.HardcodedRole;
 import org.keycloak.protocol.oidc.mappers.RoleNameMapper;
@@ -471,7 +469,7 @@ public class AccessTokenTest {
             {
                 KeycloakSession session = keycloakRule.startSession();
                 RealmModel realm = session.realms().getRealmByName("test");
-                ApplicationModel clientModel = realm.getApplicationByName("test-app");
+                ClientModel clientModel = realm.getClientByClientId("test-app");
                 clientModel.setBearerOnly(true);
                 session.getTransaction().commit();
                 session.close();
@@ -485,7 +483,7 @@ public class AccessTokenTest {
             {
                 KeycloakSession session = keycloakRule.startSession();
                 RealmModel realm = session.realms().getRealmByName("test");
-                ApplicationModel clientModel = realm.getApplicationByName("test-app");
+                ClientModel clientModel = realm.getClientByClientId("test-app");
                 clientModel.setBearerOnly(false);
                 session.getTransaction().commit();
                 session.close();
@@ -521,7 +519,7 @@ public class AccessTokenTest {
             {
                 KeycloakSession session = keycloakRule.startSession();
                 RealmModel realm = session.realms().getRealmByName("test");
-                ClientModel clientModel = realm.findClient("test-app");
+                ClientModel clientModel = realm.getClientByClientId("test-app");
                 clientModel.setEnabled(false);
                 session.getTransaction().commit();
                 session.close();
@@ -535,7 +533,7 @@ public class AccessTokenTest {
             {
                 KeycloakSession session = keycloakRule.startSession();
                 RealmModel realm = session.realms().getRealmByName("test");
-                ClientModel clientModel = realm.findClient("test-app");
+                ClientModel clientModel = realm.getClientByClientId("test-app");
                 clientModel.setEnabled(true);
                 session.getTransaction().commit();
                 session.close();
@@ -624,7 +622,7 @@ public class AccessTokenTest {
             user.setAttribute("postal_code", "02115");
             user.setAttribute("country", "USA");
             user.setAttribute("phone", "617-777-6666");
-            ApplicationModel app = realm.getApplicationByName("test-app");
+            ClientModel app = realm.getClientByClientId("test-app");
             ProtocolMapperModel mapper = AddressMapper.createAddressMapper(true, true);
             app.addProtocolMapper(mapper);
             app.addProtocolMapper(HardcodedClaim.create("hard", "hard", "coded", "String", false, null, true, true));
@@ -687,7 +685,7 @@ public class AccessTokenTest {
         {
             KeycloakSession session = keycloakRule.startSession();
             RealmModel realm = session.realms().getRealmByName("test");
-            ApplicationModel app = realm.getApplicationByName("test-app");
+            ClientModel app = realm.getClientByClientId("test-app");
             for (ProtocolMapperModel model : app.getProtocolMappers()) {
                 if (model.getName().equals("address")
                         || model.getName().equals("hard")
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
index 90a0e29..0a70da0 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -96,7 +96,7 @@ public class AuthorizationCodeTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").addRedirectUri(Constants.INSTALLED_APP_URN);
+                appRealm.getClientNameMap().get("test-app").addRedirectUri(Constants.INSTALLED_APP_URN);
             }
         });
         oauth.redirectUri(Constants.INSTALLED_APP_URN);
@@ -115,7 +115,7 @@ public class AuthorizationCodeTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").removeRedirectUri(Constants.INSTALLED_APP_URN);
+                appRealm.getClientNameMap().get("test-app").removeRedirectUri(Constants.INSTALLED_APP_URN);
             }
         });
     }
@@ -125,7 +125,7 @@ public class AuthorizationCodeTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").addRedirectUri(Constants.INSTALLED_APP_URN);
+                appRealm.getClientNameMap().get("test-app").addRedirectUri(Constants.INSTALLED_APP_URN);
             }
         });
         oauth.redirectUri(Constants.INSTALLED_APP_URN);
@@ -147,7 +147,7 @@ public class AuthorizationCodeTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").removeRedirectUri(Constants.INSTALLED_APP_URN);
+                appRealm.getClientNameMap().get("test-app").removeRedirectUri(Constants.INSTALLED_APP_URN);
             }
         });
     }
@@ -157,7 +157,7 @@ public class AuthorizationCodeTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationByName("test-app").addRedirectUri(oauth.getRedirectUri());
+                appRealm.getClientByClientId("test-app").addRedirectUri(oauth.getRedirectUri());
             }
         });
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java
index 9aa884f..7cefa79 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java
@@ -26,7 +26,7 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.RealmModel;
 import org.keycloak.services.managers.RealmManager;
@@ -39,8 +39,6 @@ import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
@@ -51,18 +49,18 @@ public class OAuthRedirectUriTest {
     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            ApplicationModel installedApp = appRealm.addApplication("test-installed");
+            ClientModel installedApp = appRealm.addClient("test-installed");
             installedApp.setEnabled(true);
             installedApp.addRedirectUri(Constants.INSTALLED_APP_URN);
             installedApp.addRedirectUri(Constants.INSTALLED_APP_URL);
             installedApp.setSecret("password");
 
-            ApplicationModel installedApp2 = appRealm.addApplication("test-installed2");
+            ClientModel installedApp2 = appRealm.addClient("test-installed2");
             installedApp2.setEnabled(true);
             installedApp2.addRedirectUri(Constants.INSTALLED_APP_URL + "/myapp");
             installedApp2.setSecret("password");
 
-            ApplicationModel installedApp3 = appRealm.addApplication("test-wildcard");
+            ClientModel installedApp3 = appRealm.addClient("test-wildcard");
             installedApp3.setEnabled(true);
             installedApp3.addRedirectUri("http://example.com/foo/*");
             installedApp3.addRedirectUri("http://localhost:8081/foo/*");
@@ -99,7 +97,7 @@ public class OAuthRedirectUriTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").addRedirectUri("http://localhost:8081/app2");
+                appRealm.getClientNameMap().get("test-app").addRedirectUri("http://localhost:8081/app2");
             }
         });
 
@@ -113,7 +111,7 @@ public class OAuthRedirectUriTest {
             keycloakRule.update(new KeycloakRule.KeycloakSetup() {
                 @Override
                 public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.getApplicationNameMap().get("test-app").removeRedirectUri("http://localhost:8081/app2");
+                    appRealm.getClientNameMap().get("test-app").removeRedirectUri("http://localhost:8081/app2");
                 }
             });
         }
@@ -124,7 +122,7 @@ public class OAuthRedirectUriTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").removeRedirectUri("http://localhost:8081/app/*");
+                appRealm.getClientNameMap().get("test-app").removeRedirectUri("http://localhost:8081/app/*");
             }
         });
 
@@ -138,7 +136,7 @@ public class OAuthRedirectUriTest {
             keycloakRule.update(new KeycloakRule.KeycloakSetup() {
                 @Override
                 public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.getApplicationNameMap().get("test-app").addRedirectUri("http://localhost:8081/app/*");
+                    appRealm.getClientNameMap().get("test-app").addRedirectUri("http://localhost:8081/app/*");
                 }
             });
         }
@@ -149,7 +147,7 @@ public class OAuthRedirectUriTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                appRealm.getApplicationNameMap().get("test-app").removeRedirectUri("http://localhost:8081/app/*");
+                appRealm.getClientNameMap().get("test-app").removeRedirectUri("http://localhost:8081/app/*");
             }
         });
 
@@ -163,7 +161,7 @@ public class OAuthRedirectUriTest {
             keycloakRule.update(new KeycloakRule.KeycloakSetup() {
                 @Override
                 public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.getApplicationNameMap().get("test-app").addRedirectUri("http://localhost:8081/app/*");
+                    appRealm.getClientNameMap().get("test-app").addRedirectUri("http://localhost:8081/app/*");
                 }
             });
         }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
index 7ab2568..90a88e2 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java
@@ -6,7 +6,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
@@ -31,7 +31,7 @@ public class ResourceOwnerPasswordCredentialsGrantTest {
     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            ApplicationModel app = appRealm.addApplication("resource-owner");
+            ClientModel app = appRealm.addClient("resource-owner");
             app.setSecret("secret");
             appRealm.setPasswordCredentialGrantAllowed(true);
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
index 126c465..000eaad 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java
@@ -6,7 +6,7 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.Config;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
@@ -259,7 +259,7 @@ public class SamlBindingTest {
         keycloakRule.update(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                ApplicationModel app = appRealm.getApplicationByName("http://localhost:8081/employee/");
+                ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
                 for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
                     if (mapper.getName().equals("role-list")) {
                         app.removeProtocolMapper(mapper);
@@ -419,7 +419,7 @@ public class SamlBindingTest {
             RealmManager manager = new RealmManager(session);
 
             RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
-            ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
+            ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
index 14a106c..f913c15 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
@@ -3,7 +3,7 @@ package org.keycloak.testsuite.performance;
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.RepresentationToModel;
@@ -70,7 +70,7 @@ public class CreateRealmsWorker implements Worker {
 
         // Add applications
         for (int i=1 ; i<=appsPerRealm ; i++) {
-            ApplicationModel application = realm.addApplication(PerfTestUtils.getApplicationName(realmNumber, i));
+            ClientModel application = realm.addClient(PerfTestUtils.getApplicationName(realmNumber, i));
             for (int j=1 ; j<=rolesPerApp ; j++) {
                 application.addRole(PerfTestUtils.getApplicationRoleName(realmNumber, i, j));
             }
diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/CreateUsersJob.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/CreateUsersJob.java
index 115d5ae..4c1bd01 100755
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/CreateUsersJob.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/CreateUsersJob.java
@@ -1,6 +1,6 @@
 package org.keycloak.test.tools.jobs;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
@@ -26,7 +26,7 @@ public class CreateUsersJob extends UsersJob {
     }
 
     @Override
-    protected void runIteration(KeycloakSession session, RealmModel realm, Map<String, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
+    protected void runIteration(KeycloakSession session, RealmModel realm, Map<String, ClientModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
         String username = prefix + "-" + counter;
         UserModel user = session.users().addUser(realm, username);
         user.setEnabled(true);
diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/DeleteUsersJob.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/DeleteUsersJob.java
index e271108..7e39f94 100755
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/DeleteUsersJob.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/DeleteUsersJob.java
@@ -1,6 +1,6 @@
 package org.keycloak.test.tools.jobs;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
@@ -31,7 +31,7 @@ public class DeleteUsersJob extends UsersJob {
     }
 
     @Override
-    protected void runIteration(KeycloakSession session, RealmModel realm, Map<String, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
+    protected void runIteration(KeycloakSession session, RealmModel realm, Map<String, ClientModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
         session.users().removeUser(realm, users.next());
     }
 }
diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UpdateUsersJob.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UpdateUsersJob.java
index 276b6d8..6068764 100755
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UpdateUsersJob.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UpdateUsersJob.java
@@ -1,6 +1,6 @@
 package org.keycloak.test.tools.jobs;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
@@ -36,7 +36,7 @@ public class UpdateUsersJob extends UsersJob {
     }
 
     @Override
-    protected void runIteration(KeycloakSession session, RealmModel realm, Map<String, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
+    protected void runIteration(KeycloakSession session, RealmModel realm, Map<String, ClientModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
         String username = users.next().getUsername();
 
         // Remove all role mappings first
diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UsersJob.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UsersJob.java
index b58a03b..d2f797a 100755
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UsersJob.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/jobs/UsersJob.java
@@ -1,6 +1,6 @@
 package org.keycloak.test.tools.jobs;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
@@ -61,11 +61,11 @@ public abstract class UsersJob implements Runnable {
             session.getTransaction().begin();
 
             RealmModel realm = new RealmManager(session).getRealmByName(realmName);
-            Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
+            Map<String, ClientModel> apps = realm.getClientNameMap();
 
             Set<RoleModel> realmRoles = realm.getRoles();
             Map<String, Set<RoleModel>> appRoles = new HashMap<String, Set<RoleModel>>();
-            for (Map.Entry<String, ApplicationModel> appEntry : apps.entrySet()) {
+            for (Map.Entry<String, ClientModel> appEntry : apps.entrySet()) {
                 appRoles.put(appEntry.getKey(), appEntry.getValue().getRoles());
             }
 
@@ -86,7 +86,7 @@ public abstract class UsersJob implements Runnable {
 
     protected abstract void before(KeycloakSession keycloakSession);
 
-    protected abstract void runIteration(KeycloakSession session, RealmModel realm, Map<String, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter);
+    protected abstract void runIteration(KeycloakSession session, RealmModel realm, Map<String, ClientModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter);
 
     protected RoleModel findRole(Set<RoleModel> roles, String roleName) {
         for (RoleModel role : roles) {