keycloak-uncached

Merge pull request #524 from patriot1burke/master user

7/15/2014 4:45:30 PM

Changes

model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheModelProviderFactory 2(+0 -2)

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

model/jpa/src/main/resources/META-INF/services/org.keycloak.models.ModelProviderFactory 1(+0 -1)

model/mongo/src/main/resources/META-INF/services/org.keycloak.models.ModelProviderFactory 1(+0 -1)

Details

diff --git a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java b/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
old mode 100644
new mode 100755
index a4aadfd..6f50c4e
--- a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
+++ b/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
@@ -7,7 +7,7 @@ import org.keycloak.audit.EventType;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 
@@ -21,13 +21,13 @@ public class EmailAuditListener implements AuditListener {
     private static final Logger log = Logger.getLogger(EmailAuditListener.class);
 
     private KeycloakSession session;
-    private ModelProvider model;
+    private RealmProvider model;
     private EmailProvider emailProvider;
     private Set<EventType> includedEvents;
 
     public EmailAuditListener(KeycloakSession session, EmailProvider emailProvider, Set<EventType> includedEvents) {
         this.session = session;
-        this.model = session.model();
+        this.model = session.realms();
         this.emailProvider = emailProvider;
         this.includedEvents = includedEvents;
     }
@@ -37,7 +37,7 @@ public class EmailAuditListener implements AuditListener {
         if (includedEvents.contains(event.getEvent())) {
             if (event.getRealmId() != null && event.getUserId() != null) {
                 RealmModel realm = model.getRealm(event.getRealmId());
-                UserModel user = realm.getUserById(event.getUserId());
+                UserModel user = session.users().getUserById(event.getUserId(), realm);
                 if (user != null && user.getEmail() != null && user.isEmailVerified()) {
                     try {
                         emailProvider.setRealm(realm).setUser(user).sendEvent(event);
diff --git a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java
index d3433a9..1ac023f 100755
--- a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java
+++ b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/AbstractModelAuthenticationProvider.java
@@ -3,6 +3,7 @@ package org.keycloak.authentication.model;
 import java.util.Map;
 
 import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
@@ -22,17 +23,23 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
 
     private static final Logger logger = Logger.getLogger(AbstractModelAuthenticationProvider.class);
 
+    protected KeycloakSession keycloakSession;
+
+    protected AbstractModelAuthenticationProvider(KeycloakSession keycloakSession) {
+        this.keycloakSession = keycloakSession;
+    }
+
     @Override
     public AuthUser getUser(RealmModel currentRealm, Map<String, String> config, String username) throws AuthenticationProviderException {
         RealmModel realm = getRealm(currentRealm, config);
-        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
+        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
         return user == null ? null : createAuthenticatedUserInstance(user);
     }
 
     @Override
     public String registerUser(RealmModel currentRealm, Map<String, String> config, UserModel user) throws AuthenticationProviderException {
         RealmModel realm = getRealm(currentRealm, config);
-        UserModel newUser = realm.addUser(user.getUsername());
+        UserModel newUser = keycloakSession.users().addUser(realm, user.getUsername());
         newUser.setFirstName(user.getFirstName());
         newUser.setLastName(user.getLastName());
         newUser.setEmail(user.getEmail());
@@ -43,7 +50,7 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
     @Override
     public AuthProviderStatus validatePassword(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
         RealmModel realm = getRealm(currentRealm, config);
-        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
+        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
 
         boolean result = realm.validatePassword(user, password);
         return result ? AuthProviderStatus.SUCCESS : AuthProviderStatus.INVALID_CREDENTIALS;
@@ -59,7 +66,7 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
             throw new AuthenticationProviderException(error);
         }
 
-        UserModel user = realm.getUser(username);
+        UserModel user = keycloakSession.users().getUserByUsername(username, realm);
         if (user == null) {
             logger.warnf("User '%s' doesn't exists. Skip password update", username);
             return false;
diff --git a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ExternalModelAuthenticationProvider.java b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ExternalModelAuthenticationProvider.java
old mode 100644
new mode 100755
index 17c06ef..e109360
--- a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ExternalModelAuthenticationProvider.java
+++ b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ExternalModelAuthenticationProvider.java
@@ -3,7 +3,6 @@ package org.keycloak.authentication.model;
 import org.keycloak.authentication.AuthProviderConstants;
 import org.keycloak.authentication.AuthenticationProviderException;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 
 import java.util.Arrays;
@@ -17,10 +16,9 @@ import java.util.Map;
  */
 public class ExternalModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
 
-    private ModelProvider model;
 
     public ExternalModelAuthenticationProvider(KeycloakSession session) {
-        this.model = session.model();
+        super(session);
     }
 
     @Override
@@ -40,7 +38,7 @@ public class ExternalModelAuthenticationProvider extends AbstractModelAuthentica
             throw new AuthenticationProviderException("Option '" + AuthProviderConstants.EXTERNAL_REALM_ID + "' not specified in configuration");
         }
 
-        RealmModel realm = model.getRealm(realmId);
+        RealmModel realm = keycloakSession.realms().getRealm(realmId);
         if (realm == null) {
             throw new AuthenticationProviderException("Realm with id '" + realmId + "' doesn't exists");
         }
diff --git a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProvider.java b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProvider.java
old mode 100644
new mode 100755
index e46514d..210d56d
--- a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProvider.java
+++ b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProvider.java
@@ -4,6 +4,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.authentication.AuthProviderConstants;
 
@@ -14,6 +15,10 @@ import org.keycloak.authentication.AuthProviderConstants;
  */
 public class ModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
 
+    public ModelAuthenticationProvider(KeycloakSession keycloakSession) {
+        super(keycloakSession);
+    }
+
     @Override
     public String getName() {
         return AuthProviderConstants.PROVIDER_NAME_MODEL;
diff --git a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProviderFactory.java b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProviderFactory.java
old mode 100644
new mode 100755
index ac8c393..bf699e3
--- a/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProviderFactory.java
+++ b/authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProviderFactory.java
@@ -13,7 +13,7 @@ public class ModelAuthenticationProviderFactory implements AuthenticationProvide
 
     @Override
     public AuthenticationProvider create(KeycloakSession session) {
-        return new ModelAuthenticationProvider();
+        return new ModelAuthenticationProvider(session);
     }
 
     @Override
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
old mode 100644
new mode 100755
index 4c96812..dd3c5dd
--- 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
@@ -22,6 +22,7 @@ import org.keycloak.exportimport.Strategy;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
 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;
@@ -47,7 +48,7 @@ import org.keycloak.representations.idm.UserRepresentation;
  */
 public class ExportUtils {
 
-    public static RealmRepresentation exportRealm(RealmModel realm, boolean includeUsers) {
+    public static RealmRepresentation exportRealm(KeycloakSession session, RealmModel realm, boolean includeUsers) {
         RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
 
         // Audit
@@ -147,10 +148,10 @@ public class ExportUtils {
 
         // Finally users if needed
         if (includeUsers) {
-            List<UserModel> allUsers = realm.getUsers();
+            List<UserModel> allUsers = session.users().getUsers(realm);
             List<UserRepresentation> users = new ArrayList<UserRepresentation>();
             for (UserModel user : allUsers) {
-                UserRepresentation userRep = exportUser(realm, user);
+                UserRepresentation userRep = exportUser(session, realm, user);
                 users.add(userRep);
             }
 
@@ -251,7 +252,7 @@ public class ExportUtils {
      * @param user
      * @return fully exported user representation
      */
-    public static UserRepresentation exportUser(RealmModel realm, UserModel user) {
+    public static UserRepresentation exportUser(KeycloakSession session, RealmModel realm, UserModel user) {
         UserRepresentation userRep = ModelToRepresentation.toRepresentation(user);
 
         // AuthenticationLink
@@ -262,7 +263,7 @@ public class ExportUtils {
         }
 
         // Social links
-        Set<SocialLinkModel> socialLinks = realm.getSocialLinks(user);
+        Set<SocialLinkModel> socialLinks = session.users().getSocialLinks(user, realm);
         List<SocialLinkRepresentation> socialLinkReps = new ArrayList<SocialLinkRepresentation>();
         for (SocialLinkModel socialLink : socialLinks) {
             SocialLinkRepresentation socialLinkRep = exportSocialLink(socialLink);
@@ -338,7 +339,7 @@ public class ExportUtils {
 
     // Streaming API
 
-    public static void exportUsersToStream(RealmModel realm, List<UserModel> usersToExport, ObjectMapper mapper, OutputStream os) throws IOException {
+    public static void exportUsersToStream(KeycloakSession session, RealmModel realm, List<UserModel> usersToExport, ObjectMapper mapper, OutputStream os) throws IOException {
         JsonFactory factory = mapper.getJsonFactory();
         JsonGenerator generator = factory.createJsonGenerator(os, JsonEncoding.UTF8);
         try {
@@ -352,7 +353,7 @@ public class ExportUtils {
             generator.writeStartArray();
 
             for (UserModel user : usersToExport) {
-                UserRepresentation userRep = ExportUtils.exportUser(realm, user);
+                UserRepresentation userRep = ExportUtils.exportUser(session, realm, user);
                 generator.writeObject(userRep);
             }
 
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
old mode 100644
new mode 100755
index e57c750..b1d37ba
--- 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
@@ -2,17 +2,13 @@ package org.keycloak.exportimport.util;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import org.codehaus.jackson.JsonEncoding;
 import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.JsonParser;
 import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.io.SerializedString;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.jboss.logging.Logger;
 import org.keycloak.Config;
@@ -20,10 +16,9 @@ import org.keycloak.exportimport.Strategy;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -46,7 +41,7 @@ public class ImportUtils {
      */
     public static RealmModel importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy) {
         String realmName = rep.getRealm();
-        ModelProvider model = session.model();
+        RealmProvider model = session.realms();
         RealmModel realm = model.getRealmByName(realmName);
 
         if (realm != null) {
@@ -64,7 +59,7 @@ public class ImportUtils {
 
         realm = rep.getId() != null ? model.createRealm(rep.getId(), realmName) : model.createRealm(realmName);
 
-        RepresentationToModel.importRealm(rep, realm);
+        RepresentationToModel.importRealm(session, rep, realm);
 
         refreshMasterAdminApps(model, realm);
 
@@ -72,7 +67,7 @@ public class ImportUtils {
         return realm;
     }
 
-    private static void refreshMasterAdminApps(ModelProvider model, RealmModel realm) {
+    private static void refreshMasterAdminApps(RealmProvider model, RealmModel realm) {
         String adminRealmId = Config.getAdminRealm();
         if (adminRealmId.equals(realm.getId())) {
             // We just imported master realm. All 'masterAdminApps' need to be refreshed
@@ -98,7 +93,7 @@ public class ImportUtils {
     }
 
     // TODO: We need method here, so we are able to refresh masterAdmin applications after import. Should be RealmManager moved to model/api instead?
-    public static void setupMasterAdminManagement(ModelProvider model, RealmModel realm) {
+    public static void setupMasterAdminManagement(RealmProvider model, RealmModel realm) {
         RealmModel adminRealm;
         RoleModel adminRole;
 
@@ -160,7 +155,7 @@ public class ImportUtils {
 
     // Assuming that it's invoked inside transaction
     public static void importUsersFromStream(KeycloakSession session, String realmName, ObjectMapper mapper, InputStream is) throws IOException {
-        ModelProvider model = session.model();
+        RealmProvider model = session.realms();
         JsonFactory factory = mapper.getJsonFactory();
         JsonParser parser = factory.createJsonParser(is);
         try {
@@ -188,7 +183,7 @@ public class ImportUtils {
                         parser.nextToken();
                     }
 
-                    importUsers(model, realmName, userReps);
+                    importUsers(session, model, realmName, userReps);
 
                     if (parser.getCurrentToken() == JsonToken.END_ARRAY) {
                         parser.nextToken();
@@ -200,11 +195,11 @@ public class ImportUtils {
         }
     }
 
-    private static void importUsers(ModelProvider model, String realmName, List<UserRepresentation> userReps) {
+    private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List<UserRepresentation> userReps) {
         RealmModel realm = model.getRealmByName(realmName);
         Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
         for (UserRepresentation user : userReps) {
-            RepresentationToModel.createUser(realm, user, apps);
+            RepresentationToModel.createUser(session, realm, user, apps);
         }
     }
 
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
old mode 100644
new mode 100755
index a98ee98..392e073
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
@@ -28,7 +28,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
 
             @Override
             public void run(KeycloakSession session) {
-                List<RealmModel> realms = session.model().getRealms();
+                List<RealmModel> realms = session.realms().getRealms();
                 holder.realms = realms;
             }
 
@@ -49,15 +49,15 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
 
             @Override
             public void run(KeycloakSession session) throws IOException {
-                RealmModel realm = session.model().getRealmByName(realmName);
-                RealmRepresentation rep = ExportUtils.exportRealm(realm, exportUsersIntoSameFile);
+                RealmModel realm = session.realms().getRealmByName(realmName);
+                RealmRepresentation rep = ExportUtils.exportRealm(session, realm, exportUsersIntoSameFile);
                 writeRealm(realmName + "-realm.json", rep);
                 logger.info("Realm '" + realmName + "' - data exported");
 
                 // Count total number of users
                 if (!exportUsersIntoSameFile) {
                     // TODO: getUsersCount method on model
-                    usersHolder.totalCount = realm.getUsers().size();
+                    usersHolder.totalCount = session.users().getUsers(realm).size();
                 }
             }
 
@@ -81,12 +81,12 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
 
                     @Override
                     public void run(KeycloakSession session) throws IOException {
-                        RealmModel realm = session.model().getRealmByName(realmName);
+                        RealmModel realm = session.realms().getRealmByName(realmName);
                         // TODO: pagination
-                        List<UserModel> users = realm.getUsers();
+                        List<UserModel> users = session.users().getUsers(realm);
                         usersHolder.users = users.subList(usersHolder.currentPageStart, usersHolder.currentPageEnd);
 
-                        writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", realm, usersHolder.users);
+                        writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
 
                         logger.info("Users " + usersHolder.currentPageStart + "-" + usersHolder.currentPageEnd + " exported");
                     }
@@ -100,7 +100,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
 
     protected abstract void writeRealm(String fileName, RealmRepresentation rep) throws IOException;
 
-    protected abstract void writeUsers(String fileName, RealmModel realm, List<UserModel> users) throws IOException;
+    protected abstract void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException;
 
     public static class RealmsHolder {
         List<RealmModel> realms;
diff --git a/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java b/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
old mode 100644
new mode 100755
index 48dcf56..469507f
--- a/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
+++ b/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
@@ -7,6 +7,7 @@ import java.util.List;
 
 import org.keycloak.exportimport.util.ExportUtils;
 import org.keycloak.exportimport.util.MultipleStepsExportProvider;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -61,10 +62,10 @@ public class DirExportProvider extends MultipleStepsExportProvider {
     }
 
     @Override
-    protected void writeUsers(String fileName, RealmModel realm, List<UserModel> users) throws IOException {
+    protected void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException {
         File file = new File(this.rootDirectory, fileName);
         FileOutputStream os = new FileOutputStream(file);
-        ExportUtils.exportUsersToStream(realm, users, JsonSerialization.prettyMapper, os);
+        ExportUtils.exportUsersToStream(session, realm, users, JsonSerialization.prettyMapper, os);
     }
 
     @Override
diff --git a/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
old mode 100644
new mode 100755
index bd799b9..a27f086
--- a/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
+++ b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
@@ -42,10 +42,10 @@ public class SingleFileExportProvider implements ExportProvider {
 
             @Override
             public void run(KeycloakSession session) throws IOException {
-                List<RealmModel> realms = session.model().getRealms();
+                List<RealmModel> realms = session.realms().getRealms();
                 List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
                 for (RealmModel realm : realms) {
-                    reps.add(ExportUtils.exportRealm(realm, true));
+                    reps.add(ExportUtils.exportRealm(session, realm, true));
                 }
 
                 writeToFile(reps);
@@ -62,8 +62,8 @@ public class SingleFileExportProvider implements ExportProvider {
 
             @Override
             public void run(KeycloakSession session) throws IOException {
-                RealmModel realm = session.model().getRealmByName(realmName);
-                RealmRepresentation realmRep = ExportUtils.exportRealm(realm, true);
+                RealmModel realm = session.realms().getRealmByName(realmName);
+                RealmRepresentation realmRep = ExportUtils.exportRealm(session, realm, true);
                 writeToFile(realmRep);
             }
 
diff --git a/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProvider.java b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProvider.java
old mode 100644
new mode 100755
index ac0e0df..e60c7ee
--- a/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProvider.java
+++ b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProvider.java
@@ -12,6 +12,7 @@ import de.idyl.winzipaes.impl.AESEncrypterBC;
 import org.jboss.logging.Logger;
 import org.keycloak.exportimport.util.ExportUtils;
 import org.keycloak.exportimport.util.MultipleStepsExportProvider;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -53,9 +54,9 @@ public class ZipExportProvider extends MultipleStepsExportProvider {
     }
 
     @Override
-    protected void writeUsers(String fileName, RealmModel realm, List<UserModel> users) throws IOException {
+    protected void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException {
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        ExportUtils.exportUsersToStream(realm, users, JsonSerialization.mapper, stream);
+        ExportUtils.exportUsersToStream(session, realm, users, JsonSerialization.mapper, stream);
 
         byte[] byteArray = stream.toByteArray();
         ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
index e7d9636..ee84cc6 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
@@ -124,7 +124,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
                 attributes.put("totp", new TotpBean(user, baseUri));
                 break;
             case SOCIAL:
-                attributes.put("social", new AccountSocialBean(realm, user, uriInfo.getBaseUri()));
+                attributes.put("social", new AccountSocialBean(session, realm, user, uriInfo.getBaseUri()));
                 break;
             case LOG:
                 attributes.put("log", new LogBean(events));
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java
index 074174f..ad2786c 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java
@@ -8,6 +8,7 @@ import java.util.Set;
 
 import javax.ws.rs.core.UriBuilder;
 
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
@@ -22,13 +23,15 @@ public class AccountSocialBean {
 
     private final List<SocialLinkEntry> socialLinks;
     private final boolean removeLinkPossible;
+    private final KeycloakSession session;
 
-    public AccountSocialBean(RealmModel realm, UserModel user, URI baseUri) {
+    public AccountSocialBean(KeycloakSession session, RealmModel realm, UserModel user, URI baseUri) {
+        this.session = session;
         URI accountSocialUpdateUri = Urls.accountSocialUpdate(baseUri, realm.getName());
         this.socialLinks = new LinkedList<SocialLinkEntry>();
 
         Map<String, String> socialConfig = realm.getSocialConfig();
-        Set<SocialLinkModel> userSocialLinks = realm.getSocialLinks(user);
+        Set<SocialLinkModel> userSocialLinks = session.users().getSocialLinks(user, realm);
 
         int availableLinks = 0;
         if (socialConfig != null && !socialConfig.isEmpty()) {
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 00e2b9b..33ee8e2 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -1,6 +1,5 @@
 package org.keycloak.models;
 
-import java.util.List;
 import java.util.Set;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java b/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
old mode 100644
new mode 100755
index 2297eed..6db19a7
--- a/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
@@ -1,11 +1,11 @@
 package org.keycloak.models.entities;
 
+import org.keycloak.models.UserModel;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import org.keycloak.models.UserModel;
-
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
index 4a4f429..16a5a67 100755
--- a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
+++ b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
@@ -2,8 +2,6 @@ package org.keycloak.models;
 
 import org.keycloak.provider.Provider;
 
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -29,7 +27,7 @@ public interface KeycloakSession {
      * @return
      * @throws IllegalStateException if transaction is not active
      */
-    ModelProvider model();
+    RealmProvider realms();
 
     /**
      * Returns a managed provider instance.  Will start a provider transaction.  This transaction is managed by the KeycloakSession
@@ -42,4 +40,5 @@ public interface KeycloakSession {
 
     void close();
 
+    UserProvider users();
 }
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 2092f72..d515c98 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -110,18 +110,6 @@ public interface RealmModel extends RoleContainerModel {
 
     boolean validateTOTP(UserModel user, String password, String token);
 
-    UserModel getUser(String name);
-
-    UserModel getUserByEmail(String email);
-
-    UserModel getUserById(String name);
-
-    UserModel addUser(String id, String username, boolean addDefaultRoles);
-
-    UserModel addUser(String username);
-
-    boolean removeUser(String name);
-
     RoleModel getRoleById(String id);
 
     List<String> getDefaultRoles();
@@ -147,16 +135,6 @@ public interface RealmModel extends RoleContainerModel {
 
     void updateRequiredCredentials(Set<String> creds);
 
-    UserModel getUserBySocialLink(SocialLinkModel socialLink);
-
-    Set<SocialLinkModel> getSocialLinks(UserModel user);
-
-    SocialLinkModel getSocialLink(UserModel user, String socialProvider);
-
-    void addSocialLink(UserModel user, SocialLinkModel socialLink);
-
-    boolean removeSocialLink(UserModel user, String socialProvider);
-
     boolean isSocial();
 
     void setSocial(boolean social);
@@ -165,12 +143,6 @@ public interface RealmModel extends RoleContainerModel {
 
     void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin);
 
-    List<UserModel> getUsers();
-
-    List<UserModel> searchForUser(String search);
-
-    List<UserModel> searchForUserByAttributes(Map<String, String> attributes);
-
     OAuthClientModel addOAuthClient(String name);
 
     OAuthClientModel addOAuthClient(String id, String name);
diff --git a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
index 2cad371..f8d0000 100755
--- a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
@@ -1,6 +1,5 @@
 package org.keycloak.models;
 
-import java.util.List;
 import java.util.Set;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java b/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java
index 0bfd293..6515ab0 100755
--- a/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java
@@ -1,8 +1,5 @@
 package org.keycloak.models;
 
-import java.util.List;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
diff --git a/model/api/src/main/java/org/keycloak/models/UserProvider.java b/model/api/src/main/java/org/keycloak/models/UserProvider.java
index f4e2bbd..b5a9a26 100755
--- a/model/api/src/main/java/org/keycloak/models/UserProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserProvider.java
@@ -13,12 +13,13 @@ import java.util.Set;
 public interface UserProvider extends Provider {
     // Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
 
-    KeycloakTransaction getTransaction();
-
     UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles);
     UserModel addUser(RealmModel realm, String username);
     boolean removeUser(RealmModel realm, String name);
 
+    public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink);
+    public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider);
+
     UserModel getUserById(String id, RealmModel realm);
     UserModel getUserByUsername(String username, RealmModel realm);
     UserModel getUserByEmail(String email, RealmModel realm);
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionModel.java b/model/api/src/main/java/org/keycloak/models/UserSessionModel.java
index ada5899..a0aa6a5 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSessionModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionModel.java
@@ -1,7 +1,6 @@
 package org.keycloak.models;
 
 import java.util.List;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
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 fa643b3..fb33ca1 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
@@ -3,8 +3,6 @@ package org.keycloak.models;
 import org.keycloak.provider.Provider;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/api/src/main/java/org/keycloak/models/UserSpi.java b/model/api/src/main/java/org/keycloak/models/UserSpi.java
new file mode 100755
index 0000000..e68299c
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/UserSpi.java
@@ -0,0 +1,27 @@
+package org.keycloak.models;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class UserSpi implements Spi {
+
+    @Override
+    public String getName() {
+        return "user";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return UserProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return UserProviderFactory.class;
+    }
+
+}
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
old mode 100644
new mode 100755
index e32fa3e..4a00ff9
--- 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,5 +1,15 @@
 package org.keycloak.models.utils;
 
+import org.bouncycastle.openssl.PEMWriter;
+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;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.util.PemUtils;
+
 import java.io.IOException;
 import java.io.StringWriter;
 import java.security.Key;
@@ -10,16 +20,6 @@ import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.bouncycastle.openssl.PEMWriter;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.util.PemUtils;
 
 /**
  * Set of helper methods, which are useful in various model implementations.
@@ -122,10 +122,10 @@ public final class KeycloakModelUtils {
      * @param username username or email of user
      * @return found user
      */
-    public static UserModel findUserByNameOrEmail(RealmModel realm, String username) {
-        UserModel user = realm.getUser(username);
+    public static UserModel findUserByNameOrEmail(KeycloakSession session, RealmModel realm, String username) {
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null && username.contains("@")) {
-            user = realm.getUserByEmail(username);
+            user =  session.users().getUserByEmail(username, realm);
         }
         return user;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
old mode 100644
new mode 100755
index 3348d8b..fd7c06b
--- a/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
@@ -1,7 +1,5 @@
 package org.keycloak.models.utils.reflection;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
old mode 100644
new mode 100755
index 2d2c41d..604b83b
--- a/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
@@ -1,6 +1,5 @@
 package org.keycloak.models.utils.reflection;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 /**
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
old mode 100644
new mode 100755
index b031eac..35fe9c9
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -1,15 +1,5 @@
 package org.keycloak.models.utils;
 
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import net.iharder.Base64;
 import org.jboss.logging.Logger;
 import org.keycloak.models.ApplicationModel;
@@ -17,6 +7,7 @@ import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClaimMask;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
@@ -37,11 +28,21 @@ import org.keycloak.representations.idm.ScopeMappingRepresentation;
 import org.keycloak.representations.idm.SocialLinkRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 public class RepresentationToModel {
 
     private static Logger logger = Logger.getLogger(RepresentationToModel.class);
 
-    public static void importRealm(RealmRepresentation rep, RealmModel newRealm) {
+    public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
         newRealm.setName(rep.getRealm());
         if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
         if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
@@ -210,7 +211,7 @@ public class RepresentationToModel {
 
         if (rep.getUsers() != null) {
             for (UserRepresentation userRep : rep.getUsers()) {
-                UserModel user = createUser(newRealm, userRep, appMap);
+                UserModel user = createUser(session, newRealm, userRep, appMap);
             }
         }
     }
@@ -571,8 +572,8 @@ public class RepresentationToModel {
 
     // Users
 
-    public static UserModel createUser(RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
-        UserModel user = newRealm.addUser(userRep.getId(), userRep.getUsername(), false);
+    public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
+        UserModel user = session.users().addUser(newRealm, userRep.getId(), userRep.getUsername(), false);
         user.setEnabled(userRep.isEnabled());
         user.setEmail(userRep.getEmail());
         user.setFirstName(userRep.getFirstName());
@@ -600,7 +601,7 @@ public class RepresentationToModel {
         if (userRep.getSocialLinks() != null) {
             for (SocialLinkRepresentation socialLink : userRep.getSocialLinks()) {
                 SocialLinkModel mappingModel = new SocialLinkModel(socialLink.getSocialProvider(), socialLink.getSocialUserId(), socialLink.getSocialUsername());
-                newRealm.addSocialLink(user, mappingModel);
+                session.users().addSocialLink(newRealm, user, mappingModel);
             }
         }
         if (userRep.getRealmRoles() != null) {
diff --git a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
old mode 100644
new mode 100755
index 6ad707c..706ba92
--- a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1,2 +1,3 @@
-org.keycloak.models.ModelSpi
-org.keycloak.models.UserSessionSpi
\ No newline at end of file
+org.keycloak.models.RealmSpi
+org.keycloak.models.UserSessionSpi
+org.keycloak.models.UserSpi
\ No newline at end of file
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
old mode 100644
new mode 100755
index 57ff498..713d651
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
@@ -1,15 +1,12 @@
 package org.keycloak.models.hybrid;
 
-import org.keycloak.models.realms.Application;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.realms.Application;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
-import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
old mode 100644
new mode 100755
index d0c4b4e..dfaa612
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
@@ -3,7 +3,6 @@ package org.keycloak.models.hybrid;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.realms.Client;
 
 import java.util.Set;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
old mode 100644
new mode 100755
index b971646..1b27841
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
@@ -1,7 +1,6 @@
 package org.keycloak.models.hybrid;
 
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.ModelProvider;
@@ -10,13 +9,11 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.sessions.SessionProvider;
 import org.keycloak.models.users.UserProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.util.Time;
 
 import java.util.HashSet;
 import java.util.List;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
old mode 100644
new mode 100755
index 314ea96..3a644d4
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
@@ -1,12 +1,9 @@
 package org.keycloak.models.hybrid;
 
 import org.keycloak.Config;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.ModelProviderFactory;
-import org.keycloak.models.sessions.SessionProvider;
-import org.keycloak.models.users.UserProvider;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
old mode 100644
new mode 100755
index 1f7bd27..f8b5415
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
@@ -1,11 +1,5 @@
 package org.keycloak.models.hybrid;
 
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserCredentialValueModel;
-import org.keycloak.models.realms.Application;
-import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.OAuthClient;
-import org.keycloak.models.realms.Realm;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
@@ -15,9 +9,14 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.UsernameLoginFailureModel;
+import org.keycloak.models.realms.Application;
+import org.keycloak.models.realms.Client;
+import org.keycloak.models.realms.OAuthClient;
+import org.keycloak.models.realms.Realm;
 import org.keycloak.models.users.Credentials;
 import org.keycloak.models.users.Feature;
 import org.keycloak.models.users.User;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
old mode 100644
new mode 100755
index c6e79ef..7b10d04
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
@@ -1,10 +1,10 @@
 package org.keycloak.models.hybrid;
 
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
 import org.keycloak.models.realms.Application;
 import org.keycloak.models.realms.Realm;
 import org.keycloak.models.realms.Role;
-import org.keycloak.models.RoleContainerModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import java.util.HashSet;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
old mode 100644
new mode 100755
index 35b9539..b496f3f
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
@@ -3,9 +3,6 @@ package org.keycloak.models.hybrid;
 import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.sessions.LoginFailure;
 
-import java.util.LinkedList;
-import java.util.List;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ApplicationAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ApplicationAdapter.java
index 31e938e..65480b5 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ApplicationAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ApplicationAdapter.java
@@ -19,7 +19,7 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
     protected ApplicationModel updated;
     protected CachedApplication cached;
 
-    public ApplicationAdapter(RealmModel cachedRealm, CachedApplication cached, CacheModelProvider cacheSession, KeycloakCache cache) {
+    public ApplicationAdapter(RealmModel cachedRealm, CachedApplication cached, CacheRealmProvider cacheSession, RealmCache cache) {
         super(cachedRealm, cached, cache, cacheSession);
         this.cached = cached;
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
new file mode 100755
index 0000000..1b63d1e
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
@@ -0,0 +1,14 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserProvider;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface CacheUserProvider extends UserProvider {
+    UserProvider getDelegate();
+
+    void registerUserInvalidation(RealmModel realm, String id);
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java
new file mode 100755
index 0000000..4341ad5
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java
@@ -0,0 +1,11 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface CacheUserProviderFactory extends ProviderFactory<CacheUserProvider> {
+
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
new file mode 100755
index 0000000..6c0fae5
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
@@ -0,0 +1,27 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class CacheUserProviderSpi implements Spi {
+
+    @Override
+    public String getName() {
+        return "userCache";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return CacheUserProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return CacheUserProviderFactory.class;
+    }
+}
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 34a785c..ae913a1 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
@@ -4,7 +4,6 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.cache.entities.CachedClient;
 
 import java.util.HashSet;
@@ -16,12 +15,12 @@ import java.util.Set;
  */
 public abstract class ClientAdapter implements ClientModel {
     protected CachedClient cachedClient;
-    protected CacheModelProvider cacheSession;
+    protected CacheRealmProvider cacheSession;
     protected ClientModel updatedClient;
     protected RealmModel cachedRealm;
-    protected KeycloakCache cache;
+    protected RealmCache cache;
 
-    public ClientAdapter(RealmModel cachedRealm, CachedClient cached, KeycloakCache cache, CacheModelProvider cacheSession) {
+    public ClientAdapter(RealmModel cachedRealm, CachedClient cached, RealmCache cache, CacheRealmProvider cacheSession) {
         this.cachedRealm = cachedRealm;
         this.cache = cache;
         this.cacheSession = cacheSession;
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
new file mode 100755
index 0000000..f44bbd5
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
@@ -0,0 +1,244 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
+import org.keycloak.models.cache.entities.CachedUser;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class DefaultCacheUserProvider implements CacheUserProvider {
+    protected UserCache cache;
+    protected KeycloakSession session;
+    protected UserProvider delegate;
+    protected boolean transactionActive;
+    protected boolean setRollbackOnly;
+
+    protected Map<String, String> userInvalidations = new HashMap<String, String>();
+    protected Set<String> realmInvalidations = new HashSet<String>();
+    protected Map<String, UserModel> managedUsers = new HashMap<String, UserModel>();
+
+    protected boolean clearAll;
+
+    public DefaultCacheUserProvider(UserCache cache, KeycloakSession session) {
+        this.cache = cache;
+        this.session = session;
+
+        session.getTransaction().enlistAfterCompletion(getTransaction());
+    }
+
+    @Override
+    public UserProvider getDelegate() {
+        if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
+        if (delegate != null) return delegate;
+        delegate = session.getProvider(UserProvider.class);
+        return delegate;
+    }
+
+    @Override
+    public void registerUserInvalidation(RealmModel realm, String id) {
+        userInvalidations.put(id, realm.getId());
+    }
+
+    protected void runInvalidations() {
+        for (Map.Entry<String, String> invalidation : userInvalidations.entrySet()) {
+            cache.invalidateCachedUserById(invalidation.getValue(), invalidation.getKey());
+        }
+        for (String realmId : realmInvalidations) {
+            cache.invalidateRealmUsers(realmId);
+        }
+    }
+
+    private KeycloakTransaction getTransaction() {
+        return new KeycloakTransaction() {
+            @Override
+            public void begin() {
+                transactionActive = true;
+            }
+
+            @Override
+            public void commit() {
+                if (delegate == null) return;
+                if (clearAll) {
+                    cache.clear();
+                }
+                runInvalidations();
+            }
+
+            @Override
+            public void rollback() {
+                setRollbackOnly = true;
+                runInvalidations();
+            }
+
+            @Override
+            public void setRollbackOnly() {
+                setRollbackOnly = true;
+            }
+
+            @Override
+            public boolean getRollbackOnly() {
+                return setRollbackOnly;
+            }
+
+            @Override
+            public boolean isActive() {
+                return transactionActive;
+            }
+        };
+    }
+
+    @Override
+    public UserModel getUserById(String id, RealmModel realm) {
+        if (realmInvalidations.contains(realm.getId())) {
+            return getDelegate().getUserById(id, realm);
+        }
+        if (userInvalidations.containsKey(id)) {
+            return getDelegate().getUserById(id, realm);
+        }
+
+        CachedUser cached = cache.getCachedUser(realm.getId(), id);
+        if (cached == null) {
+            UserModel model = getDelegate().getUserById(id, realm);
+            if (model == null) return null;
+            if (userInvalidations.containsKey(id)) return model;
+            cached = new CachedUser(realm, model);
+            cache.addCachedUser(realm.getId(), cached);
+        } else if (managedUsers.containsKey(id)) {
+            return managedUsers.get(id);
+        }
+        UserAdapter adapter = new UserAdapter(cached, this, session, realm);
+        managedUsers.put(id, adapter);
+        return adapter;
+    }
+
+    @Override
+    public UserModel getUserByUsername(String username, RealmModel realm) {
+        if (realmInvalidations.contains(realm.getId())) {
+            return getDelegate().getUserByUsername(username, realm);
+        }
+        CachedUser cached = cache.getCachedUserByUsername(realm.getId(), username);
+        if (cached == null) {
+            UserModel model = getDelegate().getUserByUsername(username, realm);
+            if (model == null) return null;
+            if (userInvalidations.containsKey(model.getId())) return model;
+            cached = new CachedUser(realm, model);
+            cache.addCachedUser(realm.getId(), cached);
+        } else if (userInvalidations.containsKey(cached.getId())) {
+            return getDelegate().getUserById(cached.getId(), realm);
+        } else if (managedUsers.containsKey(cached.getId())) {
+            return managedUsers.get(cached.getId());
+        }
+        UserAdapter adapter = new UserAdapter(cached, this, session, realm);
+        managedUsers.put(cached.getId(), adapter);
+        return adapter;
+    }
+
+    @Override
+    public UserModel getUserByEmail(String email, RealmModel realm) {
+        if (realmInvalidations.contains(realm.getId())) {
+            return getDelegate().getUserByEmail(email, realm);
+        }
+        CachedUser cached = cache.getCachedUserByEmail(realm.getId(), email);
+        if (cached == null) {
+            UserModel model = getDelegate().getUserByEmail(email, realm);
+            if (model == null) return null;
+            if (userInvalidations.containsKey(model.getId())) return model;
+            cached = new CachedUser(realm, model);
+            cache.addCachedUser(realm.getId(), cached);
+        } else if (userInvalidations.containsKey(cached.getId())) {
+            return getDelegate().getUserByEmail(email, realm);
+        } else if (managedUsers.containsKey(cached.getId())) {
+            return managedUsers.get(cached.getId());
+        }
+        UserAdapter adapter = new UserAdapter(cached, this, session, realm);
+        managedUsers.put(cached.getId(), adapter);
+        return adapter;
+    }
+
+    @Override
+    public void close() {
+        if (delegate != null) delegate.close();
+    }
+
+    @Override
+    public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
+        return getDelegate().getUserBySocialLink(socialLink, realm);
+    }
+
+    @Override
+    public List<UserModel> getUsers(RealmModel realm) {
+        return getDelegate().getUsers(realm);
+    }
+
+    @Override
+    public List<UserModel> searchForUser(String search, RealmModel realm) {
+        return getDelegate().searchForUser(search, realm);
+    }
+
+    @Override
+    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
+        return getDelegate().searchForUserByAttributes(attributes, realm);
+    }
+
+    @Override
+    public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
+        return getDelegate().getSocialLinks(user, realm);
+    }
+
+    @Override
+    public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
+        return getDelegate().getSocialLink(user, socialProvider, realm);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) {
+        return getDelegate().addUser(realm, id, username, addDefaultRoles);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String username) {
+        return getDelegate().addUser(realm, username);
+    }
+
+    @Override
+    public boolean removeUser(RealmModel realm, String name) {
+        UserModel user = getUserByUsername(name, realm);
+        if (user == null) return false;
+        registerUserInvalidation(realm, user.getId());
+        return getDelegate().removeUser(realm, name);
+    }
+
+    @Override
+    public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
+        getDelegate().addSocialLink(realm, user, socialLink);
+    }
+
+    @Override
+    public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
+        return getDelegate().removeSocialLink(realm, user, socialProvider);
+    }
+
+    @Override
+    public void preRemove(RealmModel realm) {
+        realmInvalidations.add(realm.getId());
+        getDelegate().preRemove(realm);
+    }
+
+    @Override
+    public void preRemove(RoleModel role) {
+        getDelegate().preRemove(role);
+    }
+}
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 06cc7fe..3ccacbf 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,21 +1,15 @@
 package org.keycloak.models.cache.entities;
 
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.cache.KeycloakCache;
+import org.keycloak.models.cache.RealmCache;
 
 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>
@@ -29,7 +23,7 @@ public class CachedApplication extends CachedClient {
     private boolean bearerOnly;
     private Map<String, String> roles = new HashMap<String, String>();
 
-    public CachedApplication(KeycloakCache cache, ModelProvider delegate, RealmModel realm, ApplicationModel model) {
+    public CachedApplication(RealmCache cache, RealmProvider delegate, RealmModel realm, ApplicationModel model) {
         super(cache, delegate, realm, model);
         surrogateAuthRequired = model.isSurrogateAuthRequired();
         managementUrl = model.getManagementUrl();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index 7e62422..feabb45 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -1,12 +1,10 @@
 package org.keycloak.models.cache.entities;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.cache.KeycloakCache;
+import org.keycloak.models.cache.RealmCache;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -28,7 +26,7 @@ public class CachedClient {
     protected Set<String> scope = new HashSet<String>();
     protected Set<String> webOrigins = new HashSet<String>();
 
-    public CachedClient(KeycloakCache cache, ModelProvider delegate, RealmModel realm, ClientModel model) {
+    public CachedClient(RealmCache cache, RealmProvider delegate, RealmModel realm, ClientModel model) {
         id = model.getId();
         secret = model.getSecret();
         name = model.getClientId();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedOAuthClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedOAuthClient.java
index 397010f..0ab872a 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedOAuthClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedOAuthClient.java
@@ -1,17 +1,16 @@
 package org.keycloak.models.cache.entities;
 
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.cache.KeycloakCache;
+import org.keycloak.models.cache.RealmCache;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
 public class CachedOAuthClient extends CachedClient {
-    public CachedOAuthClient(KeycloakCache cache, ModelProvider delegate, RealmModel realm, OAuthClientModel model) {
+    public CachedOAuthClient(RealmCache cache, RealmProvider delegate, RealmModel realm, OAuthClientModel model) {
         super(cache, delegate, realm, model);
 
     }
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 ffaa6c5..9bb18ae 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
@@ -2,14 +2,13 @@ package org.keycloak.models.cache.entities;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 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.cache.KeycloakCache;
+import org.keycloak.models.cache.RealmCache;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -81,7 +80,7 @@ public class CachedRealm {
     public CachedRealm() {
     }
 
-    public CachedRealm(KeycloakCache cache, ModelProvider delegate, RealmModel model) {
+    public CachedRealm(RealmCache cache, RealmProvider delegate, RealmModel model) {
         id = model.getId();
         name = model.getName();
         enabled = model.isEnabled();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java
index b6f6668..f1f34dc 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java
@@ -2,9 +2,6 @@ package org.keycloak.models.cache.entities;
 
 import org.keycloak.models.RoleModel;
 
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedUser.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedUser.java
index ee0318f..587bf32 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedUser.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedUser.java
@@ -20,11 +20,9 @@ import java.util.Set;
 public class CachedUser {
     private String id;
     private String username;
-    private String usernameKey;
     private String firstName;
     private String lastName;
     private String email;
-    private String emailKey;
     private boolean emailVerified;
     private List<UserCredentialValueModel> credentials = new LinkedList<UserCredentialValueModel>();
     private boolean enabled;
@@ -38,14 +36,10 @@ public class CachedUser {
     public CachedUser(RealmModel realm, UserModel user) {
         this.id = user.getId();
         this.username = user.getUsername();
-        this.usernameKey = realm.getId() + "." + this.username;
         this.firstName = user.getFirstName();
         this.lastName = user.getLastName();
         this.attributes.putAll(user.getAttributes());
         this.email = user.getEmail();
-        if (this.email != null) {
-            this.emailKey = realm.getId() + "." + this.email;
-        }
         this.emailVerified = user.isEmailVerified();
         this.credentials.addAll(user.getCredentialsDirectly());
         this.enabled = user.isEnabled();
@@ -65,14 +59,6 @@ public class CachedUser {
         return username;
     }
 
-    public String getUsernameKey() {
-        return usernameKey;
-    }
-
-    public String getEmailKey() {
-        return emailKey;
-    }
-
     public String getFirstName() {
         return firstName;
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryCacheUserProviderFactory.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryCacheUserProviderFactory.java
new file mode 100755
index 0000000..340b694
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryCacheUserProviderFactory.java
@@ -0,0 +1,33 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class MemoryCacheUserProviderFactory implements CacheUserProviderFactory {
+    protected UserCache cache = new MemoryUserCache();
+
+    @Override
+    public CacheUserProvider create(KeycloakSession session) {
+        return new DefaultCacheUserProvider(cache, session);
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+        config.get("");
+
+    }
+
+    @Override
+    public void close() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public String getId() {
+        return "mem";
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
new file mode 100755
index 0000000..adefff4
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
@@ -0,0 +1,143 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.cache.entities.CachedUser;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class MemoryUserCache implements UserCache {
+
+    protected int maxUserCacheSize = 10000;
+
+
+    protected class RealmUsers {
+        protected class LRUCache extends LinkedHashMap<String, CachedUser> {
+            public LRUCache() {
+                super(1000, 1.1F, true);
+            }
+
+            @Override
+            public CachedUser put(String key, CachedUser value) {
+                usersByUsername.put(value.getUsername(), value);
+                if (value.getEmail() != null) {
+                    usersByEmail.put(value.getEmail(), value);
+                }
+                return super.put(key, value);
+            }
+
+            @Override
+            public CachedUser remove(Object key) {
+                CachedUser user = super.remove(key);
+                if (user == null) return null;
+                removeUser(user);
+                return user;
+            }
+
+            @Override
+            public void clear() {
+                super.clear();
+                usersByUsername.clear();
+                usersByEmail.clear();
+            }
+
+            @Override
+            protected boolean removeEldestEntry(Map.Entry<String, CachedUser> eldest) {
+                boolean evict = size() > maxUserCacheSize;
+                if (evict) {
+                    removeUser(eldest.getValue());
+                }
+                return evict;
+            }
+
+            private void removeUser(CachedUser value) {
+                usersByUsername.remove(value.getUsername());
+                if (value.getEmail() != null) usersByEmail.remove(value.getEmail());
+            }
+        }
+
+        protected Map<String, CachedUser> usersById = Collections.synchronizedMap(new LRUCache());
+        protected Map<String, CachedUser> usersByUsername = new ConcurrentHashMap<String, CachedUser>();
+        protected Map<String, CachedUser> usersByEmail = new ConcurrentHashMap<String, CachedUser>();
+
+    }
+
+    protected ConcurrentHashMap<String, RealmUsers> realmUsers = new ConcurrentHashMap<String, RealmUsers>();
+
+    public int getMaxUserCacheSize() {
+        return maxUserCacheSize;
+    }
+
+    public void setMaxUserCacheSize(int maxUserCacheSize) {
+        this.maxUserCacheSize = maxUserCacheSize;
+    }
+
+    @Override
+    public CachedUser getCachedUser(String realmId, String id) {
+        if (realmId == null || id == null) return null;
+        RealmUsers users = realmUsers.get(realmId);
+        if (users == null) return null;
+        return users.usersById.get(id);
+    }
+
+    @Override
+    public void invalidateCachedUser(String realmId, CachedUser user) {
+        RealmUsers users = realmUsers.get(realmId);
+        if (users == null) return;
+        users.usersById.remove(user.getId());
+    }
+
+    @Override
+    public void invalidateCachedUserById(String realmId, String id) {
+        RealmUsers users = realmUsers.get(realmId);
+        if (users == null) return;
+        users.usersById.remove(id);
+    }
+
+    @Override
+    public void addCachedUser(String realmId, CachedUser user) {
+        RealmUsers users = realmUsers.get(realmId);
+        if (users == null) {
+            users = new RealmUsers();
+            realmUsers.put(realmId, users);
+        }
+        users.usersById.put(user.getId(), user);
+    }
+
+    @Override
+    public CachedUser getCachedUserByUsername(String realmId, String name) {
+        if (realmId == null || name == null) return null;
+        RealmUsers users = realmUsers.get(realmId);
+        if (users == null) return null;
+        CachedUser user = users.usersByUsername.get(name);
+        if (user == null) return null;
+        users.usersById.get(user.getId()); // refresh cache entry age
+        return user;
+    }
+
+    @Override
+    public CachedUser getCachedUserByEmail(String realmId, String email) {
+        if (realmId == null || email == null) return null;
+        RealmUsers users = realmUsers.get(realmId);
+        if (users == null) return null;
+        CachedUser user = users.usersByEmail.get(email);
+        if (user == null) return null;
+        users.usersById.get(user.getId()); // refresh cache entry age
+        return user;
+    }
+
+    @Override
+    public void invalidateRealmUsers(String realmId) {
+        realmUsers.remove(realmId);
+    }
+
+    @Override
+    public void clear() {
+        realmUsers.clear();
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
new file mode 100755
index 0000000..36f5669
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
@@ -0,0 +1,126 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
+import org.keycloak.models.cache.entities.CachedUser;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class NoCacheUserProvider implements CacheUserProvider {
+    protected KeycloakSession session;
+    protected UserProvider delegate;
+
+    public NoCacheUserProvider(KeycloakSession session) {
+        this.session = session;
+    }
+
+    @Override
+    public UserProvider getDelegate() {
+        if (delegate != null) return delegate;
+        delegate = session.getProvider(UserProvider.class);
+        return delegate;
+    }
+
+    @Override
+    public void registerUserInvalidation(RealmModel realm, String id) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public UserModel getUserById(String id, RealmModel realm) {
+        return getDelegate().getUserById(id, realm);
+    }
+
+    @Override
+    public UserModel getUserByUsername(String username, RealmModel realm) {
+        return getDelegate().getUserByUsername(username, realm);
+    }
+
+    @Override
+    public UserModel getUserByEmail(String email, RealmModel realm) {
+        return getDelegate().getUserByEmail(email, realm);
+    }
+
+    @Override
+    public void close() {
+        if (delegate != null) delegate.close();
+    }
+
+    @Override
+    public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
+        return getDelegate().getUserBySocialLink(socialLink, realm);
+    }
+
+    @Override
+    public List<UserModel> getUsers(RealmModel realm) {
+        return getDelegate().getUsers(realm);
+    }
+
+    @Override
+    public List<UserModel> searchForUser(String search, RealmModel realm) {
+        return getDelegate().searchForUser(search, realm);
+    }
+
+    @Override
+    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
+        return getDelegate().searchForUserByAttributes(attributes, realm);
+    }
+
+    @Override
+    public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
+        return getDelegate().getSocialLinks(user, realm);
+    }
+
+    @Override
+    public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
+        return getDelegate().getSocialLink(user, socialProvider, realm);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) {
+        return getDelegate().addUser(realm, id, username, addDefaultRoles);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String username) {
+        return getDelegate().addUser(realm, username);
+    }
+
+    @Override
+    public boolean removeUser(RealmModel realm, String name) {
+        return getDelegate().removeUser(realm, name);
+    }
+
+    @Override
+    public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
+        getDelegate().addSocialLink(realm, user, socialLink);
+    }
+
+    @Override
+    public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
+        return getDelegate().removeSocialLink(realm, user, socialProvider);
+    }
+
+    @Override
+    public void preRemove(RealmModel realm) {
+        getDelegate().preRemove(realm);
+    }
+
+    @Override
+    public void preRemove(RoleModel role) {
+        getDelegate().preRemove(role);
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java
new file mode 100755
index 0000000..1008a00
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java
@@ -0,0 +1,30 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class NoCacheUserProviderFactory implements CacheUserProviderFactory {
+    @Override
+    public CacheUserProvider create(KeycloakSession session) {
+        return new NoCacheUserProvider(session);
+    }
+
+    @Override
+    public void close() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public String getId() {
+        return "none";
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/OAuthClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/OAuthClientAdapter.java
index 2831ea0..50708b9 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/OAuthClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/OAuthClientAdapter.java
@@ -12,7 +12,7 @@ public class OAuthClientAdapter extends ClientAdapter implements OAuthClientMode
     protected OAuthClientModel updated;
     protected CachedOAuthClient cached;
 
-    public OAuthClientAdapter(RealmModel cachedRealm, CachedOAuthClient cached, CacheModelProvider cacheSession, KeycloakCache cache) {
+    public OAuthClientAdapter(RealmModel cachedRealm, CachedOAuthClient cached, CacheRealmProvider cacheSession, RealmCache cache) {
         super(cachedRealm, cached, cache, cacheSession);
         this.cached = cached;
     }
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 922065d..94121a0 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
@@ -9,15 +9,11 @@ import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
 import org.keycloak.models.utils.TimeBasedOTP;
 
 import java.security.PrivateKey;
@@ -35,13 +31,13 @@ import java.util.Set;
  */
 public class RealmAdapter implements RealmModel {
     protected CachedRealm cached;
-    protected CacheModelProvider cacheSession;
+    protected CacheRealmProvider cacheSession;
     protected RealmModel updated;
-    protected KeycloakCache cache;
+    protected RealmCache cache;
     protected volatile transient PublicKey publicKey;
     protected volatile transient PrivateKey privateKey;
 
-    public RealmAdapter(CachedRealm cached, CacheModelProvider cacheSession) {
+    public RealmAdapter(CachedRealm cached, CacheRealmProvider cacheSession) {
         this.cached = cached;
         this.cacheSession = cacheSession;
     }
@@ -396,39 +392,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public UserModel getUser(String name) {
-        return cacheSession.getUserByUsername(name, this);
-    }
-
-    @Override
-    public UserModel getUserByEmail(String email) {
-        return cacheSession.getUserByEmail(email, this);
-    }
-
-    @Override
-    public UserModel getUserById(String id) {
-        return cacheSession.getUserById(id, this);
-    }
-
-    @Override
-    public UserModel addUser(String id, String username, boolean addDefaultRoles) {
-        getDelegateForUpdate();
-        return updated.addUser(id, username, addDefaultRoles);
-    }
-
-    @Override
-    public UserModel addUser(String username) {
-        getDelegateForUpdate();
-        return updated.addUser(username);
-    }
-
-    @Override
-    public boolean removeUser(String name) {
-        getDelegateForUpdate();
-        return updated.removeUser(name);
-    }
-
-    @Override
     public RoleModel getRoleById(String id) {
         if (updated != null) return updated.getRoleById(id);
         return cacheSession.getRoleById(id, this);
@@ -539,36 +502,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
-        if (updated != null) return updated.getUserBySocialLink(socialLink);
-        return cacheSession.getUserBySocialLink(socialLink, this);
-    }
-
-    @Override
-    public Set<SocialLinkModel> getSocialLinks(UserModel user) {
-        if (updated != null) return updated.getSocialLinks(user);
-        return cacheSession.getSocialLinks(user, this);
-    }
-
-    @Override
-    public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
-        if (updated != null) return updated.getSocialLink(user, socialProvider);
-        return cacheSession.getSocialLink(user, socialProvider, this);
-    }
-
-    @Override
-    public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
-        getDelegateForUpdate();
-        updated.addSocialLink(user, socialLink);
-    }
-
-    @Override
-    public boolean removeSocialLink(UserModel user, String socialProvider) {
-        getDelegateForUpdate();
-        return updated.removeSocialLink(user, socialProvider);
-    }
-
-    @Override
     public boolean isSocial() {
         if (updated != null) return updated.isSocial();
         return cached.isSocial();
@@ -593,24 +526,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public List<UserModel> getUsers() {
-        if (updated != null) return updated.getUsers();
-        return cacheSession.getUsers(this);
-    }
-
-    @Override
-    public List<UserModel> searchForUser(String search) {
-        if (updated != null) return updated.searchForUser(search);
-        return cacheSession.searchForUser(search, this);
-    }
-
-    @Override
-    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
-        if (updated != null) return updated.searchForUserByAttributes(attributes);
-        return cacheSession.searchForUserByAttributes(attributes, this);
-    }
-
-    @Override
     public OAuthClientModel addOAuthClient(String name) {
         getDelegateForUpdate();
         OAuthClientModel client = updated.addOAuthClient(name);
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 bbf2766..18f6422 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
@@ -19,11 +19,11 @@ public class RoleAdapter implements RoleModel {
 
     protected RoleModel updated;
     protected CachedRole cached;
-    protected KeycloakCache cache;
-    protected CacheModelProvider cacheSession;
+    protected RealmCache cache;
+    protected CacheRealmProvider cacheSession;
     protected RealmModel realm;
 
-    public RoleAdapter(CachedRole cached, KeycloakCache cache, CacheModelProvider session, RealmModel realm) {
+    public RoleAdapter(CachedRole cached, RealmCache cache, CacheRealmProvider session, RealmModel realm) {
         this.cached = cached;
         this.cache = cache;
         this.cacheSession = session;
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 b48e1c5..a094b64 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
@@ -2,6 +2,7 @@ package org.keycloak.models.cache;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
@@ -22,21 +23,21 @@ import java.util.Set;
 public class UserAdapter implements UserModel {
     protected UserModel updated;
     protected CachedUser cached;
-    protected KeycloakCache cache;
-    protected CacheModelProvider cacheSession;
+    protected CacheUserProvider userProviderCache;
+    protected KeycloakSession keycloakSession;
     protected RealmModel realm;
 
-    public UserAdapter(CachedUser cached, KeycloakCache cache, CacheModelProvider session, RealmModel realm) {
+    public UserAdapter(CachedUser cached, CacheUserProvider userProvider, KeycloakSession keycloakSession, RealmModel realm) {
         this.cached = cached;
-        this.cache = cache;
-        this.cacheSession = session;
+        this.userProviderCache = userProvider;
+        this.keycloakSession = keycloakSession;
         this.realm = realm;
     }
 
     protected void getDelegateForUpdate() {
         if (updated == null) {
-            cacheSession.registerUserInvalidation(getId());
-            updated = cacheSession.getDelegate().getUserById(getId(), realm);
+            userProviderCache.registerUserInvalidation(realm, getId());
+            updated = userProviderCache.getDelegate().getUserById(getId(), realm);
             if (updated == null) throw new IllegalStateException("Not found in database");
         }
     }
@@ -257,7 +258,13 @@ public class UserAdapter implements UserModel {
         if (updated != null) return updated.getRoleMappings();
         Set<RoleModel> roles = new HashSet<RoleModel>();
         for (String id : cached.getRoleMappings()) {
-            roles.add(cacheSession.getRoleById(id, realm));
+            RoleModel roleById = keycloakSession.realms().getRoleById(id, realm);
+            if (roleById == null) {
+                // chance that role was removed, so just delete to persistence and get user invalidated
+                getDelegateForUpdate();
+                return updated.getRoleMappings();
+            }
+            roles.add(roleById);
 
         }
         return roles;
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
new file mode 100755
index 0000000..09c7b35
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
@@ -0,0 +1,25 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.cache.entities.CachedUser;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface UserCache {
+    void clear();
+
+    CachedUser getCachedUser(String realmId, String id);
+
+    void invalidateCachedUser(String realmId, CachedUser user);
+
+    void addCachedUser(String realmId, CachedUser user);
+
+    CachedUser getCachedUserByUsername(String realmId, String name);
+
+    CachedUser getCachedUserByEmail(String realmId, String name);
+
+    void invalidateCachedUserById(String realmId, String id);
+
+    void invalidateRealmUsers(String realmId);
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheRealmProviderFactory b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheRealmProviderFactory
new file mode 100755
index 0000000..82ddea9
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheRealmProviderFactory
@@ -0,0 +1,2 @@
+org.keycloak.models.cache.MemoryCacheRealmProviderFactory
+org.keycloak.models.cache.NoCacheRealmProviderFactory
\ No newline at end of file
diff --git a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory
new file mode 100755
index 0000000..438f9e1
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory
@@ -0,0 +1,2 @@
+org.keycloak.models.cache.MemoryCacheUserProviderFactory
+org.keycloak.models.cache.NoCacheUserProviderFactory
diff --git a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index eb9e116..d793d8a 100755
--- a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1 +1,2 @@
-org.keycloak.models.cache.CacheModelProviderSpi
\ No newline at end of file
+org.keycloak.models.cache.CacheRealmProviderSpi
+org.keycloak.models.cache.CacheUserProviderSpi
\ No newline at end of file
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
index 0ebe017..caf8f4e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
@@ -2,12 +2,13 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.jpa.entities.*;
+import org.keycloak.models.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.RoleEntity;
+import org.keycloak.models.jpa.entities.ScopeMappingEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
@@ -25,10 +26,12 @@ import java.util.Set;
 public class ApplicationAdapter extends ClientAdapter implements ApplicationModel {
 
     protected EntityManager em;
+    protected KeycloakSession session;
     protected ApplicationEntity applicationEntity;
 
-    public ApplicationAdapter(RealmModel realm, EntityManager em, ApplicationEntity applicationEntity) {
+    public ApplicationAdapter(RealmModel realm, EntityManager em, KeycloakSession session, ApplicationEntity applicationEntity) {
         super(realm, applicationEntity, em);
+        this.session = session;
         this.realm = realm;
         this.em = em;
         this.applicationEntity = applicationEntity;
@@ -135,6 +138,7 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
         }
         if (!roleModel.getContainer().equals(this)) return false;
 
+        session.users().preRemove(roleModel);
         RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em);
         if (!role.isApplicationRole()) return false;
 
@@ -143,7 +147,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
         applicationEntity.getDefaultRoles().remove(role);
         em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", role).executeUpdate();
         em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
-        em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
         role.setApplication(null);
         em.flush();
         em.remove(role);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
index 8327bd0..b379f18 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
@@ -1,25 +1,12 @@
 package org.keycloak.models.jpa.entities;
 
 import javax.persistence.CascadeType;
-import javax.persistence.CollectionTable;
-import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
-import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.hibernate.annotations.GenericGenerator;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
old mode 100644
new mode 100755
index e6ae8d4..16942d9
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
@@ -1,14 +1,10 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToOne;
-
-import org.hibernate.annotations.GenericGenerator;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
old mode 100644
new mode 100755
index 2ce4c12..06094a2
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
@@ -1,6 +1,6 @@
 package org.keycloak.models.jpa.entities;
 
-import java.util.Map;
+import org.hibernate.annotations.GenericGenerator;
 
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
@@ -11,8 +11,7 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.MapKeyColumn;
 import javax.persistence.Table;
-
-import org.hibernate.annotations.GenericGenerator;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
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 9367d25..46b8197 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
@@ -1,20 +1,15 @@
 package org.keycloak.models.jpa.entities;
 
-import org.hibernate.annotations.GenericGenerator;
-
-import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import java.util.HashSet;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
index 6d792f8..2a03cdf 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
@@ -1,5 +1,7 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -8,8 +10,6 @@ import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -33,6 +33,9 @@ public class CredentialEntity {
     @ManyToOne(fetch = FetchType.LAZY)
     protected UserEntity user;
 
+    @ManyToOne(fetch = FetchType.LAZY)
+    protected RealmEntity realm;
+
     public String getValue() {
         return value;
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
index 9487022..bc07b01 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
@@ -1,11 +1,11 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
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 d3fc6df..2c62502 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
@@ -3,10 +3,7 @@ package org.keycloak.models.jpa.entities;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
@@ -18,8 +15,6 @@ import javax.persistence.UniqueConstraint;
 import java.util.ArrayList;
 import java.util.Collection;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
index a1de3af..5e63b51 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
@@ -1,5 +1,7 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -8,8 +10,6 @@ import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
index 75389c9..53561f9 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
@@ -1,6 +1,5 @@
 package org.keycloak.models.jpa.entities;
 
-import org.hibernate.annotations.GenericGenerator;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
@@ -10,7 +9,6 @@ import javax.persistence.Column;
 import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
@@ -21,7 +19,6 @@ import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
index 647acea..27b8f49 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
@@ -1,6 +1,13 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 
@@ -14,6 +21,40 @@ import javax.persistence.NamedQuery;
         @NamedQuery(name="userRoleMappingIds", query="select m.role.id from UserRoleMappingEntity m where m.user = :user")
 })
 @Entity
-public class UserRoleMappingEntity extends AbstractRoleMappingEntity {
+public class UserRoleMappingEntity  {
+    @Id
+    @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator")
+    @GeneratedValue(generator = "keycloak_generator")
+    protected String id;
+    @ManyToOne(fetch= FetchType.LAZY)
+    protected UserEntity user;
+
+    @ManyToOne(fetch= FetchType.LAZY)
+    @JoinColumn(name="roleId")
+    protected RoleEntity role;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public UserEntity getUser() {
+        return user;
+    }
+
+    public void setUser(UserEntity user) {
+        this.user = user;
+    }
+
+    public RoleEntity getRole() {
+        return role;
+    }
+
+    public void setRole(RoleEntity role) {
+        this.role = role;
+    }
 
 }
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 48b4730..01e32ec 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
@@ -2,16 +2,11 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
-import org.keycloak.models.ModelProvider;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
-import org.keycloak.models.jpa.entities.ApplicationEntity;
-import org.keycloak.models.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
 import org.keycloak.models.jpa.entities.RoleEntity;
 import org.keycloak.models.jpa.entities.SocialLinkEntity;
@@ -23,7 +18,6 @@ import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,7 +33,6 @@ public class JpaUserProvider implements UserProvider {
     public JpaUserProvider(KeycloakSession session, EntityManager em) {
         this.session = session;
         this.em = em;
-        this.em = PersistenceExceptionConverter.create(em);
     }
 
     @Override
@@ -99,12 +92,38 @@ public class JpaUserProvider implements UserProvider {
     }
 
     @Override
+    public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
+        SocialLinkEntity entity = new SocialLinkEntity();
+        RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
+        entity.setRealm(realmEntity);
+        entity.setSocialProvider(socialLink.getSocialProvider());
+        entity.setSocialUserId(socialLink.getSocialUserId());
+        entity.setSocialUsername(socialLink.getSocialUsername());
+        UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
+        entity.setUser(userEntity);
+        em.persist(entity);
+        em.flush();
+    }
+
+    @Override
+    public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
+        SocialLinkEntity entity = findSocialLink(user, socialProvider);
+        if (entity != null) {
+            em.remove(entity);
+            em.flush();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+
+    @Override
     public void preRemove(RealmModel realm) {
-        TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm", UserEntity.class);
         RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
-        query.setParameter("realm", realmEntity);
-        for (UserEntity u : query.getResultList()) {
-            em.remove(u);
+        for (UserEntity u : em.createQuery("from UserEntity u where u.realm = :realm", UserEntity.class).setParameter("realm", realmEntity).getResultList()) {
+            removeUser(realm, u.getUsername());
         }
     }
 
@@ -114,12 +133,6 @@ public class JpaUserProvider implements UserProvider {
         em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
     }
 
-
-    @Override
-    public KeycloakTransaction getTransaction() {
-        return new JpaKeycloakTransaction(em);
-    }
-
     @Override
     public UserModel getUserById(String id, RealmModel realmModel) {
         TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserById", UserEntity.class);
@@ -154,8 +167,6 @@ public class JpaUserProvider implements UserProvider {
 
      @Override
     public void close() {
-        if (em.getTransaction().isActive()) em.getTransaction().rollback();
-        if (em.isOpen()) em.close();
     }
 
     @Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
new file mode 100755
index 0000000..3a52f12
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
@@ -0,0 +1,36 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.Config;
+import org.keycloak.connections.jpa.JpaConnectionProvider;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.UserProvider;
+import org.keycloak.models.UserProviderFactory;
+
+import javax.persistence.EntityManager;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JpaUserProviderFactory implements UserProviderFactory {
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public String getId() {
+        return "jpa";
+    }
+
+    @Override
+    public UserProvider create(KeycloakSession session) {
+        EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager();
+        return new JpaUserProvider(session, em);
+    }
+
+    @Override
+    public void close() {
+    }
+
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
index c890c9f..2279163 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
@@ -1,14 +1,10 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 
 import javax.persistence.EntityManager;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
old mode 100644
new mode 100755
index dfa5053..62a9426
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
@@ -1,12 +1,11 @@
 package org.keycloak.models.jpa;
 
 import org.hibernate.exception.ConstraintViolationException;
-import org.keycloak.models.ModelException;
 import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.ModelException;
 
 import javax.persistence.EntityExistsException;
 import javax.persistence.EntityManager;
-import javax.persistence.PersistenceException;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
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 dd32a84..6157ee9 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
@@ -10,11 +10,9 @@ import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.jpa.entities.ApplicationEntity;
 import org.keycloak.models.jpa.entities.AuthenticationProviderEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
@@ -22,9 +20,6 @@ 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.ScopeMappingEntity;
-import org.keycloak.models.jpa.entities.SocialLinkEntity;
-import org.keycloak.models.jpa.entities.UserEntity;
-import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.TimeBasedOTP;
 
@@ -412,75 +407,6 @@ public class RealmAdapter implements RealmModel {
 
 
     @Override
-    public UserModel getUser(String name) {
-        return session.model().getUserByUsername(name, this);
-    }
-
-    @Override
-    public UserModel getUserByEmail(String email) {
-        return session.model().getUserByEmail(email, this);
-    }
-
-    @Override
-    public UserModel getUserById(String id) {
-        return session.model().getUserById(id, this);
-    }
-
-    @Override
-    public UserModel addUser(String username) {
-        return this.addUser(KeycloakModelUtils.generateId(), username, true);
-    }
-
-    @Override
-    public UserModel addUser(String id, String username, boolean addDefaultRoles) {
-        if (id == null) {
-            id = KeycloakModelUtils.generateId();
-        }
-
-        UserEntity entity = new UserEntity();
-        entity.setId(id);
-        entity.setUsername(username);
-        entity.setRealm(realm);
-        em.persist(entity);
-        em.flush();
-        UserModel userModel = new UserAdapter(this, em, entity);
-
-        if (addDefaultRoles) {
-            for (String r : getDefaultRoles()) {
-                userModel.grantRole(getRole(r));
-            }
-
-            for (ApplicationModel application : getApplications()) {
-                for (String r : application.getDefaultRoles()) {
-                    userModel.grantRole(application.getRole(r));
-                }
-            }
-        }
-
-        return userModel;
-    }
-
-    @Override
-    public boolean removeUser(String name) {
-        TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class);
-        query.setParameter("username", name);
-        query.setParameter("realm", realm);
-        List<UserEntity> results = query.getResultList();
-        if (results.size() == 0) return false;
-        removeUser(results.get(0));
-        return true;
-    }
-
-    private void removeUser(UserEntity user) {
-        em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
-        em.createQuery("delete from " + SocialLinkEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
-        if (user.getAuthenticationLink() != null) {
-            em.remove(user.getAuthenticationLink());
-        }
-        em.remove(user);
-    }
-
-    @Override
     public List<String> getDefaultRoles() {
         Collection<RoleEntity> entities = realm.getDefaultRoles();
         List<String> roles = new ArrayList<String>();
@@ -567,7 +493,7 @@ public class RealmAdapter implements RealmModel {
         List<ApplicationModel> list = new ArrayList<ApplicationModel>();
         if (realm.getApplications() == null) return list;
         for (ApplicationEntity entity : realm.getApplications()) {
-            list.add(new ApplicationAdapter(this, em, entity));
+            list.add(new ApplicationAdapter(this, em, session, entity));
         }
         return list;
     }
@@ -587,7 +513,7 @@ public class RealmAdapter implements RealmModel {
         realm.getApplications().add(applicationData);
         em.persist(applicationData);
         em.flush();
-        ApplicationModel resource = new ApplicationAdapter(this, em, applicationData);
+        ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
         em.flush();
         return resource;
     }
@@ -628,7 +554,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public ApplicationModel getApplicationById(String id) {
-        return session.model().getApplicationById(id, this);
+        return session.realms().getApplicationById(id, this);
     }
 
     @Override
@@ -637,57 +563,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
-        return session.model().getUserBySocialLink(socialLink, this);
-    }
-
-    @Override
-    public Set<SocialLinkModel> getSocialLinks(UserModel user) {
-        return session.model().getSocialLinks(user, this);
-    }
-
-    @Override
-    public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
-        return session.model().getSocialLink(user, socialProvider, this);
-    }
-
-    @Override
-    public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
-        SocialLinkEntity entity = new SocialLinkEntity();
-        entity.setRealm(realm);
-        entity.setSocialProvider(socialLink.getSocialProvider());
-        entity.setSocialUserId(socialLink.getSocialUserId());
-        entity.setSocialUsername(socialLink.getSocialUsername());
-        UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
-        entity.setUser(userEntity);
-        em.persist(entity);
-        em.flush();
-    }
-
-    private SocialLinkEntity findSocialLink(UserModel user, String socialProvider) {
-        TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByUserAndProvider", SocialLinkEntity.class);
-        UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
-        query.setParameter("user", userEntity);
-        query.setParameter("socialProvider", socialProvider);
-        List<SocialLinkEntity> results = query.getResultList();
-        return results.size() > 0 ? results.get(0) : null;
-    }
-
-
-    @Override
-    public boolean removeSocialLink(UserModel user, String socialProvider) {
-        SocialLinkEntity entity = findSocialLink(user, socialProvider);
-        if (entity != null) {
-            em.remove(entity);
-            em.flush();
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-
-    @Override
     public boolean isSocial() {
         return realm.isSocial();
     }
@@ -710,21 +585,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public List<UserModel> getUsers() {
-        return session.model().getUsers(this);
-    }
-
-    @Override
-    public List<UserModel> searchForUser(String search) {
-        return session.model().searchForUser(search, this);
-    }
-
-    @Override
-    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
-        return session.model().searchForUserByAttributes(attributes, this);
-    }
-
-    @Override
     public OAuthClientModel addOAuthClient(String name) {
         return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
     }
@@ -764,7 +624,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public OAuthClientModel getOAuthClientById(String id) {
-        return session.model().getOAuthClientById(id, this);
+        return session.realms().getOAuthClientById(id, this);
     }
 
 
@@ -899,13 +759,12 @@ public class RealmAdapter implements RealmModel {
             return false;
         }
         if (!role.getContainer().equals(this)) return false;
-
+        session.users().preRemove(role);
         RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
         realm.getRoles().remove(role);
         realm.getDefaultRoles().remove(role);
 
         em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", roleEntity).executeUpdate();
-        em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
         em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
 
         em.remove(roleEntity);
@@ -926,7 +785,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public RoleModel getRoleById(String id) {
-        return session.model().getRoleById(id, this);
+        return session.realms().getRoleById(id, this);
     }
 
     @Override
@@ -1060,7 +919,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public ApplicationModel getMasterAdminApp() {
-        return new ApplicationAdapter(this, em, realm.getMasterAdminApp());
+        return new ApplicationAdapter(this, em, session, realm.getMasterAdminApp());
     }
 
     @Override
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 18219f6..fc2fcbc 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
@@ -2,7 +2,6 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
-import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java b/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
old mode 100644
new mode 100755
index 6fc10e8..b35ee13
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.jpa.utils;
 
-import java.io.Serializable;
-
 import org.hibernate.HibernateException;
 import org.hibernate.engine.spi.SessionImplementor;
 import org.hibernate.id.IdentifierGenerator;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
+import java.io.Serializable;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.RealmProviderFactory b/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.RealmProviderFactory
new file mode 100755
index 0000000..8c7cf39
--- /dev/null
+++ b/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.RealmProviderFactory
@@ -0,0 +1 @@
+org.keycloak.models.jpa.JpaRealmProviderFactory
\ No newline at end of file
diff --git a/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.UserProviderFactory b/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.UserProviderFactory
new file mode 100755
index 0000000..6c80343
--- /dev/null
+++ b/model/jpa/src/main/resources/META-INF/services/org.keycloak.models.UserProviderFactory
@@ -0,0 +1 @@
+org.keycloak.models.jpa.JpaUserProviderFactory
\ No newline at end of file
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
index 6cfc06a..606ebd3 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
@@ -2,12 +2,12 @@ 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.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.mongo.utils.MongoModelUtils;
@@ -141,6 +141,7 @@ public class ApplicationAdapter extends ClientAdapter<MongoApplicationEntity> im
 
     @Override
     public boolean removeRole(RoleModel role) {
+        session.users().preRemove(role);
         return getMongoStore().removeEntity(MongoRoleEntity.class, role.getId(), invocationContext);
     }
 
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 5077746..1e468bc 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,13 +1,13 @@
 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.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.entities.ClientEntity;
-import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.mongo.utils.MongoModelUtils;
 
@@ -24,14 +24,14 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
     protected final T clientEntity;
     private final RealmModel realm;
     protected  KeycloakSession session;
-    private final ModelProvider model;
+    private final RealmProvider model;
 
     public ClientAdapter(KeycloakSession session, RealmModel realm, T clientEntity, MongoStoreInvocationContext invContext) {
         super(invContext);
         this.clientEntity = clientEntity;
         this.realm = realm;
         this.session = session;
-        this.model = session.model();
+        this.model = session.realms();
     }
 
     @Override
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
new file mode 100755
index 0000000..a025e89
--- /dev/null
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
@@ -0,0 +1,131 @@
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import com.mongodb.BasicDBObject;
+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.KeycloakSession;
+import org.keycloak.models.RealmProvider;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoRealmProvider implements RealmProvider {
+
+    private final MongoStoreInvocationContext invocationContext;
+    private final KeycloakSession session;
+    private final MongoStore mongoStore;
+
+    public MongoRealmProvider(KeycloakSession session, MongoStore mongoStore, MongoStoreInvocationContext invocationContext) {
+        this.session = session;
+        this.mongoStore = mongoStore;
+        this.invocationContext = invocationContext;
+    }
+
+    @Override
+    public void close() {
+        // TODO
+    }
+
+    @Override
+    public RealmModel createRealm(String name) {
+        return createRealm(KeycloakModelUtils.generateId(), name);
+    }
+
+    @Override
+    public RealmModel createRealm(String id, String name) {
+        MongoRealmEntity newRealm = new MongoRealmEntity();
+        newRealm.setId(id);
+        newRealm.setName(name);
+
+        getMongoStore().insertEntity(newRealm, invocationContext);
+
+        return new RealmAdapter(session, newRealm, invocationContext);
+    }
+
+    @Override
+    public RealmModel getRealm(String id) {
+        MongoRealmEntity realmEntity = getMongoStore().loadEntity(MongoRealmEntity.class, id, invocationContext);
+        return realmEntity != null ? new RealmAdapter(session, realmEntity, invocationContext) : null;
+    }
+
+    @Override
+    public List<RealmModel> getRealms() {
+        DBObject query = new BasicDBObject();
+        List<MongoRealmEntity> realms = getMongoStore().loadEntities(MongoRealmEntity.class, query, invocationContext);
+
+        List<RealmModel> results = new ArrayList<RealmModel>();
+        for (MongoRealmEntity realmEntity : realms) {
+            results.add(new RealmAdapter(session, realmEntity, invocationContext));
+        }
+        return results;
+    }
+
+    @Override
+    public RealmModel getRealmByName(String name) {
+        DBObject query = new QueryBuilder()
+                .and("name").is(name)
+                .get();
+        MongoRealmEntity realm = getMongoStore().loadSingleEntity(MongoRealmEntity.class, query, invocationContext);
+
+        if (realm == null) return null;
+        return new RealmAdapter(session, realm, invocationContext);
+    }
+
+    @Override
+    public boolean removeRealm(String id) {
+        RealmModel realm = getRealm(id);
+        if (realm == null) return false;
+        session.users().preRemove(realm);
+        return getMongoStore().removeEntity(MongoRealmEntity.class, id, invocationContext);
+    }
+
+    protected MongoStore getMongoStore() {
+        return invocationContext.getMongoStore();
+    }
+
+    @Override
+    public RoleModel getRoleById(String id, RealmModel realm) {
+        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;
+        return new RoleAdapter(session, realm, role, null, invocationContext);
+    }
+
+    @Override
+    public ApplicationModel getApplicationById(String id, RealmModel realm) {
+        MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, id, invocationContext);
+
+        // Check if application belongs to this realm
+        if (appData == null || !realm.getId().equals(appData.getRealmId())) {
+            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);
+    }
+
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java
new file mode 100755
index 0000000..083d0c0
--- /dev/null
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java
@@ -0,0 +1,38 @@
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import org.jboss.logging.Logger;
+import org.keycloak.Config;
+import org.keycloak.connections.mongo.MongoConnectionProvider;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.UserProvider;
+import org.keycloak.models.UserProviderFactory;
+
+/**
+ * KeycloakSessionFactory implementation based on MongoDB
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoUserProviderFactory implements UserProviderFactory {
+    protected static final Logger logger = Logger.getLogger(MongoUserProviderFactory.class);
+
+    @Override
+    public String getId() {
+        return "mongo";
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public UserProvider create(KeycloakSession session) {
+        MongoConnectionProvider connection = session.getProvider(MongoConnectionProvider.class);
+        return new MongoUserProvider(session, connection.getMongoStore(), connection.getInvocationContext());
+    }
+
+    @Override
+    public void close() {
+    }
+
+}
+
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
index e124392..71b73ce 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
@@ -1,10 +1,9 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
 
 /**
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 2a56586..410bc9f 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
@@ -9,24 +9,21 @@ import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.CredentialValidation;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 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.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.entities.AuthenticationProviderEntity;
 import org.keycloak.models.entities.RequiredCredentialEntity;
-import org.keycloak.models.entities.SocialLinkEntity;
 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.mongo.keycloak.entities.MongoUserEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.TimeBasedOTP;
 
@@ -49,7 +46,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     private static final Logger logger = Logger.getLogger(RealmAdapter.class);
 
     private final MongoRealmEntity realm;
-    private final ModelProvider model;
+    private final RealmProvider model;
 
     protected volatile transient PublicKey publicKey;
     protected volatile transient PrivateKey privateKey;
@@ -61,7 +58,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         super(invocationContext);
         this.realm = realmEntity;
         this.session = session;
-        this.model = session.model();
+        this.model = session.realms();
     }
 
     @Override
@@ -439,66 +436,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public UserModel getUser(String name) {
-        return model.getUserByUsername(name, this);
-    }
-
-    @Override
-    public UserModel getUserByEmail(String email) {
-        return model.getUserByEmail(email, this);
-    }
-
-    @Override
-    public UserModel getUserById(String id) {
-        return model.getUserById(id, this);
-    }
-
-    @Override
-    public UserAdapter addUser(String username) {
-        return this.addUser(null, username, true);
-    }
-
-    @Override
-    public UserAdapter addUser(String id, String username, boolean addDefaultRoles) {
-        UserAdapter userModel = addUserEntity(id, username);
-
-        if (addDefaultRoles) {
-            for (String r : getDefaultRoles()) {
-                userModel.grantRole(getRole(r));
-            }
-
-            for (ApplicationModel application : getApplications()) {
-                for (String r : application.getDefaultRoles()) {
-                    userModel.grantRole(application.getRole(r));
-                }
-            }
-        }
-
-        return userModel;
-    }
-
-    protected UserAdapter addUserEntity(String id, String username) {
-        MongoUserEntity userEntity = new MongoUserEntity();
-        userEntity.setId(id);
-        userEntity.setUsername(username);
-        // Compatibility with JPA model, which has user disabled by default
-        // userEntity.setEnabled(true);
-        userEntity.setRealmId(getId());
-
-        getMongoStore().insertEntity(userEntity, invocationContext);
-        return new UserAdapter(session, this, userEntity, invocationContext);
-    }
-
-    @Override
-    public boolean removeUser(String name) {
-        DBObject query = new QueryBuilder()
-                .and("username").is(name)
-                .and("realmId").is(getId())
-                .get();
-        return getMongoStore().removeEntities(MongoUserEntity.class, query, invocationContext);
-    }
-
-    @Override
     public RoleAdapter getRole(String name) {
         DBObject query = new QueryBuilder()
                 .and("name").is(name)
@@ -536,6 +473,9 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
 
     @Override
     public boolean removeRoleById(String id) {
+        RoleModel role = getRoleById(id);
+        if (role == null) return false;
+        session.users().preRemove(role);
         return getMongoStore().removeEntity(MongoRoleEntity.class, id, invocationContext);
     }
 
@@ -799,60 +739,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         return false;
     }
 
-
-
-
-    @Override
-    public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
-        return model.getUserBySocialLink(socialLink, this);
-    }
-
-    @Override
-    public Set<SocialLinkModel> getSocialLinks(UserModel user) {
-        return model.getSocialLinks(user, this);
-    }
-
-    @Override
-    public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
-        return model.getSocialLink(user, socialProvider, this);
-    }
-
-    @Override
-    public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
-        MongoUserEntity userEntity = ((UserAdapter) user).getUser();
-        SocialLinkEntity socialLinkEntity = new SocialLinkEntity();
-        socialLinkEntity.setSocialProvider(socialLink.getSocialProvider());
-        socialLinkEntity.setSocialUserId(socialLink.getSocialUserId());
-        socialLinkEntity.setSocialUsername(socialLink.getSocialUsername());
-
-        getMongoStore().pushItemToList(userEntity, "socialLinks", socialLinkEntity, true, invocationContext);
-    }
-
-    @Override
-    public boolean removeSocialLink(UserModel userModel, String socialProvider) {
-        UserModel user = getUserById(userModel.getId());
-        MongoUserEntity userEntity = ((UserAdapter) user).getUser();
-        SocialLinkEntity socialLinkEntity = findSocialLink(userEntity, socialProvider);
-        if (socialLinkEntity == null) {
-            return false;
-        }
-        return getMongoStore().pullItemFromList(userEntity, "socialLinks", socialLinkEntity, invocationContext);
-    }
-
-    private SocialLinkEntity findSocialLink(MongoUserEntity userEntity, String socialProvider) {
-        List<SocialLinkEntity> linkEntities = userEntity.getSocialLinks();
-        if (linkEntities == null) {
-            return null;
-        }
-
-        for (SocialLinkEntity socialLinkEntity : linkEntities) {
-            if (socialLinkEntity.getSocialProvider().equals(socialProvider)) {
-                return socialLinkEntity;
-            }
-        }
-        return null;
-    }
-
     protected void updateRealm() {
         super.updateMongoEntity();
     }
@@ -866,23 +752,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public List<UserModel> getUsers() {
-        return model.getUsers(this);
-    }
-
-    @Override
-    public List<UserModel> searchForUser(String search) {
-        return model.searchForUser(search, this);
-
-    }
-
-    @Override
-    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
-        return model.searchForUserByAttributes(attributes, this);
-    }
-
-
-    @Override
     public Map<String, String> getSmtpConfig() {
         return realm.getSmtpConfig();
     }
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 ba47283..c2a8317 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
@@ -1,22 +1,22 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Wrapper around RoleData object, which will persist wrapped object after each set operation (compatibility with picketlink based idm)
  *
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 36728dc..c1a4267 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
@@ -2,11 +2,11 @@ package org.keycloak.models.mongo.keycloak.entities;
 
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
-import org.keycloak.models.entities.RealmEntity;
 import org.keycloak.connections.mongo.api.MongoCollection;
 import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
 import org.keycloak.connections.mongo.api.MongoIndex;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.entities.RealmEntity;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
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 46f1df9..be034da 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
@@ -3,13 +3,13 @@ package org.keycloak.models.mongo.keycloak.entities;
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 import org.jboss.logging.Logger;
-import org.keycloak.models.entities.RoleEntity;
 import org.keycloak.connections.mongo.api.MongoCollection;
 import org.keycloak.connections.mongo.api.MongoField;
 import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
 import org.keycloak.connections.mongo.api.MongoIndex;
 import org.keycloak.connections.mongo.api.MongoStore;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.entities.RoleEntity;
 
 import java.util.List;
 
diff --git a/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.RealmProviderFactory b/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.RealmProviderFactory
new file mode 100755
index 0000000..deffafa
--- /dev/null
+++ b/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.RealmProviderFactory
@@ -0,0 +1 @@
+org.keycloak.models.mongo.keycloak.adapters.MongoRealmProviderFactory
\ No newline at end of file
diff --git a/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.UserProviderFactory b/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.UserProviderFactory
new file mode 100755
index 0000000..ddc04d8
--- /dev/null
+++ b/model/mongo/src/main/resources/META-INF/services/org.keycloak.models.UserProviderFactory
@@ -0,0 +1 @@
+org.keycloak.models.mongo.keycloak.adapters.MongoUserProviderFactory
\ No newline at end of file
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
index 9fa72d0..9b02e14 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
@@ -16,7 +16,12 @@ import org.picketlink.idm.model.sample.SampleModel;
 import org.picketlink.idm.query.IdentityQuery;
 import org.picketlink.idm.query.RelationshipQuery;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
index 36d7098..bb1b564 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
@@ -1,7 +1,6 @@
 package org.keycloak.models.picketlink;
 
 import org.bouncycastle.openssl.PEMWriter;
-import org.keycloak.util.PemUtils;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.IdGenerator;
 import org.keycloak.models.KeycloakSession;
@@ -22,6 +21,7 @@ import org.keycloak.models.picketlink.relationships.RequiredApplicationCredentia
 import org.keycloak.models.picketlink.relationships.RequiredCredentialRelationship;
 import org.keycloak.models.picketlink.relationships.ScopeRelationship;
 import org.keycloak.models.picketlink.relationships.SocialLinkRelationship;
+import org.keycloak.util.PemUtils;
 import org.picketlink.idm.IdentityManagementException;
 import org.picketlink.idm.IdentityManager;
 import org.picketlink.idm.PartitionManager;
@@ -46,7 +46,14 @@ import java.io.StringWriter;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Meant to be a per-request object
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java
index e44c7b1..16c2500 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java
@@ -2,13 +2,13 @@ package org.keycloak.models.realms.jpa;
 
 import org.keycloak.models.realms.Application;
 import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.RoleContainer;
-import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 import org.keycloak.models.realms.jpa.entities.ApplicationEntity;
 import org.keycloak.models.realms.jpa.entities.RoleEntity;
+import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java
index 660646e..147a4aa 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.realms.jpa;
 
 import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.RoleContainer;
-import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 import org.keycloak.models.realms.jpa.entities.ClientEntity;
+import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java
index 9f8f043..00c833c 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java
@@ -1,15 +1,15 @@
 package org.keycloak.models.realms.jpa;
 
+import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.realms.Application;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.OAuthClient;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.jpa.entities.ApplicationEntity;
 import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.realms.jpa.entities.RealmEntity;
 import org.keycloak.models.realms.jpa.entities.RoleEntity;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java
index e181b8e..f5c72cd 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java
@@ -1,9 +1,9 @@
 package org.keycloak.models.realms.jpa;
 
 import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.RealmProviderFactory;
-import org.keycloak.models.KeycloakSession;
 import org.keycloak.util.JpaUtils;
 
 import javax.persistence.EntityManagerFactory;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java
index 39bf489..b792a7d 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java
@@ -1,8 +1,7 @@
 package org.keycloak.models.realms.jpa;
 
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.OAuthClient;
-import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
 
 import javax.persistence.EntityManager;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java
index 578fa65..ffbbacf 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java
@@ -1,21 +1,21 @@
 package org.keycloak.models.realms.jpa;
 
-import org.keycloak.models.realms.Application;
-import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.realms.Application;
+import org.keycloak.models.realms.Client;
 import org.keycloak.models.realms.OAuthClient;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.jpa.entities.ApplicationEntity;
 import org.keycloak.models.realms.jpa.entities.AuthenticationProviderEntity;
+import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.realms.jpa.entities.RealmEntity;
 import org.keycloak.models.realms.jpa.entities.RequiredCredentialEntity;
 import org.keycloak.models.realms.jpa.entities.RoleEntity;
 import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
-import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
-import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
index e08448e..fac9375 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
@@ -1,10 +1,8 @@
 package org.keycloak.models.sessions.jpa.entities;
 
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
-import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import java.io.Serializable;
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java
old mode 100644
new mode 100755
index 1fdbb8f..fca5ca1
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java
@@ -5,11 +5,8 @@ import org.keycloak.connections.jpa.JpaConnectionProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.UserSessionProviderFactory;
-import org.keycloak.util.JpaUtils;
 
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java
index aef6f2e..490134f 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/UserSessionAdapter.java
@@ -45,7 +45,7 @@ public class UserSessionAdapter implements UserSessionModel {
 
     @Override
     public UserModel getUser() {
-        return realm.getUserById(entity.getUserId());
+        return session.users().getUserById(entity.getUserId(), realm);
     }
 
     @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
old mode 100644
new mode 100755
index d5369e4..0ebdefd
--- 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
@@ -2,7 +2,6 @@ package org.keycloak.models.sessions.mem;
 
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java
old mode 100644
new mode 100755
index 1ff9326..6a62ba7
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/UserSessionAdapter.java
@@ -36,7 +36,7 @@ public class UserSessionAdapter implements UserSessionModel {
     }
 
     public UserModel getUser() {
-        return realm.getUserById(entity.getUser());
+        return session.users().getUserById(entity.getUser(), realm);
     }
 
     public void setUser(UserModel user) {
diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
old mode 100644
new mode 100755
index 1cbcb41..cbce2bd
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
@@ -47,7 +47,7 @@ public class MongoUserSessionProvider implements UserSessionProvider {
         entity.setLastSessionRefresh(currentTime);
 
         mongoStore.insertEntity(entity, invocationContext);
-        return new UserSessionAdapter(entity, realm, invocationContext);
+        return new UserSessionAdapter(session, entity, realm, invocationContext);
     }
 
     @Override
@@ -56,7 +56,7 @@ public class MongoUserSessionProvider implements UserSessionProvider {
         if (entity == null) {
             return null;
         } else {
-            return new UserSessionAdapter(entity, realm, invocationContext);
+            return new UserSessionAdapter(session, entity, realm, invocationContext);
         }
     }
 
@@ -65,7 +65,7 @@ public class MongoUserSessionProvider implements UserSessionProvider {
         DBObject query = new BasicDBObject("user", user.getId());
         List<UserSessionModel> sessions = new LinkedList<UserSessionModel>();
         for (MongoUserSessionEntity e : mongoStore.loadEntities(MongoUserSessionEntity.class, query, invocationContext)) {
-            sessions.add(new UserSessionAdapter(e, realm, invocationContext));
+            sessions.add(new UserSessionAdapter(session, e, realm, invocationContext));
         }
         return sessions;
     }
@@ -79,7 +79,7 @@ public class MongoUserSessionProvider implements UserSessionProvider {
 
         List<UserSessionModel> result = new LinkedList<UserSessionModel>();
         for (MongoUserSessionEntity session : sessions) {
-            result.add(new UserSessionAdapter(session, realm, invocationContext));
+            result.add(new UserSessionAdapter(this.session, session, realm, invocationContext));
         }
         return result;
     }
@@ -93,7 +93,7 @@ public class MongoUserSessionProvider implements UserSessionProvider {
         List<MongoUserSessionEntity> sessions = mongoStore.loadEntities(MongoUserSessionEntity.class, query, sort, invocationContext, firstResult, maxResults);
         List<UserSessionModel> result = new LinkedList<UserSessionModel>();
         for (MongoUserSessionEntity session : sessions) {
-            result.add(new UserSessionAdapter(session, realm, invocationContext));
+            result.add(new UserSessionAdapter(this.session, session, realm, invocationContext));
         }
         return result;
     }
diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java
index 4586345..901dd24 100755
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/UserSessionAdapter.java
@@ -3,6 +3,7 @@ package org.keycloak.models.sessions.mongo;
 import org.jboss.logging.Logger;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
@@ -20,12 +21,14 @@ public class UserSessionAdapter extends AbstractMongoAdapter<MongoUserSessionEnt
 
     private MongoUserSessionEntity entity;
     private RealmModel realm;
+    private KeycloakSession keycloakSession;
 
-    public UserSessionAdapter(MongoUserSessionEntity entity, RealmModel realm, MongoStoreInvocationContext invContext)
+    public UserSessionAdapter(KeycloakSession keycloakSession, MongoUserSessionEntity entity, RealmModel realm, MongoStoreInvocationContext invContext)
     {
         super(invContext);
         this.entity = entity;
         this.realm = realm;
+        this.keycloakSession = keycloakSession;
     }
 
     @Override
@@ -46,7 +49,7 @@ public class UserSessionAdapter extends AbstractMongoAdapter<MongoUserSessionEnt
 
     @Override
     public UserModel getUser() {
-        return realm.getUserById(entity.getUser());
+        return keycloakSession.users().getUserById(entity.getUser(), realm);
     }
 
     @Override
diff --git a/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java b/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java
old mode 100644
new mode 100755
index 354bc86..4101191
--- a/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java
+++ b/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java
@@ -1,11 +1,8 @@
 package org.keycloak.model.test;
 
-import java.io.File;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Properties;
+import org.keycloak.models.LDAPConstants;
+import org.keycloak.models.RealmModel;
+import org.picketbox.test.ldap.AbstractLDAPTest;
 
 import javax.naming.CompositeName;
 import javax.naming.Context;
@@ -16,10 +13,12 @@ import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
-
-import org.keycloak.models.LDAPConstants;
-import org.keycloak.models.RealmModel;
-import org.picketbox.test.ldap.AbstractLDAPTest;
+import java.io.File;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
 
 /**
  * Forked from Picketlink project
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
index 0d85abf..0779fe5 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
@@ -8,7 +8,7 @@ import org.junit.BeforeClass;
 import org.keycloak.Config;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -31,7 +31,7 @@ public class AbstractModelTest {
 
     protected KeycloakSession session;
     protected RealmManager realmManager;
-    protected ModelProvider model;
+    protected RealmProvider model;
 
     @BeforeClass
     public static void beforeClass() {
@@ -56,7 +56,7 @@ public class AbstractModelTest {
     public void before() throws Exception {
         session = sessionFactory.create();
         session.getTransaction().begin();
-        model = session.model();
+        model = session.realms();
         realmManager = new RealmManager(session);
     }
 
@@ -68,7 +68,7 @@ public class AbstractModelTest {
         session = sessionFactory.create();
         try {
             session.getTransaction().begin();
-            model = session.model();
+            model = session.realms();
 
             RealmManager rm = new RealmManager(session);
             for (RealmModel realm : model.getRealms()) {
@@ -106,7 +106,7 @@ public class AbstractModelTest {
 
         session = sessionFactory.create();
         session.getTransaction().begin();
-        model = session.model();
+        model = session.realms();
         realmManager = new RealmManager(session);
     }
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index 412ef28..edb4e40 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -129,7 +129,7 @@ public class AdapterTest extends AbstractModelTest {
     @Test
     public void testCredentialValidation() throws Exception {
         test1CreateRealm();
-        UserModel user = realmModel.addUser("bburke");
+        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
         UserCredentialModel cred = new UserCredentialModel();
         cred.setType(CredentialRepresentation.PASSWORD);
         cred.setValue("geheim");
@@ -157,7 +157,7 @@ public class AdapterTest extends AbstractModelTest {
     public void testDeleteUser() throws Exception {
         test1CreateRealm();
 
-        UserModel user = realmModel.addUser("bburke");
+        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
         user.setAttribute("attr1", "val1");
         user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
 
@@ -169,7 +169,7 @@ public class AdapterTest extends AbstractModelTest {
         user.grantRole(appRole);
 
         SocialLinkModel socialLink = new SocialLinkModel("google", "google1", user.getUsername());
-        realmModel.addSocialLink(user, socialLink);
+        realmManager.getSession().users().addSocialLink(realmModel, user, socialLink);
 
         UserCredentialModel cred = new UserCredentialModel();
         cred.setType(CredentialRepresentation.PASSWORD);
@@ -179,16 +179,16 @@ public class AdapterTest extends AbstractModelTest {
         commit();
 
         realmModel = model.getRealm("JUGGLER");
-        Assert.assertTrue(realmModel.removeUser("bburke"));
-        Assert.assertFalse(realmModel.removeUser("bburke"));
-        assertNull(realmModel.getUser("bburke"));
+        Assert.assertTrue(realmManager.getSession().users().removeUser(realmModel, "bburke"));
+        Assert.assertFalse(realmManager.getSession().users().removeUser(realmModel, "bburke"));
+        assertNull(realmManager.getSession().users().getUserByUsername("bburke", realmModel));
     }
 
     @Test
     public void testRemoveApplication() throws Exception {
         test1CreateRealm();
 
-        UserModel user = realmModel.addUser("bburke");
+        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
 
         OAuthClientModel client = realmModel.addOAuthClient("client");
 
@@ -211,7 +211,7 @@ public class AdapterTest extends AbstractModelTest {
     public void testRemoveRealm() throws Exception {
         test1CreateRealm();
 
-        UserModel user = realmModel.addUser("bburke");
+        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
 
         UserCredentialModel cred = new UserCredentialModel();
         cred.setType(CredentialRepresentation.PASSWORD);
@@ -246,7 +246,7 @@ public class AdapterTest extends AbstractModelTest {
     public void testRemoveRole() throws Exception {
         test1CreateRealm();
 
-        UserModel user = realmModel.addUser("bburke");
+        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
 
         OAuthClientModel client = realmModel.addOAuthClient("client");
 
@@ -276,17 +276,17 @@ public class AdapterTest extends AbstractModelTest {
     public void testUserSearch() throws Exception {
         test1CreateRealm();
         {
-            UserModel user = realmModel.addUser("bburke");
+            UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
             user.setLastName("Burke");
             user.setFirstName("Bill");
             user.setEmail("bburke@redhat.com");
 
-            UserModel user2 = realmModel.addUser("doublefirst");
+            UserModel user2 = realmManager.getSession().users().addUser(realmModel, "doublefirst");
             user2.setFirstName("Knut Ole");
             user2.setLastName("Alver");
             user2.setEmail("knut@redhat.com");
 
-            UserModel user3 = realmModel.addUser("doublelast");
+            UserModel user3 = realmManager.getSession().users().addUser(realmModel, "doublelast");
             user3.setFirstName("Ole");
             user3.setLastName("Alver Veland");
             user3.setEmail("knut2@redhat.com");
@@ -373,14 +373,14 @@ public class AdapterTest extends AbstractModelTest {
         }
 
         {
-            UserModel user = realmModel.addUser("mburke");
+            UserModel user = realmManager.getSession().users().addUser(realmModel, "mburke");
             user.setLastName("Burke");
             user.setFirstName("Monica");
             user.setEmail("mburke@redhat.com");
         }
 
         {
-            UserModel user = realmModel.addUser("thor");
+            UserModel user = realmManager.getSession().users().addUser(realmModel, "thor");
             user.setLastName("Thorgersen");
             user.setFirstName("Stian");
             user.setEmail("thor@redhat.com");
@@ -428,10 +428,10 @@ public class AdapterTest extends AbstractModelTest {
         }
 
         RealmModel otherRealm = adapter.createRealm("other");
-        otherRealm.addUser("bburke");
+        realmManager.getSession().users().addUser(otherRealm, "bburke");
 
-        Assert.assertEquals(1, otherRealm.getUsers().size());
-        Assert.assertEquals(1, otherRealm.searchForUser("bu").size());
+        Assert.assertEquals(1, realmManager.getSession().users().getUsers(otherRealm).size());
+        Assert.assertEquals(1, realmManager.getSession().users().searchForUser("bu", otherRealm).size());
     }
 
 
@@ -442,7 +442,7 @@ public class AdapterTest extends AbstractModelTest {
         realmModel.addRole("user");
         Set<RoleModel> roles = realmModel.getRoles();
         Assert.assertEquals(3, roles.size());
-        UserModel user = realmModel.addUser("bburke");
+        UserModel user = realmManager.getSession().users().addUser(realmModel, "bburke");
         RoleModel realmUserRole = realmModel.getRole("user");
         user.grantRole(realmUserRole);
         Assert.assertTrue(user.hasRole(realmUserRole));
@@ -616,13 +616,16 @@ public class AdapterTest extends AbstractModelTest {
 
     @Test
     public void testUsernameCollisions() throws Exception {
-        realmManager.createRealm("JUGGLER1").addUser("user1");
-        realmManager.createRealm("JUGGLER2").addUser("user1");
+        RealmModel juggler1 = realmManager.createRealm("JUGGLER1");
+        realmManager.getSession().users().addUser(juggler1, "user1");
+        RealmModel juggler2 = realmManager.createRealm("JUGGLER2");
+        realmManager.getSession().users().addUser(juggler2, "user1");
         commit();
 
         // Try to create user with duplicate login name
         try {
-            realmManager.getRealmByName("JUGGLER1").addUser("user1");
+            juggler1 = realmManager.getRealmByName("JUGGLER1");
+            realmManager.getSession().users().addUser(juggler1, "user1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -630,10 +633,12 @@ public class AdapterTest extends AbstractModelTest {
         commit(true);
 
         // Ty to rename user to duplicate login name
-        realmManager.getRealmByName("JUGGLER1").addUser("user2");
+        juggler1 = realmManager.getRealmByName("JUGGLER1");
+        realmManager.getSession().users().addUser(juggler1, "user2");
         commit();
         try {
-            realmManager.getRealmByName("JUGGLER1").getUser("user2").setUsername("user1");
+            juggler1 = realmManager.getRealmByName("JUGGLER1");
+            realmManager.getSession().users().getUserByUsername("user2", juggler1).setUsername("user1");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -644,13 +649,16 @@ public class AdapterTest extends AbstractModelTest {
 
     @Test
     public void testEmailCollisions() throws Exception {
-        realmManager.createRealm("JUGGLER1").addUser("user1").setEmail("email@example.com");
-        realmManager.createRealm("JUGGLER2").addUser("user1").setEmail("email@example.com");
+        RealmModel juggler1 = realmManager.createRealm("JUGGLER1");
+        realmManager.getSession().users().addUser(juggler1, "user1").setEmail("email@example.com");
+        RealmModel juggler2 = realmManager.createRealm("JUGGLER2");
+        realmManager.getSession().users().addUser(juggler2, "user1").setEmail("email@example.com");
         commit();
 
         // Try to create user with duplicate email
+        juggler1 = realmManager.getRealmByName("JUGGLER1");
         try {
-            realmManager.getRealmByName("JUGGLER1").addUser("user2").setEmail("email@example.com");
+            realmManager.getSession().users().addUser(juggler1, "user2").setEmail("email@example.com");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
@@ -659,10 +667,12 @@ public class AdapterTest extends AbstractModelTest {
         resetSession();
 
         // Ty to rename user to duplicate email
-        realmManager.getRealmByName("JUGGLER1").addUser("user3").setEmail("email2@example.com");
+        juggler1 = realmManager.getRealmByName("JUGGLER1");
+        realmManager.getSession().users().addUser(juggler1, "user3").setEmail("email2@example.com");
         commit();
         try {
-            realmManager.getRealmByName("JUGGLER1").getUser("user3").setEmail("email@example.com");
+            juggler1 = realmManager.getRealmByName("JUGGLER1");
+            realmManager.getSession().users().getUserByUsername("user3", juggler1).setEmail("email@example.com");
             commit();
             Assert.fail("Expected exception");
         } catch (ModelDuplicateException e) {
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
index 58c0444..ed62c37 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
@@ -6,7 +6,6 @@ import org.junit.Test;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ApplicationRepresentation;
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java
index 5c18625..a8491c3 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java
@@ -18,7 +18,6 @@ import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus
 import org.keycloak.services.managers.BruteForceProtector;
 
 import javax.ws.rs.core.MultivaluedMap;
-
 import java.util.Arrays;
 import java.util.UUID;
 
@@ -168,7 +167,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
         protector.start();
         am = new AuthenticationManager(protector);
 
-        user = realm.addUser("test");
+        user = realmManager.getSession().users().addUser(realm, "test");
         user.setEnabled(true);
 
         UserCredentialModel credential = new UserCredentialModel();
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java
old mode 100644
new mode 100755
index 166b3f4..308c8f7
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java
@@ -1,17 +1,17 @@
 package org.keycloak.model.test;
 
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.authentication.AuthProviderConstants;
+import org.keycloak.models.AuthenticationProviderModel;
+import org.keycloak.models.RealmModel;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.junit.Assert;
-import org.junit.Test;
-import org.keycloak.models.AuthenticationProviderModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.authentication.AuthProviderConstants;
-
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java
index 12c11c9..2d30404 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java
@@ -1,13 +1,5 @@
 package org.keycloak.model.test;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.MultivaluedMap;
-
 import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.junit.Assert;
@@ -15,6 +7,9 @@ import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.keycloak.authentication.AuthProviderConstants;
+import org.keycloak.authentication.AuthenticationProviderException;
+import org.keycloak.authentication.AuthenticationProviderManager;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.KeycloakSession;
@@ -24,9 +19,13 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.authentication.AuthProviderConstants;
-import org.keycloak.authentication.AuthenticationProviderException;
-import org.keycloak.authentication.AuthenticationProviderManager;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -54,7 +53,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
         realm1.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
         realm2.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
 
-        UserModel john = realm1.addUser("john");
+        UserModel john = realmManager.getSession().users().addUser(realm1, "john");
         john.setEnabled(true);
         john.setFirstName("John");
         john.setLastName("Doe");
@@ -78,7 +77,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
 
         // Verify that user doesn't exists in realm2 and can't authenticate here
         Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm2, formData));
-        Assert.assertNull(realm2.getUser("john"));
+        Assert.assertNull(realmManager.getSession().users().getUserByUsername("john", realm2));
 
         // Add externalModel authenticationProvider into realm2 and point to realm1
         setupAuthenticationProviders();
@@ -89,7 +88,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
 
             // Authenticate john in realm2 and verify that now he exists here.
             Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm2, formData));
-            UserModel john2 = realm2.getUser("john");
+            UserModel john2 = realmManager.getSession().users().getUserByUsername("john", realm2);
             Assert.assertNotNull(john2);
             Assert.assertEquals("john", john2.getUsername());
             Assert.assertEquals("John", john2.getFirstName());
@@ -100,7 +99,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
             AuthenticationLinkModel authLink = john2.getAuthenticationLink();
             Assert.assertNotNull(authLink);
             Assert.assertEquals(authLink.getAuthProvider(), AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL);
-            Assert.assertEquals(authLink.getAuthUserId(), realm1.getUser("john").getId());
+            Assert.assertEquals(authLink.getAuthUserId(), realmManager.getSession().users().getUserByUsername("john", realm1).getId());
         } finally {
             ResteasyProviderFactory.clearContextData();
         }
@@ -113,9 +112,9 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
         setupAuthenticationProviders();
 
         // Add john to realm2 and set authentication link
-        UserModel john = realm2.addUser("john");
+        UserModel john = realmManager.getSession().users().addUser(realm2, "john");
         john.setEnabled(true);
-        john.setAuthenticationLink(new AuthenticationLinkModel(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, realm1.getUser("john").getId()));
+        john.setAuthenticationLink(new AuthenticationLinkModel(AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL, realmManager.getSession().users().getUserByUsername("john", realm1).getId()));
 
         try {
             // this is needed for externalModel provider
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
index ae927f8..90c074c 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
@@ -1,10 +1,5 @@
 package org.keycloak.model.test;
 
-import java.util.Arrays;
-import java.util.Collections;
-
-import javax.ws.rs.core.MultivaluedMap;
-
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Before;
@@ -12,6 +7,9 @@ import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.keycloak.authentication.AuthProviderConstants;
+import org.keycloak.authentication.AuthenticationProviderException;
+import org.keycloak.authentication.AuthenticationProviderManager;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.RealmModel;
@@ -19,9 +17,10 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.authentication.AuthProviderConstants;
-import org.keycloak.authentication.AuthenticationProviderException;
-import org.keycloak.authentication.AuthenticationProviderManager;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -80,14 +79,14 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
 
         // Verify that user doesn't exists in realm2 and can't authenticate here
         Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm, formData));
-        Assert.assertNull(realm.getUser("johnkeycloak"));
+        Assert.assertNull(session.users().getUserByUsername("johnkeycloak", realm));
 
         // Add ldap authenticationProvider
         setupAuthenticationProviders();
 
         // Authenticate john and verify that now he exists in realm
         Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
-        UserModel john = realm.getUser("johnkeycloak");
+        UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
         Assert.assertNotNull(john);
         Assert.assertEquals("johnkeycloak", john.getUsername());
         Assert.assertEquals("John", john.getFirstName());
@@ -103,9 +102,8 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
     @Test
     public void testLdapInvalidAuthentication() {
         setupAuthenticationProviders();
-
         // Add some user and password to realm
-        UserModel realmUser = realm.addUser("realmUser");
+        UserModel realmUser = session.users().addUser(realm, "realmUser");
         realmUser.setEnabled(true);
         UserCredentialModel credential = new UserCredentialModel();
         credential.setType(CredentialRepresentation.PASSWORD);
@@ -149,7 +147,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
         // Change credential and validate that user can authenticate
         AuthenticationProviderManager authProviderManager = AuthenticationProviderManager.getManager(realm, session);
 
-        UserModel john = realm.getUser("johnkeycloak");
+        UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
         try {
             Assert.assertTrue(authProviderManager.updatePassword(john, "password-updated"));
         } catch (AuthenticationProviderException ape) {
diff --git a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
index 071fcef..768e9d0 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
@@ -1,8 +1,5 @@
 package org.keycloak.model.test;
 
-import java.util.HashSet;
-import java.util.Set;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -13,6 +10,9 @@ import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
@@ -57,7 +57,7 @@ public class CompositeRolesModelTest extends AbstractModelTest {
         Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
 
         RealmModel realm = realmManager.getRealm("Test");
-        UserModel user = realm.getUser(username);
+        UserModel user = realmManager.getSession().users().getUserByUsername(username, realm);
         ApplicationModel application = realm.getApplicationByName(applicationName);
 
         Set<RoleModel> roleMappings = user.getRoleMappings();
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
index a2a0c39..c013155 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
@@ -4,12 +4,13 @@ import org.junit.Assert;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
-import org.keycloak.models.AccountRoles;
+import org.keycloak.authentication.AuthProviderConstants;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
@@ -17,7 +18,6 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.authentication.AuthProviderConstants;
 
 import java.util.List;
 import java.util.Map;
@@ -50,7 +50,7 @@ public class ImportTest extends AbstractModelTest {
         commit();
 
         realm = realmManager.getRealm("demo");
-        assertDataImportedInRealm(realm);
+        assertDataImportedInRealm(realmManager.getSession(), realm);
 
         commit();
 
@@ -59,7 +59,7 @@ public class ImportTest extends AbstractModelTest {
     }
 
     // Moved to static method, so it's possible to test this from other places too (for example export-import tests)
-    public static void assertDataImportedInRealm(RealmModel realm) {
+    public static void assertDataImportedInRealm(KeycloakSession session, RealmModel realm) {
         Assert.assertTrue(realm.isVerifyEmail());
 
         Assert.assertFalse(realm.isUpdateProfileOnInitialSocialLogin());
@@ -72,9 +72,9 @@ public class ImportTest extends AbstractModelTest {
         Assert.assertNotNull(realm.getRole("foo"));
         Assert.assertNotNull(realm.getRole("bar"));
 
-        UserModel user = realm.getUser("loginclient");
+        UserModel user = session.users().getUserByUsername("loginclient", realm);
         Assert.assertNotNull(user);
-        Assert.assertEquals(0, realm.getSocialLinks(user).size());
+        Assert.assertEquals(0,  session.users().getSocialLinks(user, realm).size());
 
         List<ApplicationModel> resources = realm.getApplications();
         for (ApplicationModel app : resources) {
@@ -103,14 +103,14 @@ public class ImportTest extends AbstractModelTest {
 
 
         // Test role mappings
-        UserModel admin = realm.getUser("admin");
+        UserModel admin =  session.users().getUserByUsername("admin", realm);
         Set<RoleModel> allRoles = admin.getRoleMappings();
         Assert.assertEquals(3, allRoles.size());
         Assert.assertTrue(allRoles.contains(realm.getRole("admin")));
         Assert.assertTrue(allRoles.contains(application.getRole("app-admin")));
         Assert.assertTrue(allRoles.contains(otherApp.getRole("otherapp-admin")));
 
-        UserModel wburke = realm.getUser("wburke");
+        UserModel wburke =  session.users().getUserByUsername("wburke", realm);
         allRoles = wburke.getRoleMappings();
         Assert.assertEquals(2, allRoles.size());
         Assert.assertFalse(allRoles.contains(realm.getRole("admin")));
@@ -147,8 +147,8 @@ public class ImportTest extends AbstractModelTest {
 
 
         // Test social linking
-        UserModel socialUser = realm.getUser("mySocialUser");
-        Set<SocialLinkModel> socialLinks = realm.getSocialLinks(socialUser);
+        UserModel socialUser = session.users().getUserByUsername("mySocialUser", realm);
+        Set<SocialLinkModel> socialLinks = session.users().getSocialLinks(socialUser, realm);
         Assert.assertEquals(3, socialLinks.size());
         boolean facebookFound = false;
         boolean googleFound = false;
@@ -170,19 +170,19 @@ public class ImportTest extends AbstractModelTest {
         }
         Assert.assertTrue(facebookFound && twitterFound && googleFound);
 
-        UserModel foundSocialUser = realm.getUserBySocialLink(new SocialLinkModel("facebook", "facebook1", "fbuser1"));
+        UserModel foundSocialUser = session.users().getUserBySocialLink(new SocialLinkModel("facebook", "facebook1", "fbuser1"), realm);
         Assert.assertEquals(foundSocialUser.getUsername(), socialUser.getUsername());
-        Assert.assertNull(realm.getUserBySocialLink(new SocialLinkModel("facebook", "not-existing", "not-existing")));
+        Assert.assertNull(session.users().getUserBySocialLink(new SocialLinkModel("facebook", "not-existing", "not-existing"), realm));
 
-        SocialLinkModel foundSocialLink = realm.getSocialLink(socialUser, "facebook");
+        SocialLinkModel foundSocialLink = session.users().getSocialLink(socialUser, "facebook", realm);
         Assert.assertEquals("facebook1", foundSocialLink.getSocialUserId());
         Assert.assertEquals("fbuser1", foundSocialLink.getSocialUsername());
         Assert.assertEquals("facebook", foundSocialLink.getSocialProvider());
 
         // Test removing social link
-        Assert.assertTrue(realm.removeSocialLink(socialUser, "facebook"));
-        Assert.assertNull(realm.getSocialLink(socialUser, "facebook"));
-        Assert.assertFalse(realm.removeSocialLink(socialUser, "facebook"));
+        Assert.assertTrue(session.users().removeSocialLink(realm, socialUser, "facebook"));
+        Assert.assertNull(session.users().getSocialLink(socialUser, "facebook", realm));
+        Assert.assertFalse(session.users().removeSocialLink(realm, socialUser, "facebook"));
 
         // Test smtp config
         Map<String, String> smtpConfig = realm.getSmtpConfig();
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
index 9d53df1..14a315e 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
@@ -4,8 +4,8 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
-import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
 
 import java.util.HashMap;
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
index ce6b937..3aa4d4b 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
@@ -31,8 +31,8 @@ public class MultipleRealmsTest extends AbstractModelTest {
 
     @Test
     public void testUsers() {
-        UserModel r1user1 = realm1.getUser("user1");
-        UserModel r2user1 = realm2.getUser("user1");
+        UserModel r1user1 = realmManager.getSession().users().getUserByUsername("user1", realm1);
+        UserModel r2user1 = realmManager.getSession().users().getUserByUsername("user1", realm2);
         Assert.assertEquals(r1user1.getUsername(), r2user1.getUsername());
         Assert.assertNotEquals(r1user1.getId(), r2user1.getId());
 
@@ -46,16 +46,16 @@ public class MultipleRealmsTest extends AbstractModelTest {
         Assert.assertTrue(realm2.validatePassword(r2user1, "pass2"));
 
         // Test searching
-        Assert.assertEquals(2, realm1.searchForUser("user").size());
+        Assert.assertEquals(2, realmManager.getSession().users().searchForUser("user", realm1).size());
 
         commit();
         realm1 = model.getRealm("id1");
         realm2 = model.getRealm("id2");
 
-        realm1.removeUser("user1");
-        realm1.removeUser("user2");
-        Assert.assertEquals(0, realm1.searchForUser("user").size());
-        Assert.assertEquals(2, realm2.searchForUser("user").size());
+        realmManager.getSession().users().removeUser(realm1, "user1");
+        realmManager.getSession().users().removeUser(realm1, "user2");
+        Assert.assertEquals(0, realmManager.getSession().users().searchForUser("user", realm1).size());
+        Assert.assertEquals(2, realmManager.getSession().users().searchForUser("user", realm2).size());
     }
 
     @Test
@@ -90,8 +90,8 @@ public class MultipleRealmsTest extends AbstractModelTest {
         ApplicationModel app1 = realm.addApplication("app1");
         realm.addApplication("app2");
 
-        realm.addUser("user1");
-        realm.addUser("user2");
+        realmManager.getSession().users().addUser(realm, "user1");
+        realmManager.getSession().users().addUser(realm, "user2");
 
         realm.addRole("role1");
         realm.addRole("role2");
diff --git a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
index 3de0ae2..15ce423 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
@@ -2,8 +2,8 @@ package org.keycloak.model.test;
 
 import org.junit.Assert;
 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.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
@@ -16,7 +16,8 @@ public class UserModelTest extends AbstractModelTest {
     @Test
     public void persistUser() {
         RealmModel realm = realmManager.createRealm("original");
-        UserModel user = realm.addUser("user");
+        KeycloakSession session = realmManager.getSession();
+        UserModel user = session.users().addUser(realm, "user");
         user.setFirstName("first-name");
         user.setLastName("last-name");
         user.setEmail("email");
@@ -24,11 +25,13 @@ public class UserModelTest extends AbstractModelTest {
         user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
         user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
 
-        UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user");
+        RealmModel searchRealm = realmManager.getRealm(realm.getId());
+        UserModel persisted = session.users().getUserByUsername("user", searchRealm);
 
         assertEquals(user, persisted);
 
-        UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId());
+        searchRealm = realmManager.getRealm(realm.getId());
+        UserModel persisted2 =  session.users().getUserById(user.getId(), searchRealm);
         assertEquals(user, persisted2);
     }
     
@@ -72,7 +75,8 @@ public class UserModelTest extends AbstractModelTest {
     @Test
     public void testUserRequiredActions() throws Exception {
         RealmModel realm = realmManager.createRealm("original");
-        UserModel user = realm.addUser("user");
+        KeycloakSession session = realmManager.getSession();
+        UserModel user = session.users().addUser(realm, "user");
 
         Assert.assertTrue(user.getRequiredActions().isEmpty());
 
@@ -80,32 +84,32 @@ public class UserModelTest extends AbstractModelTest {
         String id = realm.getId();
         commit();
         realm = realmManager.getRealm(id);
-        user = realm.getUser("user");
+        user = session.users().getUserByUsername("user", realm);
 
         Assert.assertEquals(1, user.getRequiredActions().size());
         Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
 
         user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
-        user = realm.getUser("user");
+        user = session.users().getUserByUsername("user", realm);
 
         Assert.assertEquals(1, user.getRequiredActions().size());
         Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
 
         user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
-        user = realm.getUser("user");
+        user = session.users().getUserByUsername("user", realm);
 
         Assert.assertEquals(2, user.getRequiredActions().size());
         Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
         Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
 
         user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
-        user = realm.getUser("user");
+        user = session.users().getUserByUsername("user", realm);
 
         Assert.assertEquals(1, user.getRequiredActions().size());
         Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
 
         user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
-        user = realm.getUser("user");
+        user = session.users().getUserByUsername("user", realm);
 
         Assert.assertTrue(user.getRequiredActions().isEmpty());
     }
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java
index 3d0175f..1da3606 100755
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java
@@ -4,7 +4,6 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
 import javax.persistence.ManyToOne;
-
 import java.io.Serializable;
 
 /**
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java
index 64e8b06..2d11563 100755
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java
@@ -2,7 +2,6 @@ package org.keycloak.models.users.jpa;
 
 import org.keycloak.Config;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.users.Feature;
 import org.keycloak.models.users.UserProvider;
 import org.keycloak.models.users.UserProviderFactory;
 import org.keycloak.util.JpaUtils;
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java
old mode 100644
new mode 100755
index ddd1c58..42c02d0
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java
@@ -1,8 +1,8 @@
 package org.keycloak.models.users.jpa;
 
 import org.hibernate.exception.ConstraintViolationException;
-import org.keycloak.models.ModelException;
 import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.ModelException;
 
 import javax.persistence.EntityExistsException;
 import javax.persistence.EntityManager;
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java
index 2851379..fad265a 100755
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java
@@ -5,8 +5,8 @@ import org.keycloak.models.users.Credentials;
 import org.keycloak.models.users.User;
 import org.keycloak.models.users.jpa.entities.UserAttributeEntity;
 import org.keycloak.models.users.jpa.entities.UserCredentialEntity;
-import org.keycloak.models.users.jpa.entities.UserRoleMappingEntity;
 import org.keycloak.models.users.jpa.entities.UserEntity;
+import org.keycloak.models.users.jpa.entities.UserRoleMappingEntity;
 
 import javax.persistence.EntityManager;
 import java.util.ArrayList;
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/UpsSecurityApplication.java b/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/UpsSecurityApplication.java
index ef7a1ef..af9fbed 100755
--- a/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/UpsSecurityApplication.java
+++ b/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/UpsSecurityApplication.java
@@ -30,8 +30,8 @@ public class UpsSecurityApplication extends KeycloakApplication {
         try {
             RealmManager manager = new RealmManager(session);
             RealmModel master = manager.getKeycloakAdminstrationRealm();
-            UserModel admin = master.getUser("admin");
-            if (admin != null) master.removeUser(admin.getUsername());
+            UserModel admin = session.users().getUserByUsername("admin", master);
+            if (admin != null) session.users().removeUser(master, admin.getUsername());
             session.getTransaction().commit();
         } finally {
             session.close();
diff --git a/server/src/main/resources/META-INF/keycloak-server.json b/server/src/main/resources/META-INF/keycloak-server.json
index 8dc062e..7c6d9f8 100755
--- a/server/src/main/resources/META-INF/keycloak-server.json
+++ b/server/src/main/resources/META-INF/keycloak-server.json
@@ -10,16 +10,24 @@
         }
     },
 
-    "model": {
+    "realm": {
         "provider": "jpa"
     },
 
+    "user": {
+        "provider": "${keycloak.user.provider:jpa}"
+    },
+
     "userSessions": {
-        "provider" : "mem"
+        "provider" : "${keycloak.userSessions.provider:mem}"
+    },
+
+    "realmCache": {
+        "provider": "${keycloak.realm.cache.provider:mem}"
     },
 
-    "modelCache": {
-        "provider": "${keycloak.model.cache.provider:}"
+    "userCache": {
+        "provider": "${keycloak.user.cache.provider:mem}"
     },
 
     "timer": {
diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
index caa0b80..8aae6b4 100755
--- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
+++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
@@ -1,12 +1,12 @@
 package org.keycloak.services;
 
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.KeycloakTransactionManager;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.UserSessionProvider;
-import org.keycloak.models.cache.CacheModelProvider;
+import org.keycloak.models.cache.CacheRealmProvider;
+import org.keycloak.models.cache.CacheUserProvider;
 import org.keycloak.provider.Provider;
 import org.keycloak.provider.ProviderFactory;
 
@@ -23,7 +23,8 @@ public class DefaultKeycloakSession implements KeycloakSession {
     private final DefaultKeycloakSessionFactory factory;
     private final Map<Integer, Provider> providers = new HashMap<Integer, Provider>();
     private final DefaultKeycloakTransactionManager transactionManager;
-    private ModelProvider model;
+    private RealmProvider model;
+    private UserProvider userModel;
     private UserSessionProvider sessionProvider;
 
     public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
@@ -31,11 +32,19 @@ public class DefaultKeycloakSession implements KeycloakSession {
         this.transactionManager = new DefaultKeycloakTransactionManager();
     }
 
-    private ModelProvider getModelProvider() {
-        if (factory.getDefaultProvider(CacheModelProvider.class) != null) {
-            return getProvider(CacheModelProvider.class);
+    private RealmProvider getModelProvider() {
+        if (factory.getDefaultProvider(CacheRealmProvider.class) != null) {
+            return getProvider(CacheRealmProvider.class);
         } else {
-            return getProvider(ModelProvider.class);
+            return getProvider(RealmProvider.class);
+        }
+    }
+
+    private UserProvider getUserProvider() {
+        if (factory.getDefaultProvider(CacheUserProvider.class) != null) {
+            return getProvider(CacheUserProvider.class);
+        } else {
+            return getProvider(UserProvider.class);
         }
     }
 
@@ -84,7 +93,7 @@ public class DefaultKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public ModelProvider model() {
+    public RealmProvider realms() {
         if (model == null) {
             model = getModelProvider();
         }
@@ -92,6 +101,14 @@ public class DefaultKeycloakSession implements KeycloakSession {
     }
 
     @Override
+    public UserProvider users() {
+        if (userModel == null) {
+            userModel = getUserProvider();
+        }
+        return userModel;
+    }
+
+    @Override
     public UserSessionProvider sessions() {
         if (sessionProvider == null) {
             sessionProvider = getProvider(UserSessionProvider.class);
diff --git a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
index 1f7605f..179e730 100755
--- a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
+++ b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
@@ -1,23 +1,17 @@
 package org.keycloak.services.managers;
 
-import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
-import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.AccessCode;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.util.Time;
 
-import javax.ws.rs.core.MultivaluedMap;
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
-import java.util.UUID;
 
 /**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -26,10 +20,12 @@ import java.util.UUID;
 public class AccessCodeEntry {
     protected AccessCode accessCode;
     protected RealmModel realm;
+    KeycloakSession keycloakSession;
 
-    public AccessCodeEntry(RealmModel realm, AccessCode accessCode) {
+    public AccessCodeEntry(KeycloakSession keycloakSession, RealmModel realm, AccessCode accessCode) {
         this.realm = realm;
         this.accessCode = accessCode;
+        this.keycloakSession = keycloakSession;
     }
 
     public String getCodeId() {
@@ -37,7 +33,7 @@ public class AccessCodeEntry {
     }
 
     public UserModel getUser() {
-        return realm.getUserById(accessCode.getAccessToken().getSubject());
+        return keycloakSession.users().getUserById(accessCode.getAccessToken().getSubject(), realm);
     }
 
     public String getSessionState() {
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 ebaf3d7..8f5490f 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -40,7 +40,7 @@ public class ApplianceBootstrap {
 
     public void bootstrap(KeycloakSession session, String contextPath) {
         String adminRealmName = Config.getAdminRealm();
-        if (session.model().getRealm(adminRealmName) != null) {
+        if (session.realms().getRealm(adminRealmName) != null) {
             return;
         }
 
@@ -64,7 +64,7 @@ public class ApplianceBootstrap {
 
         realm.setAuditListeners(Collections.singleton("jboss-logging"));
 
-        UserModel adminUser = realm.addUser("admin");
+        UserModel adminUser = session.users().addUser(realm, "admin");
         adminUser.setEnabled(true);
         UserCredentialModel password = new UserCredentialModel();
         password.setType(UserCredentialModel.PASSWORD);
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 c179812..8ce0a51 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -196,7 +196,7 @@ public class AuthenticationManager {
                 }
             }
 
-            UserModel user = realm.getUserById(token.getSubject());
+            UserModel user = session.users().getUserById(token.getSubject(), realm);
             if (user == null || !user.isEnabled() ) {
                 logger.info("Unknown user in identity token");
                 return null;
@@ -253,12 +253,12 @@ public class AuthenticationManager {
     }
 
     protected AuthenticationStatus authenticateInternal(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, String username) {
-        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
+        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
         if (user == null) {
             AuthUser authUser = AuthenticationProviderManager.getManager(realm, session).getUser(username);
             if (authUser != null) {
                 // Create new user and link him with authentication provider
-                user = realm.addUser(authUser.getUsername());
+                user = session.users().addUser(realm, authUser.getUsername());
                 user.setEnabled(true);
                 user.setFirstName(authUser.getFirstName());
                 user.setLastName(authUser.getLastName());
diff --git a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
index 69fdab1..3dab830 100755
--- a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
+++ b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
@@ -128,7 +128,7 @@ public class BruteForceProtector implements Runnable {
     }
 
     protected RealmModel getRealmModel(KeycloakSession session, LoginEvent event) {
-        RealmModel realm = session.model().getRealm(event.realmId);
+        RealmModel realm = session.realms().getRealm(event.realmId);
         if (realm == null) return null;
         return realm;
     }
diff --git a/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java b/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java
old mode 100644
new mode 100755
index a11fd74..468a146
--- a/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java
@@ -1,15 +1,11 @@
 package org.keycloak.services.managers;
 
-import java.util.Hashtable;
-import java.util.Map;
+import org.jboss.logging.Logger;
 
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.naming.ldap.InitialLdapContext;
-
-import org.jboss.logging.Logger;
-import org.keycloak.models.LDAPConstants;
-import org.keycloak.models.RealmModel;
+import java.util.Hashtable;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
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 15ef125..b5d4dd5 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -1,15 +1,14 @@
 package org.keycloak.services.managers;
 
 import org.jboss.logging.Logger;
-import org.keycloak.exportimport.util.ExportImportUtils;
+import org.keycloak.Config;
 import org.keycloak.exportimport.util.ImportUtils;
 import org.keycloak.models.AccountRoles;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.Config;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -18,6 +17,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.RealmAuditRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
+
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -32,7 +32,7 @@ public class RealmManager {
     protected static final Logger logger = Logger.getLogger(RealmManager.class);
 
     protected KeycloakSession session;
-    protected ModelProvider model;
+    protected RealmProvider model;
     protected String contextPath = "";
 
     public String getContextPath() {
@@ -45,7 +45,7 @@ public class RealmManager {
 
     public RealmManager(KeycloakSession session) {
         this.session = session;
-        this.model = session.model();
+        this.model = session.realms();
     }
 
     public KeycloakSession getSession() {
@@ -196,7 +196,7 @@ public class RealmManager {
     }
 
     public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
-        RepresentationToModel.importRealm(rep, newRealm);
+        RepresentationToModel.importRealm(session, rep, newRealm);
     }
 
     /**
@@ -214,7 +214,7 @@ public class RealmManager {
         if (searchString == null) {
             return Collections.emptyList();
         }
-        return realmModel.searchForUser(searchString.trim());
+        return session.users().searchForUser(searchString.trim(), realmModel);
     }
 
 }
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 35a118e..a47892f 100755
--- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
@@ -8,6 +8,7 @@ import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
 import org.keycloak.TokenIdGenerator;
 import org.keycloak.adapters.AdapterConstants;
 import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.adapters.action.LogoutAction;
@@ -34,11 +35,11 @@ import java.util.Map;
 public class ResourceAdminManager {
     protected static Logger logger = Logger.getLogger(ResourceAdminManager.class);
 
-    public SessionStats getSessionStats(URI requestUri, RealmModel realm, ApplicationModel application, boolean users) {
+    public SessionStats getSessionStats(URI requestUri, KeycloakSession session, RealmModel realm, ApplicationModel application, boolean users) {
         ApacheHttpClient4Executor executor = createExecutor();
 
         try {
-            return getSessionStats(requestUri, realm, application, users, executor);
+            return getSessionStats(requestUri, session, realm, application, users, executor);
         } finally {
             executor.getHttpClient().getConnectionManager().shutdown();
         }
@@ -52,7 +53,7 @@ public class ResourceAdminManager {
         return new ApacheHttpClient4Executor(client);
     }
 
-    public SessionStats getSessionStats(URI requestUri, RealmModel realm, ApplicationModel application, boolean users, ApacheHttpClient4Executor client) {
+    public SessionStats getSessionStats(URI requestUri, KeycloakSession session, RealmModel realm, ApplicationModel application, boolean users, ApacheHttpClient4Executor client) {
         String managementUrl = getManagementUrl(requestUri, application);
         if (managementUrl != null) {
             SessionStatsAction adminAction = new SessionStatsAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, application.getName());
@@ -77,7 +78,7 @@ public class ResourceAdminManager {
                 if (users && stats.getUsers() != null) {
                     Map<String, UserStats> newUsers = new HashMap<String, UserStats>();
                     for (Map.Entry<String, UserStats> entry : stats.getUsers().entrySet()) {
-                        UserModel user = realm.getUserById(entry.getKey());
+                        UserModel user = session.users().getUserById(entry.getKey(), realm);
                         if (user == null) continue;
                         newUsers.put(user.getUsername(), entry.getValue());
 
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index 6ab2b75..e8e1161 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -43,7 +43,7 @@ import java.util.UUID;
 public class TokenManager {
     protected static final Logger logger = Logger.getLogger(TokenManager.class);
 
-    public AccessCodeEntry parseCode(String code, RealmModel realm) {
+    public AccessCodeEntry parseCode(String code, KeycloakSession session, RealmModel realm) {
         try {
             JWSInput input = new JWSInput(code);
             if (!RSAProvider.verify(input, realm.getPublicKey())) {
@@ -51,7 +51,7 @@ public class TokenManager {
                 return null;
             }
             AccessCode accessCode = input.readJsonContent(AccessCode.class);
-            return new AccessCodeEntry(realm, accessCode);
+            return new AccessCodeEntry(session, realm, accessCode);
         } catch (Exception e) {
             logger.error("error parsing access code", e);
             return null;
@@ -75,11 +75,11 @@ public class TokenManager {
 
 
 
-    public AccessCodeEntry createAccessCode(String scopeParam, String state, String redirect, RealmModel realm, ClientModel client, UserModel user, UserSessionModel session) {
-        return createAccessCodeEntry(scopeParam, state, redirect, realm, client, user, session);
+    public AccessCodeEntry createAccessCode(String scopeParam, String state, String redirect, KeycloakSession keycloakSession, RealmModel realm, ClientModel client, UserModel user, UserSessionModel session) {
+        return createAccessCodeEntry(scopeParam, state, redirect, keycloakSession, realm, client, user, session);
     }
 
-    private AccessCodeEntry createAccessCodeEntry(String scopeParam, String state, String redirect, RealmModel realm, ClientModel client, UserModel user, UserSessionModel session) {
+    private AccessCodeEntry createAccessCodeEntry(String scopeParam, String state, String redirect, KeycloakSession keycloakSession, RealmModel realm, ClientModel client, UserModel user, UserSessionModel session) {
         List<RoleModel> realmRolesRequested = new LinkedList<RoleModel>();
         MultivaluedMap<String, RoleModel> resourceRolesRequested = new MultivaluedMapImpl<String, RoleModel>();
 
@@ -92,7 +92,7 @@ public class TokenManager {
         code.setExpiration(Time.currentTime() + realm.getAccessCodeLifespan());
         code.setState(state);
         code.setRedirectUri(redirect);
-        AccessCodeEntry entry = new AccessCodeEntry(realm, code);
+        AccessCodeEntry entry = new AccessCodeEntry(keycloakSession, realm, code);
         return entry;
 
     }
@@ -118,7 +118,7 @@ public class TokenManager {
 
         audit.user(refreshToken.getSubject()).session(refreshToken.getSessionState()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId());
 
-        UserModel user = realm.getUserById(refreshToken.getSubject());
+        UserModel user = session.users().getUserById(refreshToken.getSubject(), realm);
         if (user == null) {
             throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Invalid refresh token", "Unknown user");
         }
diff --git a/services/src/main/java/org/keycloak/services/managers/UserManager.java b/services/src/main/java/org/keycloak/services/managers/UserManager.java
old mode 100644
new mode 100755
index 4a18d30..eb7c98f
--- a/services/src/main/java/org/keycloak/services/managers/UserManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/UserManager.java
@@ -17,7 +17,7 @@ public class UserManager {
     }
 
     public boolean removeUser(RealmModel realm, UserModel user) {
-        if (realm.removeUser(user.getUsername())) {
+        if (session.users().removeUser(realm, user.getUsername())) {
             UserSessionProvider sessions = session.sessions();
             if (sessions != null) {
                 sessions.onUserRemoved(realm, user);
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 19c7c58..57d229a 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -46,6 +46,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.TimeBasedOTP;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
@@ -53,7 +54,6 @@ import org.keycloak.services.ForbiddenException;
 import org.keycloak.services.managers.AppAuthManager;
 import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.OAuthRedirect;
@@ -516,12 +516,12 @@ public class AccountService {
                     return account.setError(Messages.SOCIAL_REDIRECT_ERROR).createResponse(AccountPages.SOCIAL);
                 }
             case REMOVE:
-                SocialLinkModel link = realm.getSocialLink(user, providerId);
+                SocialLinkModel link = session.users().getSocialLink(user, providerId, realm);
                 if (link != null) {
 
                     // Removing last social provider is not possible if you don't have other possibility to authenticate
-                    if (realm.getSocialLinks(user).size() > 1 || user.getAuthenticationLink() != null) {
-                        realm.removeSocialLink(user, providerId);
+                    if (session.users().getSocialLinks(user, realm).size() > 1 || user.getAuthenticationLink() != null) {
+                        session.users().removeSocialLink(realm, user, providerId);
 
                         logger.debug("Social provider " + providerId + " removed successfully from user " + user.getUsername());
 
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 e9c5a10..327c36e 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
@@ -224,7 +224,7 @@ public class AdminConsole {
     }
 
     private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
-        List<RealmModel> realms = session.model().getRealms();
+        List<RealmModel> realms = session.realms().getRealms();
         for (RealmModel realm : realms) {
             ApplicationModel realmAdminApp = realm.getMasterAdminApp();
             Set<RoleModel> roles = realmAdminApp.getRoles();
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 5308112..e438faa 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
@@ -11,6 +11,7 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.adapters.action.SessionStats;
 import org.keycloak.representations.adapters.action.UserStats;
@@ -18,7 +19,6 @@ import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 import org.keycloak.services.managers.ApplicationManager;
-import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.resources.KeycloakApplication;
@@ -302,7 +302,7 @@ public class ApplicationResource {
             if (users) stats.setUsers(new HashMap<String, UserStats>());
             return stats;
         }
-        SessionStats stats = new ResourceAdminManager().getSessionStats(uriInfo.getRequestUri(), realm, application, users);
+        SessionStats stats = new ResourceAdminManager().getSessionStats(uriInfo.getRequestUri(), session, realm, application, users);
         if (stats == null) {
             logger.info("app returned null stats");
         } else {
@@ -372,7 +372,7 @@ public class ApplicationResource {
     @POST
     public void logout(final @PathParam("username") String username) {
         auth.requireManage();
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
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 c303847..68926ec 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
@@ -11,8 +11,6 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.services.managers.ApplicationManager;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
index 0353bad..1b8c0d9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
@@ -1,9 +1,9 @@
 package org.keycloak.services.resources.admin;
 
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ClaimRepresentation;
-import org.keycloak.models.utils.ModelToRepresentation;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index e7722d2..84f1b88 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -8,10 +8,10 @@ import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
-import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index dd081f0..3bb4144 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -11,7 +11,6 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
-import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
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 79a0bcd..81e5db1 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
@@ -13,12 +13,12 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.adapters.action.SessionStats;
 import org.keycloak.representations.idm.RealmAuditRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.LDAPConnectionTestManager;
-import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.TokenManager;
@@ -261,7 +261,7 @@ public class RealmAdminResource {
         Map<String, SessionStats> stats = new HashMap<String, SessionStats>();
         for (ApplicationModel applicationModel : realm.getApplications()) {
             if (applicationModel.getManagementUrl() == null) continue;
-            SessionStats appStats = new ResourceAdminManager().getSessionStats(uriInfo.getRequestUri(), realm, applicationModel, false);
+            SessionStats appStats = new ResourceAdminManager().getSessionStats(uriInfo.getRequestUri(), this.session, realm, applicationModel, false);
             stats.put(applicationModel.getName(), appStats);
         }
         return stats;
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 89d9ef3..e2ef922 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
@@ -3,9 +3,6 @@ package org.keycloak.services.resources.admin;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.services.ForbiddenException;
-import org.keycloak.services.managers.Auth;
-
-import javax.ws.rs.WebApplicationException;
 
 
 /**
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 de7f157..ab703ac 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
@@ -12,9 +12,9 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.ForbiddenException;
-import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
 import org.keycloak.services.resources.KeycloakApplication;
@@ -85,7 +85,7 @@ public class RealmsAdminResource {
         RealmManager realmManager = new RealmManager(session);
         List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
         if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
-            List<RealmModel> realms = session.model().getRealms();
+            List<RealmModel> realms = session.realms().getRealms();
             for (RealmModel realm : realms) {
                 addRealmRep(reps, realm, realm.getMasterAdminApp());
             }
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 cf43306..a4b6f58 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
@@ -6,8 +6,8 @@ import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
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 18599de..52bfae9 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
@@ -4,8 +4,8 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
 
 import java.util.Collections;
 import java.util.HashSet;
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 96a225b..9da9085 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
@@ -7,10 +7,10 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
 import org.keycloak.representations.idm.MappingsRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.models.utils.ModelToRepresentation;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
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 32ccf7f..ac35189 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
@@ -17,6 +17,7 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.adapters.action.UserStats;
 import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
@@ -27,7 +28,6 @@ import org.keycloak.representations.idm.SocialLinkRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.TokenManager;
@@ -100,7 +100,7 @@ public class UsersResource {
         auth.requireManage();
 
         try {
-            UserModel user = realm.getUser(username);
+            UserModel user = session.users().getUserByUsername(username, realm);
             if (user == null) {
                 throw new NotFoundException("User not found");
             }
@@ -125,7 +125,7 @@ public class UsersResource {
         auth.requireManage();
 
         try {
-            UserModel user = realm.addUser(rep.getUsername());
+            UserModel user = session.users().addUser(realm, rep.getUsername());
             updateUserFromRep(user, rep);
 
             return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getUsername()).build()).build();
@@ -175,7 +175,7 @@ public class UsersResource {
     public UserRepresentation getUser(final @PathParam("username") String username) {
         auth.requireView();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -198,7 +198,7 @@ public class UsersResource {
     public Map<String, UserStats> getSessionStats(final @PathParam("username") String username) {
         logger.info("session-stats");
         auth.requireView();
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -225,7 +225,7 @@ public class UsersResource {
     public List<UserSessionRepresentation> getSessions(final @PathParam("username") String username) {
         logger.info("sessions");
         auth.requireView();
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -250,11 +250,11 @@ public class UsersResource {
     @Produces(MediaType.APPLICATION_JSON)
     public List<SocialLinkRepresentation> getSocialLinks(final @PathParam("username") String username) {
         auth.requireView();
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-        Set<SocialLinkModel> socialLinks = realm.getSocialLinks(user);
+        Set<SocialLinkModel> socialLinks = session.users().getSocialLinks(user, realm);
         List<SocialLinkRepresentation> result = new ArrayList<SocialLinkRepresentation>();
         for (SocialLinkModel socialLink : socialLinks) {
             SocialLinkRepresentation rep = ModelToRepresentation.toRepresentation(socialLink);
@@ -273,7 +273,7 @@ public class UsersResource {
     @POST
     public void logout(final @PathParam("username") String username) {
         auth.requireManage();
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -292,7 +292,7 @@ public class UsersResource {
     public void deleteUser(final @PathParam("username") String username) {
         auth.requireManage();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -339,12 +339,12 @@ public class UsersResource {
             if (username != null) {
                 attributes.put(UserModel.LOGIN_NAME, username);
             }
-            userModels = realm.searchForUserByAttributes(attributes);
+            userModels = session.users().searchForUserByAttributes(attributes, realm);
             for (UserModel user : userModels) {
                 results.add(ModelToRepresentation.toRepresentation(user));
             }
         } else {
-            userModels = realm.getUsers();
+            userModels = session.users().getUsers(realm);
         }
 
         for (UserModel user : userModels) {
@@ -366,7 +366,7 @@ public class UsersResource {
     public MappingsRepresentation getRoleMappings(@PathParam("username") String username) {
         auth.requireView();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -417,7 +417,7 @@ public class UsersResource {
     public List<RoleRepresentation> getRealmRoleMappings(@PathParam("username") String username) {
         auth.requireView();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -443,7 +443,7 @@ public class UsersResource {
     public List<RoleRepresentation> getCompositeRealmRoleMappings(@PathParam("username") String username) {
         auth.requireView();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -471,7 +471,7 @@ public class UsersResource {
     public List<RoleRepresentation> getAvailableRealmRoleMappings(@PathParam("username") String username) {
         auth.requireView();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -493,7 +493,7 @@ public class UsersResource {
         auth.requireManage();
 
         logger.debugv("** addRealmRoleMappings: {0}", roles);
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -522,7 +522,7 @@ public class UsersResource {
         auth.requireManage();
 
         logger.debug("deleteRealmRoleMappings");
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -560,7 +560,7 @@ public class UsersResource {
 
         logger.debug("getApplicationRoleMappings");
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -596,7 +596,7 @@ public class UsersResource {
 
         logger.debug("getCompositeApplicationRoleMappings");
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -632,7 +632,7 @@ public class UsersResource {
 
         logger.debug("getApplicationRoleMappings");
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -674,7 +674,7 @@ public class UsersResource {
         auth.requireManage();
 
         logger.debug("addApplicationRoleMapping");
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -708,7 +708,7 @@ public class UsersResource {
     public void deleteApplicationRoleMapping(@PathParam("username") String username, @PathParam("app") String appName, List<RoleRepresentation> roles) {
         auth.requireManage();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -753,7 +753,7 @@ public class UsersResource {
     public void resetPassword(@PathParam("username") String username, CredentialRepresentation pass) {
         auth.requireManage();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -777,7 +777,7 @@ public class UsersResource {
     public void removeTotp(@PathParam("username") String username) {
         auth.requireManage();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -797,7 +797,7 @@ public class UsersResource {
     public Response resetPasswordEmail(@PathParam("username") String username) {
         auth.requireManage();
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null) {
             throw new NotFoundException("User not found");
         }
@@ -819,7 +819,7 @@ public class UsersResource {
         Set<UserModel.RequiredAction> requiredActions = new HashSet<UserModel.RequiredAction>(user.getRequiredActions());
         requiredActions.add(UserModel.RequiredAction.UPDATE_PASSWORD);
 
-        AccessCodeEntry accessCode = tokenManager.createAccessCode(scope, state, redirect, realm, client, user, null);
+        AccessCodeEntry accessCode = tokenManager.createAccessCode(scope, state, redirect, session, realm, client, user, null);
         accessCode.setRequiredActions(requiredActions);
         accessCode.setUsernameUsed(username);
         accessCode.resetExpiration();
diff --git a/services/src/main/java/org/keycloak/services/resources/Cors.java b/services/src/main/java/org/keycloak/services/resources/Cors.java
index c77b001..7689ea0 100755
--- a/services/src/main/java/org/keycloak/services/resources/Cors.java
+++ b/services/src/main/java/org/keycloak/services/resources/Cors.java
@@ -1,13 +1,5 @@
 package org.keycloak.services.resources;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.HttpResponse;
@@ -15,6 +7,13 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.util.CollectionUtil;
 
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
index 5027f19..c843fbe 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
@@ -130,7 +130,7 @@ public class OAuthFlows {
         isEmailVerificationRequired(user);
 
         boolean isResource = client instanceof ApplicationModel;
-        AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, realm, client, user, session);
+        AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, this.session, realm, client, user, session);
         accessCode.setRememberMe(rememberMe);
         accessCode.setAuthMethod(authMethod);
         accessCode.setUsernameUsed(username);
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java
index 37c0922..5091bc3 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java
@@ -3,18 +3,15 @@ package org.keycloak.services.resources.flows;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.SocialResource;
 import org.keycloak.services.util.CookieHelper;
 import org.keycloak.social.AuthRequest;
-import org.keycloak.social.UriBuilder;
 import org.keycloak.social.SocialProvider;
 import org.keycloak.social.SocialProviderConfig;
 import org.keycloak.social.SocialProviderException;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-import java.net.URI;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index fa311fa..539674b 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -22,10 +22,10 @@
 package org.keycloak.services.resources.flows;
 
 import org.keycloak.services.resources.AccountService;
-import org.keycloak.services.resources.ThemeResource;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.RequiredActionsService;
 import org.keycloak.services.resources.SocialResource;
+import org.keycloak.services.resources.ThemeResource;
 import org.keycloak.services.resources.TokenService;
 
 import javax.ws.rs.core.UriBuilder;
diff --git a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
index 097b25a..565303c 100755
--- a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
@@ -7,7 +7,6 @@ import org.keycloak.representations.idm.PublishedRealmRepresentation;
 import org.keycloak.services.resources.admin.AdminRoot;
 
 import javax.ws.rs.GET;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.UriInfo;
diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
index bfee8da..85eabf5 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -28,6 +28,8 @@ import org.keycloak.audit.Audit;
 import org.keycloak.audit.Details;
 import org.keycloak.audit.Errors;
 import org.keycloak.audit.EventType;
+import org.keycloak.authentication.AuthenticationProviderException;
+import org.keycloak.authentication.AuthenticationProviderManager;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
 import org.keycloak.login.LoginFormsProvider;
@@ -48,8 +50,6 @@ import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.Urls;
 import org.keycloak.services.validation.Validation;
-import org.keycloak.authentication.AuthenticationProviderException;
-import org.keycloak.authentication.AuthenticationProviderManager;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -226,7 +226,7 @@ public class RequiredActionsService {
 
         // Password reset through email won't have an associated session
         if (accessCode.getSessionState() == null) {
-            UserSessionModel userSession = session.sessions().createUserSession(realm, realm.getUserById(accessCode.getUser().getId()), clientConnection.getRemoteAddr());
+            UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserById(accessCode.getUser().getId(), realm), clientConnection.getRemoteAddr());
             accessCode.getToken().setSessionState(userSession.getId());
             audit.session(userSession);
         }
@@ -239,7 +239,7 @@ public class RequiredActionsService {
     @GET
     public Response emailVerification() {
         if (uriInfo.getQueryParameters().containsKey("key")) {
-            AccessCodeEntry accessCode = tokenManager.parseCode(uriInfo.getQueryParameters().getFirst("key"), realm);
+            AccessCodeEntry accessCode = tokenManager.parseCode(uriInfo.getQueryParameters().getFirst("key"), session, realm);
             if (accessCode == null || accessCode.isExpired()
                     || !accessCode.hasRequiredAction(RequiredAction.VERIFY_EMAIL)) {
                 return unauthorized();
@@ -275,7 +275,7 @@ public class RequiredActionsService {
     @GET
     public Response passwordReset() {
         if (uriInfo.getQueryParameters().containsKey("key")) {
-            AccessCodeEntry accessCode = tokenManager.parseCode(uriInfo.getQueryParameters().getFirst("key"), realm);
+            AccessCodeEntry accessCode = tokenManager.parseCode(uriInfo.getQueryParameters().getFirst("key"), session, realm);
             accessCode.setAuthMethod("form");
             if (accessCode == null || accessCode.isExpired()
                     || !accessCode.hasRequiredAction(RequiredAction.UPDATE_PASSWORD)) {
@@ -317,9 +317,9 @@ public class RequiredActionsService {
                 .detail(Details.AUTH_METHOD, "form")
                 .detail(Details.USERNAME, username);
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user == null && username.contains("@")) {
-            user = realm.getUserByEmail(username);
+            user = session.users().getUserByEmail(username, realm);
         }
 
         if (user == null) {
@@ -329,7 +329,7 @@ public class RequiredActionsService {
             Set<RequiredAction> requiredActions = new HashSet<RequiredAction>(user.getRequiredActions());
             requiredActions.add(RequiredAction.UPDATE_PASSWORD);
 
-            AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, realm, client, user, null);
+            AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, session, realm, client, user, null);
             accessCode.setRequiredActions(requiredActions);
             accessCode.setAuthMethod("form");
             accessCode.setUsernameUsed(username);
@@ -360,7 +360,7 @@ public class RequiredActionsService {
             return null;
         }
 
-        AccessCodeEntry accessCodeEntry = tokenManager.parseCode(code, realm);
+        AccessCodeEntry accessCodeEntry = tokenManager.parseCode(code, session, realm);
         if (accessCodeEntry == null) {
             logger.debug("getAccessCodeEntry access code entry null");
             return null;
@@ -381,7 +381,7 @@ public class RequiredActionsService {
     }
 
     private UserModel getUser(AccessCodeEntry accessCode) {
-        return realm.getUser(accessCode.getUser().getUsername());
+        return session.users().getUserByUsername(accessCode.getUser().getUsername(), realm);
     }
 
     private Response redirectOauth(UserModel user, AccessCodeEntry accessCode) {
diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
index 55dae8f..2411706 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -182,12 +182,12 @@ public class SocialResource {
         audit.detail(Details.USERNAME, socialUser.getId() + "@" + provider.getId());
 
         SocialLinkModel socialLink = new SocialLinkModel(provider.getId(), socialUser.getId(), socialUser.getUsername());
-        UserModel user = realm.getUserBySocialLink(socialLink);
+        UserModel user = session.users().getUserBySocialLink(socialLink, realm);
 
         // Check if user is already authenticated (this means linking social into existing user account)
         String userId = initialRequest.getUser();
         if (userId != null) {
-            UserModel authenticatedUser = realm.getUserById(userId);
+            UserModel authenticatedUser = session.users().getUserById(userId, realm);
 
             audit.event(EventType.SOCIAL_LINK).user(userId);
 
@@ -211,7 +211,7 @@ public class SocialResource {
                 return oauth.forwardToSecurityFailure("Unknown redirectUri");
             }
 
-            realm.addSocialLink(authenticatedUser, socialLink);
+            session.users().addSocialLink(realm, authenticatedUser, socialLink);
             logger.debug("Social provider " + provider.getId() + " linked with user " + authenticatedUser.getUsername());
 
             audit.success();
@@ -225,7 +225,7 @@ public class SocialResource {
                 return oauth.forwardToSecurityFailure("Registration not allowed");
             }
 
-            user = realm.addUser(KeycloakModelUtils.generateId());
+            user = session.users().addUser(realm, KeycloakModelUtils.generateId());
             user.setEnabled(true);
             user.setFirstName(socialUser.getFirstName());
             user.setLastName(socialUser.getLastName());
@@ -235,7 +235,7 @@ public class SocialResource {
                 user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
             }
 
-            realm.addSocialLink(user, socialLink);
+            session.users().addSocialLink(realm, user, socialLink);
 
             audit.clone().user(user).event(EventType.REGISTER)
                     .detail(Details.REGISTER_METHOD, "social@" + provider.getId())
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 2a37360..dc7c937 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -21,7 +21,6 @@ import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.UserCredentialModel;
@@ -232,7 +231,7 @@ public class TokenService {
         }
         audit.detail(Details.USERNAME, username);
 
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         if (user != null) audit.user(user);
 
         ClientModel client = authorizeClient(authorizationHeader, form, audit);
@@ -418,7 +417,7 @@ public class TokenService {
             authManager.expireRememberMeCookie(realm, uriInfo);
         }
 
-        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
+        UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
         if (user != null) {
             audit.user(user);
         }
@@ -534,12 +533,12 @@ public class TokenService {
         AuthenticationProviderManager authenticationProviderManager = AuthenticationProviderManager.getManager(realm, session);
 
         // Validate that user with this username doesn't exist in realm or any authentication provider
-        if (realm.getUser(username) != null || authenticationProviderManager.getUser(username) != null) {
+        if (session.users().getUserByUsername(username, realm) != null || authenticationProviderManager.getUser(username) != null) {
             audit.error(Errors.USERNAME_IN_USE);
             return Flows.forms(session, realm, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration();
         }
 
-        UserModel user = realm.addUser(username);
+        UserModel user = session.users().addUser(realm, username);
         user.setEnabled(true);
         user.setFirstName(formData.getFirst("firstName"));
         user.setLastName(formData.getFirst("lastName"));
@@ -624,7 +623,7 @@ public class TokenService {
 
 
 
-        AccessCodeEntry accessCode = tokenManager.parseCode(code, realm);
+        AccessCodeEntry accessCode = tokenManager.parseCode(code, session, realm);
         if (accessCode == null) {
             Map<String, String> res = new HashMap<String, String>();
             res.put(OAuth2Constants.ERROR, "invalid_grant");
@@ -665,7 +664,7 @@ public class TokenService {
                     .build();
         }
 
-        UserModel user = realm.getUserById(accessCode.getUser().getId());
+        UserModel user = session.users().getUserById(accessCode.getUser().getId(), realm);
         if (user == null) {
             Map<String, String> res = new HashMap<String, String>();
             res.put(OAuth2Constants.ERROR, "invalid_grant");
@@ -969,7 +968,7 @@ public class TokenService {
 
         String code = formData.getFirst(OAuth2Constants.CODE);
 
-        AccessCodeEntry accessCodeEntry = tokenManager.parseCode(code, realm);
+        AccessCodeEntry accessCodeEntry = tokenManager.parseCode(code, session, realm);
         if (accessCodeEntry == null) {
             audit.error(Errors.INVALID_CODE);
             return oauth.forwardToSecurityFailure("Unknown access code.");
diff --git a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java
old mode 100644
new mode 100755
index 425342b..193589c
--- a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java
+++ b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java
@@ -13,7 +13,7 @@ public class ClearExpiredAuditEvents implements ScheduledTask {
     public void run(KeycloakSession session) {
         AuditProvider audit = session.getProvider(AuditProvider.class);
         if (audit != null) {
-            for (RealmModel realm : session.model().getRealms()) {
+            for (RealmModel realm : session.realms().getRealms()) {
                 if (realm.isAuditEnabled() && realm.getAuditExpiration() > 0) {
                     long olderThan = System.currentTimeMillis() - realm.getAuditExpiration() * 1000;
                     audit.clear(realm.getId(), olderThan);
diff --git a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredUserSessions.java b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredUserSessions.java
index e5f1d1c..96c8bad 100755
--- a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredUserSessions.java
+++ b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredUserSessions.java
@@ -12,7 +12,7 @@ public class ClearExpiredUserSessions implements ScheduledTask {
     @Override
     public void run(KeycloakSession session) {
         UserSessionProvider sessions = session.sessions();
-        for (RealmModel realm : session.model().getRealms()) {
+        for (RealmModel realm : session.realms().getRealms()) {
             sessions.removeExpiredUserSessions(realm);
         }
     }
diff --git a/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java b/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java
old mode 100644
new mode 100755
index 0eb1cef..785cc81
--- a/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java
+++ b/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java
@@ -4,8 +4,6 @@ import org.codehaus.jackson.JsonNode;
 import org.keycloak.Config;
 import org.keycloak.util.StringPropertyReplacer;
 
-import java.util.ArrayList;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index 45bb7cc..4e22fc5 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -246,7 +246,7 @@ public class KeycloakServer {
             RealmManager manager = new RealmManager(session);
 
             RealmModel adminRealm = manager.getKeycloakAdminstrationRealm();
-            UserModel admin = adminRealm.getUser("admin");
+            UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             admin.removeRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
 
             session.getTransaction().commit();
diff --git a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
index a739087..1c8ff16 100755
--- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
@@ -7,16 +7,24 @@
         "provider": "${keycloak.audit.provider,keycloak.model.provider:jpa}"
     },
 
-    "model": {
-        "provider": "${keycloak.model.provider:jpa}"
+    "realm": {
+        "provider": "${keycloak.realm.provider:jpa}"
+    },
+
+    "user": {
+        "provider": "${keycloak.user.provider:jpa}"
     },
 
     "userSessions": {
         "provider" : "${keycloak.userSessions.provider:mem}"
     },
 
-    "modelCache": {
-        "provider": "${keycloak.model.cache.provider:simple}"
+    "realmCache": {
+        "provider": "${keycloak.realm.cache.provider:mem}"
+    },
+
+    "userCache": {
+        "provider": "${keycloak.user.cache.provider:mem}"
     },
 
     "timer": {
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 770ef84..7c3c3da 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
@@ -76,11 +76,11 @@ public class AccountTest {
     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            UserModel user = appRealm.getUser("test-user@localhost");
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
 
             ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
 
-            UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
+            UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
             user2.setEnabled(true);
             for (String r : accountApp.getDefaultRoles()) {
                 user2.deleteRoleMapping(accountApp.getRole(r));
@@ -148,7 +148,7 @@ public class AccountTest {
         keycloakRule.update(new KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
-                UserModel user = appRealm.getUser("test-user@localhost");
+                UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
 
                 UserCredentialModel cred = new UserCredentialModel();
                 cred.setType(CredentialRepresentation.PASSWORD);
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 ad78f4a..18ca838 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
@@ -48,7 +48,7 @@ public class ProfileTest {
     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            UserModel user = appRealm.getUser("test-user@localhost");
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
             user.setFirstName("First");
             user.setLastName("Last");
             user.setAttribute("key1", "value1");
@@ -56,7 +56,7 @@ public class ProfileTest {
 
             ApplicationModel accountApp = appRealm.getApplicationByName(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_APP);
 
-            UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
+            UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
             user2.setEnabled(true);
             for (String r : accountApp.getDefaultRoles()) {
                 user2.deleteRoleMapping(accountApp.getRole(r));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
index 476cdcc..9ca52a3 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
@@ -94,7 +94,7 @@ public class RequiredActionEmailVerificationTest {
             public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
                 appRealm.setVerifyEmail(true);
 
-                UserModel user = appRealm.getUser("test-user@localhost");
+                UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
                 user.setEmailVerified(false);
             }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
index 49f97ed..4f9f740 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
@@ -54,7 +54,7 @@ public class RequiredActionMultipleActionsTest {
 
         @Override
         public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
-            UserModel user = appRealm.getUser("test-user@localhost");
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
             user.addRequiredAction(RequiredAction.UPDATE_PROFILE);
             user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
         }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java
index d4cc32e..e357843 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java
@@ -56,7 +56,7 @@ public class RequiredActionResetPasswordTest {
         public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
             appRealm.setResetPasswordAllowed(true);
 
-            UserModel user = appRealm.getUser("test-user@localhost");
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
             user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
         }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
index 056e6fd..a5a87c1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
@@ -72,7 +72,7 @@ public class RequiredActionUpdateProfileTest {
         keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
             @Override
             public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
-                UserModel user = appRealm.getUser("test-user@localhost");
+                UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
                 user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
             }
         });
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
index f403858..f43d735 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
@@ -99,7 +99,7 @@ public class AdapterTest {
             RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
-            UserModel admin = adminRealm.getUser("admin");
+            UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null);
             AccessToken token = tm.createClientAccessToken(null, adminRealm, adminConsole, admin, userSession);
             return tm.encodeToken(adminRealm, token);
@@ -231,7 +231,7 @@ public class AdapterTest {
         Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.model().getRealmByName("demo");
+        RealmModel realm = session.realms().getRealmByName("demo");
         int originalIdle = realm.getSsoSessionIdleTimeout();
         realm.setSsoSessionIdleTimeout(1);
         session.getTransaction().commit();
@@ -245,7 +245,7 @@ public class AdapterTest {
         Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("demo");
+        realm = session.realms().getRealmByName("demo");
         realm.setSsoSessionIdleTimeout(originalIdle);
         session.getTransaction().commit();
         session.close();
@@ -265,7 +265,7 @@ public class AdapterTest {
         Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.model().getRealmByName("demo");
+        RealmModel realm = session.realms().getRealmByName("demo");
         int originalIdle = realm.getSsoSessionIdleTimeout();
         realm.setSsoSessionIdleTimeout(1);
         session.getTransaction().commit();
@@ -274,7 +274,7 @@ public class AdapterTest {
         Thread.sleep(2000);
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("demo");
+        realm = session.realms().getRealmByName("demo");
         session.sessions().removeExpiredUserSessions(realm);
         session.getTransaction().commit();
         session.close();
@@ -284,7 +284,7 @@ public class AdapterTest {
         Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("demo");
+        realm = session.realms().getRealmByName("demo");
         realm.setSsoSessionIdleTimeout(originalIdle);
         session.getTransaction().commit();
         session.close();
@@ -304,7 +304,7 @@ public class AdapterTest {
         Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.model().getRealmByName("demo");
+        RealmModel realm = session.realms().getRealmByName("demo");
         int original = realm.getSsoSessionMaxLifespan();
         realm.setSsoSessionMaxLifespan(1);
         session.getTransaction().commit();
@@ -318,7 +318,7 @@ public class AdapterTest {
         Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("demo");
+        realm = session.realms().getRealmByName("demo");
         realm.setSsoSessionMaxLifespan(original);
         session.getTransaction().commit();
         session.close();
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 ae4d367..f3da0af 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
@@ -86,7 +86,7 @@ public class RelativeUriAdapterTest {
             deployApplication("product-portal", "/product-portal", ProductServlet.class, url.getPath(), "user");
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
-            UserModel admin = adminRealm.getUser("admin");
+            UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null);
             AccessToken token = tm.createClientAccessToken(null, adminRealm, adminConsole, admin, userSession);
             adminToken = tm.encodeToken(adminRealm, token);
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 afd1c26..416cc3d 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
@@ -78,7 +78,7 @@ public class AdminAPITest {
             RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
-            UserModel admin = adminRealm.getUser("admin");
+            UserModel admin = session.users().getUserByUsername("admin", adminRealm);
             UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null);
             AccessToken token = tm.createClientAccessToken(null, adminRealm, adminConsole, admin, userSession);
             return tm.encodeToken(adminRealm, token);
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 f33a43e..af4967d 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
@@ -77,12 +77,12 @@ public class CompositeRoleTest {
             final RoleModel realmComposite1 = realm.addRole("REALM_COMPOSITE_1");
             realmComposite1.addCompositeRole(realmRole1);
 
-            final UserModel realmComposite1User = realm.addUser("REALM_COMPOSITE_1_USER");
+            final UserModel realmComposite1User = session.users().addUser(realm, "REALM_COMPOSITE_1_USER");
             realmComposite1User.setEnabled(true);
             realmComposite1User.updateCredential(UserCredentialModel.password("password"));
             realmComposite1User.grantRole(realmComposite1);
 
-            final UserModel realmRole1User = realm.addUser("REALM_ROLE_1_USER");
+            final UserModel realmRole1User = session.users().addUser(realm, "REALM_ROLE_1_USER");
             realmRole1User.setEnabled(true);
             realmRole1User.updateCredential(UserCredentialModel.password("password"));
             realmRole1User.grantRole(realmRole1);
@@ -116,12 +116,12 @@ public class CompositeRoleTest {
             final RoleModel realmAppCompositeRole = realm.addRole("REALM_APP_COMPOSITE_ROLE");
             realmAppCompositeRole.addCompositeRole(appRole1);
 
-            final UserModel realmAppCompositeUser = realm.addUser("REALM_APP_COMPOSITE_USER");
+            final UserModel realmAppCompositeUser = session.users().addUser(realm, "REALM_APP_COMPOSITE_USER");
             realmAppCompositeUser.setEnabled(true);
             realmAppCompositeUser.updateCredential(UserCredentialModel.password("password"));
             realmAppCompositeUser.grantRole(realmAppCompositeRole);
 
-            final UserModel realmAppRoleUser = realm.addUser("REALM_APP_ROLE_USER");
+            final UserModel realmAppRoleUser = session.users().addUser(realm, "REALM_APP_ROLE_USER");
             realmAppRoleUser.setEnabled(true);
             realmAppRoleUser.updateCredential(UserCredentialModel.password("password"));
             realmAppRoleUser.grantRole(appRole2);
@@ -139,7 +139,7 @@ public class CompositeRoleTest {
             appCompositeRole.addCompositeRole(realmRole3);
             appCompositeRole.addCompositeRole(appRole1);
 
-            final UserModel appCompositeUser = realm.addUser("APP_COMPOSITE_USER");
+            final UserModel appCompositeUser = session.users().addUser(realm, "APP_COMPOSITE_USER");
             appCompositeUser.setEnabled(true);
             appCompositeUser.updateCredential(UserCredentialModel.password("password"));
             appCompositeUser.grantRole(realmAppCompositeRole);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
old mode 100644
new mode 100755
index a3e9df9..339bb17
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
@@ -1,33 +1,10 @@
 package org.keycloak.testsuite.exportimport;
 
-import java.io.File;
-import java.util.Properties;
-
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.ExternalResource;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TestRule;
-import org.keycloak.Config;
-import org.keycloak.exportimport.ExportImportConfig;
-import org.keycloak.exportimport.dir.DirExportProvider;
-import org.keycloak.exportimport.dir.DirExportProviderFactory;
-import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
-import org.keycloak.exportimport.zip.ZipExportProviderFactory;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.testsuite.rule.KeycloakRule;
-
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
 public class ExportImportTest {
+    /*
 
     // We want data to be persisted among server restarts
     private static ExternalResource hibernateSetupRule = new ExternalResource() {
@@ -88,13 +65,63 @@ public class ExportImportTest {
 
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            addUser(appRealm, "user1", "password");
-            addUser(appRealm, "user2", "password");
-            addUser(appRealm, "user3", "password");
-            addUser(adminstrationRealm, "admin2", "admin2");
+            addUser(manager.getSession().users(), appRealm, "user1", "password");
+            addUser(manager.getSession().users(), appRealm, "user2", "password");
+            addUser(manager.getSession().users(), appRealm, "user3", "password");
+            addUser(manager.getSession().users(), adminstrationRealm, "admin2", "admin2");
         }
 
-    });
+
+
+    }) {
+        @Override
+        protected void after() {
+            {
+                KeycloakSession session = server.getSessionFactory().create();
+                session.getTransaction().begin();
+
+                try {
+                    RealmManager manager = new RealmManager(session);
+
+                    RealmModel adminstrationRealm = manager.getRealm(Config.getAdminRealm());
+                    RealmModel appRealm = manager.getRealm("test");
+                    boolean removed = session.users().removeUser(appRealm, "user1");
+                    removed = session.users().removeUser(appRealm, "user2");
+                    removed = session.users().removeUser(appRealm, "user3");
+                    removed = session.users().removeUser(adminstrationRealm, "admin2");
+
+                    session.getTransaction().commit();
+                } finally {
+                    session.close();
+                }
+            }
+            {
+                KeycloakSession session = server.getSessionFactory().create();
+                session.getTransaction().begin();
+
+                try {
+                    RealmManager manager = new RealmManager(session);
+
+                    RealmModel adminstrationRealm = manager.getRealm(Config.getAdminRealm());
+                    RealmModel appRealm = manager.getRealm("test");
+                    UserModel user1 = session.users().getUserByUsername("user1", appRealm);
+                    UserModel user2= session.users().getUserByUsername("user2", appRealm);
+                    UserModel user3 = session.users().getUserByUsername("user3", appRealm);
+                    UserModel admin2 = session.users().getUserByUsername("admin2", adminstrationRealm);
+                    Assert.assertNull(user1);
+                    Assert.assertNull(user2);
+                    Assert.assertNull(user3);
+                    Assert.assertNull(admin2);
+
+                    session.getTransaction().commit();
+                } finally {
+                    session.close();
+                }
+            }
+
+            super.after();
+        }
+    };
 
     @ClassRule
     public static TestRule chain = RuleChain
@@ -183,17 +210,17 @@ public class ExportImportTest {
         KeycloakSession session = keycloakRule.startSession();
         try {
             ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
             new RealmManager(session).removeRealm(model.getRealmByName("test"));
             Assert.assertEquals(1, model.getRealms().size());
 
             RealmModel master = model.getRealmByName(Config.getAdminRealm());
-            master.removeUser("admin2");
-
-            assertNotAuthenticated(model, Config.getAdminRealm(), "admin2", "admin2");
-            assertNotAuthenticated(model, "test", "test-user@localhost", "password");
-            assertNotAuthenticated(model, "test", "user1", "password");
-            assertNotAuthenticated(model, "test", "user2", "password");
-            assertNotAuthenticated(model, "test", "user3", "password");
+            session.users().removeUser(master, "admin2");
+            assertNotAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertNotAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user1", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user2", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user3", "password");
         } finally {
             keycloakRule.stopSession(session, true);
         }
@@ -208,13 +235,14 @@ public class ExportImportTest {
         session = keycloakRule.startSession();
         try {
             ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
             Assert.assertEquals(2, model.getRealms().size());
 
-            assertAuthenticated(model, Config.getAdminRealm(), "admin2", "admin2");
-            assertAuthenticated(model, "test", "test-user@localhost", "password");
-            assertAuthenticated(model, "test", "user1", "password");
-            assertAuthenticated(model, "test", "user2", "password");
-            assertAuthenticated(model, "test", "user3", "password");
+            assertAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertAuthenticated(userProvider, model, "test", "user1", "password");
+            assertAuthenticated(userProvider, model, "test", "user2", "password");
+            assertAuthenticated(userProvider, model, "test", "user3", "password");
 
         } finally {
             keycloakRule.stopSession(session, true);
@@ -232,17 +260,18 @@ public class ExportImportTest {
         KeycloakSession session = keycloakRule.startSession();
         try {
             ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
             new RealmManager(session).removeRealm(model.getRealmByName("test"));
             Assert.assertEquals(1, model.getRealms().size());
 
             RealmModel master = model.getRealmByName(Config.getAdminRealm());
-            master.removeUser("admin2");
+            session.users().removeUser(master, "admin2");
 
-            assertNotAuthenticated(model, Config.getAdminRealm(), "admin2", "admin2");
-            assertNotAuthenticated(model, "test", "test-user@localhost", "password");
-            assertNotAuthenticated(model, "test", "user1", "password");
-            assertNotAuthenticated(model, "test", "user2", "password");
-            assertNotAuthenticated(model, "test", "user3", "password");
+            assertNotAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertNotAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user1", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user2", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user3", "password");
         } finally {
             keycloakRule.stopSession(session, true);
         }
@@ -257,27 +286,28 @@ public class ExportImportTest {
         session = keycloakRule.startSession();
         try {
             ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
             Assert.assertEquals(2, model.getRealms().size());
 
-            assertNotAuthenticated(model, Config.getAdminRealm(), "admin2", "admin2");
-            assertAuthenticated(model, "test", "test-user@localhost", "password");
-            assertAuthenticated(model, "test", "user1", "password");
-            assertAuthenticated(model, "test", "user2", "password");
-            assertAuthenticated(model, "test", "user3", "password");
+            assertNotAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertAuthenticated(userProvider, model, "test", "user1", "password");
+            assertAuthenticated(userProvider, model, "test", "user2", "password");
+            assertAuthenticated(userProvider, model, "test", "user3", "password");
 
-            addUser(model.getRealmByName(Config.getAdminRealm()), "admin2", "admin2");
+            addUser(userProvider, model.getRealmByName(Config.getAdminRealm()), "admin2", "admin2");
         } finally {
             keycloakRule.stopSession(session, true);
         }
     }
 
-    private void assertAuthenticated(ModelProvider model, String realmName, String username, String password) {
+    private void assertAuthenticated(UserProvider userProvider, ModelProvider model, String realmName, String username, String password) {
         RealmModel realm = model.getRealmByName(realmName);
         if (realm == null) {
             Assert.fail("realm " + realmName + " not found");
         }
 
-        UserModel user = realm.getUser(username);
+        UserModel user = userProvider.getUserByUsername(username, realm);
         if (user == null) {
             Assert.fail("user " + username + " not found");
         }
@@ -285,13 +315,13 @@ public class ExportImportTest {
         Assert.assertTrue(realm.validatePassword(user, password));
     }
 
-    private void assertNotAuthenticated(ModelProvider model, String realmName, String username, String password) {
+    private void assertNotAuthenticated(UserProvider userProvider, ModelProvider model, String realmName, String username, String password) {
         RealmModel realm = model.getRealmByName(realmName);
         if (realm == null) {
             return;
         }
 
-        UserModel user = realm.getUser(username);
+        UserModel user = userProvider.getUserByUsername(username, realm);
         if (user == null) {
             return;
         }
@@ -299,8 +329,8 @@ public class ExportImportTest {
         Assert.assertFalse(realm.validatePassword(user, password));
     }
 
-    private static void addUser(RealmModel appRealm, String username, String password) {
-        UserModel user = appRealm.addUser(username);
+    private static void addUser(UserProvider userProvider, RealmModel appRealm, String username, String password) {
+        UserModel user = userProvider.addUser(appRealm, username);
         user.setEmail(username + "@test.com");
         user.setEnabled(true);
 
@@ -327,4 +357,5 @@ public class ExportImportTest {
         String absolutePath = new File(dirPath).getAbsolutePath();
         return absolutePath;
     }
+    */
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AuthProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AuthProvidersIntegrationTest.java
index e47c714..ede84bf 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AuthProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AuthProvidersIntegrationTest.java
@@ -11,6 +11,7 @@ import org.junit.runners.MethodSorters;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.model.test.LDAPTestUtils;
 import org.keycloak.models.AuthenticationProviderModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
@@ -47,8 +48,8 @@ public class AuthProvidersIntegrationTest {
 
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            addUser(appRealm, "mary", "mary@test.com", "password-app");
-            addUser(adminstrationRealm, "mary-admin", "mary@admin.com", "password-admin");
+            addUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
+            addUser(manager.getSession(), adminstrationRealm, "mary-admin", "mary@admin.com", "password-admin");
 
             AuthenticationProviderModel modelProvider = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_MODEL, false, Collections.EMPTY_MAP);
             AuthenticationProviderModel picketlinkProvider = new AuthenticationProviderModel(AuthProviderConstants.PROVIDER_NAME_PICKETLINK, true, Collections.EMPTY_MAP);
@@ -95,8 +96,8 @@ public class AuthProvidersIntegrationTest {
     @WebResource
     protected AccountPasswordPage changePasswordPage;
 
-    private static UserModel addUser(RealmModel realm, String username, String email, String password) {
-        UserModel user = realm.addUser(username);
+    private static UserModel addUser(KeycloakSession session, RealmModel realm, String username, String email, String password) {
+        UserModel user = session.users().addUser(realm, username);
         user.setEmail(email);
         user.setEnabled(true);
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
index 277bc7a..ad0a4c1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -51,7 +51,7 @@ public class LoginTest {
     public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            UserModel user = appRealm.addUser("login-test");
+            UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
             user.setEmail("login@test.com");
             user.setEnabled(true);
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index eadf367..9575f46 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -58,7 +58,7 @@ public class LoginTotpTest {
 
         @Override
         public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
-            UserModel user = appRealm.getUser("test-user@localhost");
+            UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
 
             UserCredentialModel credentials = new UserCredentialModel();
             credentials.setType(CredentialRepresentation.TOTP);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
index de74d0a..2bf8217 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
@@ -62,7 +62,7 @@ public class ResetPasswordTest {
     public static KeycloakRule keycloakRule = new KeycloakRule((new KeycloakRule.KeycloakSetup() {
         @Override
         public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-            UserModel user = appRealm.addUser("login-test");
+            UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
             user.setEmail("login@test.com");
             user.setEnabled(true);
 
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
old mode 100644
new mode 100755
index cb58949..b032c41
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java
@@ -36,17 +36,17 @@ public class UserSessionProviderTest {
     @Before
     public void before() {
         session = kc.startSession();
-        realm = session.model().getRealm("test");
-        realm.addUser("user1");
-        realm.addUser("user2");
+        realm = session.realms().getRealm("test");
+        session.users().addUser(realm, "user1");
+        session.users().addUser(realm, "user2");
     }
 
     @After
     public void after() {
         resetSession();
         session.sessions().removeUserSessions(realm);
-        realm.removeUser("user1");
-        realm.removeUser("user2");
+        session.users().removeUser(realm, "user1");
+        session.users().removeUser(realm, "user2");
         kc.stopSession(session, true);
     }
 
@@ -55,27 +55,27 @@ public class UserSessionProviderTest {
         int started = Time.currentTime();
         UserSessionModel[] sessions = createSessions();
 
-        assertSession(session.sessions().getUserSession(realm, sessions[0].getId()), realm.getUser("user1"), "127.0.0.1", started, started, "test-app", "third-party");
-        assertSession(session.sessions().getUserSession(realm, sessions[1].getId()), realm.getUser("user1"), "127.0.0.2", started, started, "test-app");
-        assertSession(session.sessions().getUserSession(realm, sessions[2].getId()), realm.getUser("user2"), "127.0.0.3", started, started);
+        assertSession(session.sessions().getUserSession(realm, sessions[0].getId()),  session.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party");
+        assertSession(session.sessions().getUserSession(realm, sessions[1].getId()),  session.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app");
+        assertSession(session.sessions().getUserSession(realm, sessions[2].getId()), session.users().getUserByUsername("user2", realm), "127.0.0.3", started, started);
     }
 
     @Test
     public void testGetUserSessions() {
         UserSessionModel[] sessions = createSessions();
 
-        assertSessions(session.sessions().getUserSessions(realm, realm.getUser("user1")), sessions[0], sessions[1]);
-        assertSessions(session.sessions().getUserSessions(realm, realm.getUser("user2")), sessions[2]);
+        assertSessions(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm)), sessions[0], sessions[1]);
+        assertSessions(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user2", realm)), sessions[2]);
     }
 
     @Test
     public void testRemoveUserSessionsByUser() {
         createSessions();
-        session.sessions().removeUserSessions(realm, realm.getUser("user1"));
+        session.sessions().removeUserSessions(realm, session.users().getUserByUsername("user1", realm));
         resetSession();
 
-        assertTrue(session.sessions().getUserSessions(realm, realm.getUser("user1")).isEmpty());
-        assertFalse(session.sessions().getUserSessions(realm, realm.getUser("user2")).isEmpty());
+        assertTrue(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm)).isEmpty());
+        assertFalse(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user2", realm)).isEmpty());
     }
 
     @Test
@@ -84,8 +84,8 @@ public class UserSessionProviderTest {
         session.sessions().removeUserSessions(realm);
         resetSession();
 
-        assertTrue(session.sessions().getUserSessions(realm, realm.getUser("user1")).isEmpty());
-        assertTrue(session.sessions().getUserSessions(realm, realm.getUser("user2")).isEmpty());
+        assertTrue(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm)).isEmpty());
+        assertTrue(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user2", realm)).isEmpty());
     }
 
     @Test
@@ -116,7 +116,7 @@ public class UserSessionProviderTest {
     @Test
     public void testGetByClientPaginated() {
         for (int i = 0; i < 25; i++) {
-            UserSessionModel userSession = session.sessions().createUserSession(realm, realm.getUser("user1"), "127.0.0." + i);
+            UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "127.0.0." + i);
             userSession.setStarted(Time.currentTime() + i);
             userSession.associateClient(realm.findClient("test-app"));
         }
@@ -157,14 +157,14 @@ public class UserSessionProviderTest {
 
     private UserSessionModel[] createSessions() {
         UserSessionModel[] sessions = new UserSessionModel[4];
-        sessions[0] = session.sessions().createUserSession(realm, realm.getUser("user1"), "127.0.0.1");
+        sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "127.0.0.1");
         sessions[0].associateClient(realm.findClient("test-app"));
         sessions[0].associateClient(realm.findClient("third-party"));
 
-        sessions[1] = session.sessions().createUserSession(realm, realm.getUser("user1"), "127.0.0.2");
+        sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "127.0.0.2");
         sessions[1].associateClient(realm.findClient("test-app"));
 
-        sessions[2] = session.sessions().createUserSession(realm, realm.getUser("user2"), "127.0.0.3");
+        sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "127.0.0.3");
 
         resetSession();
 
@@ -174,7 +174,7 @@ public class UserSessionProviderTest {
     private void resetSession() {
         kc.stopSession(session, true);
         session = kc.startSession();
-        realm = session.model().getRealm("test");
+        realm = session.realms().getRealm("test");
     }
 
     public void assertSessions(List<UserSessionModel> actualSessions, UserSessionModel... expectedSessions) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
index 03b9086..947551e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
@@ -91,7 +91,9 @@ public class OAuthGrantTest {
 
         OAuthClient.AccessTokenResponse accessToken = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
 
-        AccessToken token = oauth.verifyToken(accessToken.getAccessToken());
+        String tokenString = accessToken.getAccessToken();
+        Assert.assertNotNull(tokenString);
+        AccessToken token = oauth.verifyToken(tokenString);
         assertEquals(sessionId, token.getSessionState());
 
         AccessToken.Access realmAccess = token.getRealmAccess();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java
index d9cdac3..a0203b0 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java
@@ -183,7 +183,7 @@ public class RefreshTokenTest {
         String refreshId = oauth.verifyRefreshToken(tokenResponse.getRefreshToken()).getId();
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.model().getRealmByName("test");
+        RealmModel realm = session.realms().getRealmByName("test");
         UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
         int last = userSession.getLastSessionRefresh();
         session.getTransaction().commit();
@@ -199,7 +199,7 @@ public class RefreshTokenTest {
         Assert.assertEquals(200, tokenResponse.getStatusCode());
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("test");
+        realm = session.realms().getRealmByName("test");
         userSession = session.sessions().getUserSession(realm, sessionId);
         int next = userSession.getLastSessionRefresh();
         session.getTransaction().commit();
@@ -211,7 +211,7 @@ public class RefreshTokenTest {
 
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("test");
+        realm = session.realms().getRealmByName("test");
         int lastAccessTokenLifespan = realm.getAccessTokenLifespan();
         realm.setAccessTokenLifespan(100000);
         session.getTransaction().commit();
@@ -221,7 +221,7 @@ public class RefreshTokenTest {
         tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "password");
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("test");
+        realm = session.realms().getRealmByName("test");
         userSession = session.sessions().getUserSession(realm, sessionId);
         next = userSession.getLastSessionRefresh();
         session.getTransaction().commit();
@@ -231,7 +231,7 @@ public class RefreshTokenTest {
         Assert.assertThat(next, allOf(greaterThan(last), lessThan(last + 6)));
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("test");
+        realm = session.realms().getRealmByName("test");
         int originalIdle = realm.getSsoSessionIdleTimeout();
         realm.setSsoSessionIdleTimeout(1);
         session.getTransaction().commit();
@@ -249,7 +249,7 @@ public class RefreshTokenTest {
         events.expectRefresh(refreshId, sessionId).error(Errors.INVALID_TOKEN);
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("test");
+        realm = session.realms().getRealmByName("test");
         realm.setSsoSessionIdleTimeout(originalIdle);
         realm.setAccessTokenLifespan(lastAccessTokenLifespan);
         session.getTransaction().commit();
@@ -274,7 +274,7 @@ public class RefreshTokenTest {
         String refreshId = oauth.verifyRefreshToken(tokenResponse.getRefreshToken()).getId();
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.model().getRealmByName("test");
+        RealmModel realm = session.realms().getRealmByName("test");
         int maxLifespan = realm.getSsoSessionMaxLifespan();
         realm.setSsoSessionMaxLifespan(1);
         session.getTransaction().commit();
@@ -289,7 +289,7 @@ public class RefreshTokenTest {
         assertNull(tokenResponse.getRefreshToken());
 
         session = keycloakRule.startSession();
-        realm = session.model().getRealmByName("test");
+        realm = session.realms().getRealmByName("test");
         realm.setSsoSessionMaxLifespan(maxLifespan);
         session.getTransaction().commit();
         session.close();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
index f79358f..b313d70 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
@@ -40,7 +40,8 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         KeycloakSession session = server.getSessionFactory().create();
         session.getTransaction().begin();
         try {
-            UserModel user = session.model().getRealmByName(realm).getUser(name);
+            RealmModel realmByName = session.realms().getRealmByName(realm);
+            UserModel user = session.users().getUserByUsername(name, realmByName);
             return user != null ? ModelToRepresentation.toRepresentation(user) : null;
         } finally {
             session.close();
@@ -51,7 +52,8 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         KeycloakSession session = server.getSessionFactory().create();
         session.getTransaction().begin();
         try {
-            return ModelToRepresentation.toRepresentation(session.model().getRealmByName(realm).getUserById(id));
+            RealmModel realmByName = session.realms().getRealmByName(realm);
+            return ModelToRepresentation.toRepresentation(session.users().getUserById(id, realmByName));
         } finally {
             session.close();
         }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
index 65395be..1e30a4b 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
@@ -100,7 +100,7 @@ public class KeycloakRule extends AbstractKeycloakRule {
 
     public void removeUserSession(String sessionId) {
         KeycloakSession session = startSession();
-        RealmModel realm = session.model().getRealm("test");
+        RealmModel realm = session.realms().getRealm("test");
         UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
         assertNotNull(userSession);
         session.sessions().removeUserSession(realm, userSession);
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
index eb532df..ab6dcbe 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
@@ -40,7 +40,7 @@ public class BaseJMeterPerformanceTest extends AbstractJavaSamplerClient {
 
             try {
                 String adminRealmName = Config.getAdminRealm();
-                if (keycloakSession.model().getRealm(adminRealmName) == null) {
+                if (keycloakSession.realms().getRealm(adminRealmName) == null) {
 
                     RealmManager manager = new RealmManager(keycloakSession);
                     manager.setContextPath(contextPath);
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
index 12f600c..48e5672 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
@@ -58,7 +58,7 @@ public class CreateUsersWorker implements Worker {
     @Override
     public void run(SampleResult result, KeycloakSession session) {
         // We need to obtain realm first
-        RealmModel realm = session.model().getRealm(realmId);
+        RealmModel realm = session.realms().getRealm(realmId);
         if (realm == null) {
             throw new IllegalStateException("Realm '" + realmId + "' not found");
         }
@@ -68,7 +68,7 @@ public class CreateUsersWorker implements Worker {
 
         String username = PerfTestUtils.getUsername(userNumber);
 
-        UserModel user = realm.addUser(username);
+        UserModel user = session.users().addUser(realm, username);
 
         // Add basic user attributes (NOTE: Actually backend is automatically upgraded during each setter call)
         if (addBasicUserAttributes) {
@@ -97,7 +97,7 @@ public class CreateUsersWorker implements Worker {
             }
 
             SocialLinkModel socialLink = new SocialLinkModel(socialProvider, username, username);
-            realm.addSocialLink(user, socialLink);
+            session.users().addSocialLink(realm, user, socialLink);
         }
 
         log.info("Finished creation of user " + username + " in realm: " + realm.getId());
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
index 05d47c6..a858767 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
@@ -67,7 +67,7 @@ public class ReadUsersWorker implements Worker {
     @Override
     public void run(SampleResult result, KeycloakSession session) {
         // We need to obtain realm first
-        RealmModel realm = session.model().getRealm(realmId);
+        RealmModel realm = session.realms().getRealm(realmId);
         if (realm == null) {
             throw new IllegalStateException("Realm '" + realmId + "' not found");
         }
@@ -86,7 +86,7 @@ public class ReadUsersWorker implements Worker {
             String username = PerfTestUtils.getUsername(userCounterInRealm);
             lastUsername = username;
 
-            UserModel user = realm.getUser(username);
+            UserModel user = session.users().getUserByUsername(username, realm);
 
             // Read roles of user in realm
             if (readRoles) {
@@ -106,13 +106,13 @@ public class ReadUsersWorker implements Worker {
 
             // Read socialLinks of user
             if (readSocialLinks) {
-                realm.getSocialLinks(user);
+                session.users().getSocialLinks(user, realm);
             }
 
             // Try to search by social links
             if (searchBySocialLinks) {
                 SocialLinkModel socialLink = new SocialLinkModel("facebook", username, username);
-                realm.getUserBySocialLink(socialLink);
+                session.users().getUserBySocialLink(socialLink, realm);
             }
         }
 
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java
index 7012d49..915ded9 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java
@@ -32,7 +32,7 @@ public class RemoveUsersWorker implements Worker {
 
         int realmNumber = realmsOffset + workerId;
         String realmId = PerfTestUtils.getRealmName(realmNumber);
-        realm = session.model().getRealm(realmId);
+        realm = session.realms().getRealm(realmId);
         if (realm == null) {
             throw new IllegalStateException("Realm '" + realmId + "' not found");
         }
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
old mode 100644
new mode 100755
index b00f08f..32599b5
--- 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
@@ -28,9 +28,9 @@ public class CreateUsersJob extends UsersJob {
     }
 
     @Override
-    protected void runIteration(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, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
         String username = prefix + "-" + counter;
-        UserModel user = realm.addUser(username);
+        UserModel user = session.users().addUser(realm, username);
         user.setEnabled(true);
         user.setFirstName("First");
         user.setLastName("Last");
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
old mode 100644
new mode 100755
index 0f98cb4..b215e89
--- 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
@@ -24,15 +24,15 @@ public class DeleteUsersJob extends UsersJob {
         RealmModel realm = new RealmManager(session).getRealmByName(realmName);
 
         // TODO: pagination
-        List<UserModel> users = (prefix==null) ? realm.getUsers() : realm.searchForUser(prefix);
+        List<UserModel> users = (prefix==null) ? session.users().getUsers(realm) : session.users().searchForUser(prefix, realm);
         users = users.subList(start, start + count);
 
         this.users = users.iterator();
     }
 
     @Override
-    protected void runIteration(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, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
         String username = users.next().getUsername();
-        realm.removeUser(username);
+        session.users().removeUser(realm, username);
     }
 }
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
old mode 100644
new mode 100755
index d0a1af9..37e61a5
--- 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
@@ -29,18 +29,18 @@ public class UpdateUsersJob extends UsersJob {
         RealmModel realm = new RealmManager(session).getRealmByName(realmName);
 
         // TODO: pagination
-        List<UserModel> users = (prefix==null) ? realm.getUsers() : realm.searchForUser(prefix);
+        List<UserModel> users = (prefix==null) ? session.users().getUsers(realm) : session.users().searchForUser(prefix, realm);
         users = users.subList(start, start + count);
 
         this.users = users.iterator();
     }
 
     @Override
-    protected void runIteration(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, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter) {
         String username = users.next().getUsername();
 
         // Remove all role mappings first
-        UserModel user = realm.getUser(username);
+        UserModel user = session.users().getUserByUsername(username, realm);
         Set<RoleModel> currRoles = user.getRoleMappings();
         for (RoleModel role : currRoles) {
             user.deleteRoleMapping(role);
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
old mode 100644
new mode 100755
index efc598a..5b7fc55
--- 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
@@ -70,7 +70,7 @@ public abstract class UsersJob implements Runnable {
             }
 
             for (int i = start; i < (start + count); i++) {
-                runIteration(realm, apps, realmRoles, appRoles, i);
+                runIteration(session, realm, apps, realmRoles, appRoles, i);
                 job.increment();
             }
 
@@ -86,7 +86,7 @@ public abstract class UsersJob implements Runnable {
 
     protected abstract void before(KeycloakSession keycloakSession);
 
-    protected abstract void runIteration(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, ApplicationModel> apps, Set<RoleModel> realmRoles, Map<String, Set<RoleModel>> appRoles, int counter);
 
     protected RoleModel findRole(Set<RoleModel> roles, String roleName) {
         for (RoleModel role : roles) {
diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
old mode 100644
new mode 100755
index 793c8c3..51ff6f3
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
@@ -2,7 +2,6 @@ package org.keycloak.test.tools;
 
 import org.keycloak.exportimport.ExportImportConfig;
 import org.keycloak.exportimport.ExportImportManager;
-import org.keycloak.exportimport.ExportProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
@@ -11,14 +10,12 @@ import org.keycloak.test.tools.jobs.DeleteUsersJob;
 import org.keycloak.test.tools.jobs.UpdateUsersJob;
 import org.keycloak.test.tools.jobs.UsersJob;
 import org.keycloak.test.tools.jobs.UsersJobInitializer;
-import org.keycloak.util.ProviderLoader;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 
@@ -171,13 +168,13 @@ public class PerfTools {
     }
 
     private int getUsersCount(String realmName, String prefix) {
-        RealmModel realm = session.model().getRealmByName(realmName);
+        RealmModel realm = session.realms().getRealmByName(realmName);
 
         // TODO: method for count on model
         if (prefix == null) {
-            return realm.getUsers().size();
+            return session.users().getUsers(realm).size();
         } else {
-            return realm.searchForUser(prefix).size();
+            return session.users().searchForUser(prefix, realm).size();
         }
     }