keycloak-uncached

Changes

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

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

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

model/jpa/src/main/java/org/keycloak/models/jpa/UsernameLoginFailureAdapter.java 70(+0 -70)

model/pom.xml 12(+7 -5)

model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemSessionProvider.java 194(+0 -194)

model/sessions-mem/src/main/resources/META-INF/services/org.keycloak.models.sessions.SessionProviderFactory 1(+0 -1)

model/tests-hybrid/pom.xml 55(+0 -55)

model/tests-hybrid/src/main/java/org/keycloak/model/test/AbstractUserProviderTest.java 274(+0 -274)

pom.xml 6(+6 -0)

server/pom.xml 5(+5 -0)

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
index f763928..a4aadfd 100644
--- a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
+++ b/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
@@ -27,7 +27,7 @@ public class EmailAuditListener implements AuditListener {
 
     public EmailAuditListener(KeycloakSession session, EmailProvider emailProvider, Set<EventType> includedEvents) {
         this.session = session;
-        this.model = session.getModel();
+        this.model = session.model();
         this.emailProvider = emailProvider;
         this.includedEvents = includedEvents;
     }
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
index b6e22c7..17c06ef 100644
--- 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
@@ -20,7 +20,7 @@ public class ExternalModelAuthenticationProvider extends AbstractModelAuthentica
     private ModelProvider model;
 
     public ExternalModelAuthenticationProvider(KeycloakSession session) {
-        this.model = session.getModel();
+        this.model = session.model();
     }
 
     @Override
diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java
index fd0a2bb..03c9dda 100644
--- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java
+++ b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java
@@ -41,11 +41,11 @@ public class ExportImportProviderImpl implements ExportImportProvider {
 
                 if (export) {
                     ExportWriter exportWriter = getProvider().getExportWriter();
-                    new ModelExporter().exportModel(session.getModel(), exportWriter);
+                    new ModelExporter().exportModel(session.model(), exportWriter);
                     logger.infof("Export finished successfully");
                 } else {
                     ImportReader importReader = getProvider().getImportReader();
-                    new ModelImporter().importModel(session.getModel(), importReader);
+                    new ModelImporter().importModel(session.model(), importReader);
                     logger.infof("Import finished successfully");
                 }
 
diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java
index e63f0ac..2b47bce 100755
--- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java
+++ b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java
@@ -55,7 +55,7 @@ public class ModelExporter {
         exportOAuthClients(model, "oauthClients.json");
         exportRoles(model, "roles.json");
         exportUsers(model, "users.json");
-        exportUserFailures(model, "userFailures.json");
+//        exportUserFailures(model, "userFailures.json");
 
         this.exportWriter.closeExportWriter();
     }
@@ -278,25 +278,25 @@ public class ModelExporter {
 
 
      // Does it makes sense to export user failures ?
-    protected void exportUserFailures(ModelProvider model, String fileName) {
-        List<RealmModel> realms = model.getRealms();
-        List<UsernameLoginFailureModel> allFailures = new ArrayList<UsernameLoginFailureModel>();
-        for (RealmModel realmModel : realms) {
-            allFailures.addAll(realmModel.getAllUserLoginFailures());
-        }
-
-        List<UsernameLoginFailureEntity> result = new LinkedList<UsernameLoginFailureEntity>();
-        for (UsernameLoginFailureModel failureModel : allFailures) {
-            UsernameLoginFailureEntity failureEntity = new UsernameLoginFailureEntity();
-            this.propertiesManager.setBasicPropertiesFromModel(failureModel, failureEntity);
-            result.add(failureEntity);
-
-            failureEntity.setUsername(failureModel.getUsername());
-            failureEntity.setNumFailures(failureModel.getNumFailures());
-        }
-
-        this.exportWriter.writeEntities(fileName, result);
-    }
+//    protected void exportUserFailures(ModelProvider model, String fileName) {
+//        List<RealmModel> realms = model.getRealms();
+//        List<UsernameLoginFailureModel> allFailures = new ArrayList<UsernameLoginFailureModel>();
+//        for (RealmModel realmModel : realms) {
+//            allFailures.addAll(realmModel.getAllUserLoginFailures());
+//        }
+//
+//        List<UsernameLoginFailureEntity> result = new LinkedList<UsernameLoginFailureEntity>();
+//        for (UsernameLoginFailureModel failureModel : allFailures) {
+//            UsernameLoginFailureEntity failureEntity = new UsernameLoginFailureEntity();
+//            this.propertiesManager.setBasicPropertiesFromModel(failureModel, failureEntity);
+//            result.add(failureEntity);
+//
+//            failureEntity.setUsername(failureModel.getUsername());
+//            failureEntity.setNumFailures(failureModel.getNumFailures());
+//        }
+//
+//        this.exportWriter.writeEntities(fileName, result);
+//    }
 
     private List<String> getScopeIds(ClientModel clientModel) {
         Set<RoleModel> allScopes = clientModel.getScopeMappings();
diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
index eb10fbc..35371b4 100755
--- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
+++ b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java
@@ -63,7 +63,7 @@ public class ModelImporter {
 
         importOAuthClients(model, "oauthClients.json");
         importUsers(model, "users.json");
-        importUserFailures(model, "userFailures.json");
+//        importUserFailures(model, "userFailures.json");
 
         this.importReader.closeImportReader();
     }
@@ -311,17 +311,17 @@ public class ModelImporter {
         }
     }
 
-    public void importUserFailures(ModelProvider model, String fileName) {
-        List<UsernameLoginFailureEntity> userFailures = this.importReader.readEntities(fileName, UsernameLoginFailureEntity.class);
-        for (UsernameLoginFailureEntity entity : userFailures) {
-            RealmModel realm = model.getRealm(entity.getRealmId());
-            UsernameLoginFailureModel loginFailureModel = realm.addUserLoginFailure(entity.getUsername());
-
-            this.propertiesManager.setBasicPropertiesToModel(loginFailureModel , entity);
-
-            for (int i=0 ; i<entity.getNumFailures() ; i++) {
-                loginFailureModel.incrementFailures();
-            }
-        }
-    }
+//    public void importUserFailures(ModelProvider model, String fileName) {
+//        List<UsernameLoginFailureEntity> userFailures = this.importReader.readEntities(fileName, UsernameLoginFailureEntity.class);
+//        for (UsernameLoginFailureEntity entity : userFailures) {
+//            RealmModel realm = model.getRealm(entity.getRealmId());
+//            UsernameLoginFailureModel loginFailureModel = realm.addUserLoginFailure(entity.getUsername());
+//
+//            this.propertiesManager.setBasicPropertiesToModel(loginFailureModel , entity);
+//
+//            for (int i=0 ; i<entity.getNumFailures() ; i++) {
+//                loginFailureModel.incrementFailures();
+//            }
+//        }
+//    }
 }
diff --git a/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/ExportImportTestBase.java b/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/ExportImportTestBase.java
index 318313f..1f0c55e 100644
--- a/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/ExportImportTestBase.java
+++ b/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/ExportImportTestBase.java
@@ -55,7 +55,7 @@ public abstract class ExportImportTestBase {
         exportModel(factory);
 
         beginTransaction();
-        realm = session.getModel().getRealm("demo");
+        realm = session.model().getRealm("demo");
         String wburkeId = realm.getUser("wburke").getId();
         String appId = realm.getApplicationByName("Application").getId();
 
@@ -72,7 +72,7 @@ public abstract class ExportImportTestBase {
 
         // Verify it's imported in mongo (reusing ImportTest)
         beginTransaction();
-        RealmModel importedRealm = session.getModel().getRealm("demo");
+        RealmModel importedRealm = session.model().getRealm("demo");
         System.out.println("Exported realm: " + realm + ", Imported realm: " + importedRealm);
 
         Assert.assertEquals(wburkeId, importedRealm.getUser("wburke").getId());
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 321d014..00e2b9b 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -75,7 +75,4 @@ public interface ClientModel {
 
     void setNotBefore(int notBefore);
 
-    Set<UserSessionModel> getUserSessions();
-
-    int getActiveUserSessions();
 }
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 19b6b07..409e77e 100755
--- a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
+++ b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
@@ -23,7 +23,9 @@ public interface KeycloakSession {
 
     <T extends Provider> Set<T> getAllProviders(Class<T> clazz);
 
-    ModelProvider getModel();
+    ModelProvider model();
+
+    UserSessionProvider sessions();
 
     void close();
 
diff --git a/model/api/src/main/java/org/keycloak/models/ModelProvider.java b/model/api/src/main/java/org/keycloak/models/ModelProvider.java
index 6e2ddf5..ff567d0 100755
--- a/model/api/src/main/java/org/keycloak/models/ModelProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/ModelProvider.java
@@ -31,26 +31,11 @@ public interface ModelProvider extends Provider {
     Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm);
     SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm);
 
-
     RoleModel getRoleById(String id, RealmModel realm);
     ApplicationModel getApplicationById(String id, RealmModel realm);
     OAuthClientModel getOAuthClientById(String id, RealmModel realm);
     List<RealmModel> getRealms();
     boolean removeRealm(String id);
 
-    UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm);
-    UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm);
-    List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm);
-
-    UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress);
-    UserSessionModel getUserSession(String id, RealmModel realm);
-    List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm);
-    Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client);
-    int getActiveUserSessions(RealmModel realm, ClientModel client);
-    void removeUserSession(UserSessionModel session);
-    void removeUserSessions(RealmModel realm, UserModel user);
-    void removeExpiredUserSessions(RealmModel realm);
-    void removeUserSessions(RealmModel realm);
-
     void close();
 }
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 7106454..2092f72 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -165,10 +165,6 @@ public interface RealmModel extends RoleContainerModel {
 
     void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin);
 
-    UsernameLoginFailureModel getUserLoginFailure(String username);
-    UsernameLoginFailureModel addUserLoginFailure(String username);
-    List<UsernameLoginFailureModel> getAllUserLoginFailures();
-
     List<UserModel> getUsers();
 
     List<UserModel> searchForUser(String search);
@@ -245,19 +241,6 @@ public interface RealmModel extends RoleContainerModel {
 
     void setMasterAdminApp(ApplicationModel app);
 
-    UserSessionModel createUserSession(UserModel user, String ipAddress);
-
-    UserSessionModel getUserSession(String id);
-
-    List<UserSessionModel> getUserSessions(UserModel user);
-
-    void removeUserSession(UserSessionModel session);
-
-    void removeUserSessions(UserModel user);
-
-    void removeExpiredUserSessions();
-
     ClientModel findClientById(String id);
 
-    void removeUserSessions();
 }
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
new file mode 100755
index 0000000..053b667
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
@@ -0,0 +1,37 @@
+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>
+ * @version $Revision: 1 $
+ */
+public interface UserSessionProvider extends Provider {
+
+    KeycloakTransaction getTransaction();
+
+    UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress);
+    UserSessionModel getUserSession(RealmModel realm, String id);
+    List<UserSessionModel> getUserSessions(RealmModel realm, UserModel user);
+    Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client);
+    int getActiveUserSessions(RealmModel realm, ClientModel client);
+    void removeUserSession(RealmModel realm, UserSessionModel session);
+    void removeUserSessions(RealmModel realm, UserModel user);
+    void removeExpiredUserSessions(RealmModel realm);
+    void removeUserSessions(RealmModel realm);
+
+    UsernameLoginFailureModel getUserLoginFailure(RealmModel realm, String username);
+    UsernameLoginFailureModel addUserLoginFailure(RealmModel realm, String username);
+    List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm);
+
+    void onRealmRemoved(RealmModel realm);
+    void onClientRemoved(RealmModel realm, ClientModel client);
+    void onUserRemoved(RealmModel realm, UserModel user);
+
+    void close();
+
+}
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionProviderFactory.java b/model/api/src/main/java/org/keycloak/models/UserSessionProviderFactory.java
new file mode 100755
index 0000000..5e57609
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionProviderFactory.java
@@ -0,0 +1,10 @@
+package org.keycloak.models;
+
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface UserSessionProviderFactory extends ProviderFactory<UserSessionProvider> {
+}
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionSpi.java b/model/api/src/main/java/org/keycloak/models/UserSessionSpi.java
new file mode 100644
index 0000000..471928e
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionSpi.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 UserSessionSpi implements Spi {
+
+    @Override
+    public String getName() {
+        return "userSessions";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return UserSessionProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return UserSessionProviderFactory.class;
+    }
+
+}
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
index 48ff59e..6ad707c 100644
--- 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 +1,2 @@
-org.keycloak.models.ModelSpi
\ No newline at end of file
+org.keycloak.models.ModelSpi
+org.keycloak.models.UserSessionSpi
\ No newline at end of file
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
index a35b662..d0c4b4e 100644
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
@@ -181,16 +181,6 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
-    public Set<UserSessionModel> getUserSessions() {
-        return provider.mappings().wrapSessions(getRealm(), provider.sessions().getUserSessionsByClient(client.getRealm().getId(), client.getId()));
-    }
-
-    @Override
-    public int getActiveUserSessions() {
-        return provider.sessions().getActiveUserSessions(client.getRealm().getId(), client.getId());
-    }
-
-    @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (!this.getClass().equals(o.getClass())) return false;
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
index 8de241d..b971646 100644
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
@@ -199,53 +199,6 @@ public class HybridModelProvider implements ModelProvider {
     }
 
     @Override
-    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
-        return mappings.wrap(realm, sessions().createUserSession(realm.getId(), KeycloakModelUtils.generateId(), user.getId(), ipAddress));
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id, RealmModel realm) {
-        return mappings.wrap(realm, sessions().getUserSession(id, realm.getId()));
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
-        return mappings.wrapSessions(realm, sessions().getUserSessionsByUser(user.getId(), realm.getId()));
-    }
-
-    @Override
-    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
-        return mappings.wrapSessions(realm, sessions().getUserSessionsByClient(realm.getId(), client.getClientId()));
-    }
-
-    @Override
-    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
-        return sessions().getActiveUserSessions(realm.getId(), client.getClientId());
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        sessions().removeUserSession(mappings.unwrap(session));
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm, UserModel user) {
-        sessions().removeUserSessions(realm.getId(), user.getId());
-    }
-
-    @Override
-    public void removeExpiredUserSessions(RealmModel realm) {
-        long refreshTimeout = Time.currentTime() - realm.getSsoSessionIdleTimeout();
-        long sessionTimeout = Time.currentTime() - realm.getSsoSessionMaxLifespan();
-        sessions().removeExpiredUserSessions(realm.getId(), refreshTimeout, sessionTimeout);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm) {
-        sessions().removeUserSessions(realm.getId());
-    }
-
-    @Override
     public void close() {
     }
 
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
index 2f3e0a2..1f7bd27 100644
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
@@ -729,36 +729,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public UserSessionModel createUserSession(UserModel user, String ipAddress) {
-        return provider.createUserSession(this, user, ipAddress);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id) {
-        return provider.getUserSession(id, this);
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user) {
-        return provider.getUserSessions(user, this);
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        provider.removeUserSession(session);
-    }
-
-    @Override
-    public void removeUserSessions(UserModel user) {
-        provider.removeUserSessions(this, user);
-    }
-
-    @Override
-    public void removeExpiredUserSessions() {
-        provider.removeExpiredUserSessions(this);
-    }
-
-    @Override
     public ClientModel findClientById(String id) {
         Application application = provider.realms().getApplicationById(id, realm.getId());
         if (application != null) {
@@ -774,11 +744,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public void removeUserSessions() {
-        provider.removeUserSessions(this);
-    }
-
-    @Override
     public RoleModel getRole(String name) {
         return provider.mappings().wrap(realm.getRole(name));
     }
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 8be3d82..34a785c 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
@@ -196,13 +196,4 @@ public abstract class ClientAdapter implements ClientModel {
         updatedClient.setNotBefore(notBefore);
     }
 
-    public Set<UserSessionModel> getUserSessions() {
-        if (updatedClient != null) return updatedClient.getUserSessions();
-        return cacheSession.getUserSessions(cachedRealm, this);
-    }
-
-    public int getActiveUserSessions() {
-        if (updatedClient != null) return updatedClient.getActiveUserSessions();
-        return cacheSession.getActiveUserSessions(cachedRealm, this);
-    }
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java
index 186d76b..46521df 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java
@@ -388,63 +388,4 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
         return adapter;
     }
 
-    @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm) {
-        return getDelegate().getUserLoginFailure(username, realm);
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm) {
-        return getDelegate().addUserLoginFailure(username, realm);
-    }
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm) {
-        return getDelegate().getAllUserLoginFailures(realm);
-    }
-
-    @Override
-    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
-        return getDelegate().createUserSession(realm, user, ipAddress);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id, RealmModel realm) {
-        return getDelegate().getUserSession(id, realm);
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
-        return getDelegate().getUserSessions(user, realm);
-    }
-
-    @Override
-    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
-        return getDelegate().getUserSessions(realm, client);
-    }
-
-    @Override
-    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
-        return getDelegate().getActiveUserSessions(realm, client);
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        getDelegate().removeUserSession(session);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm, UserModel user) {
-        getDelegate().removeUserSessions(realm, user);
-    }
-
-    @Override
-    public void removeExpiredUserSessions(RealmModel realm) {
-        getDelegate().removeExpiredUserSessions(realm);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm) {
-        getDelegate().removeUserSessions(realm);
-    }
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java
index b9cf8d1..fa85cb4 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java
@@ -207,66 +207,6 @@ public class NoCacheModelProvider implements CacheModelProvider {
     }
 
     @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm) {
-        return getDelegate().getUserLoginFailure(username, realm);
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm) {
-        return getDelegate().addUserLoginFailure(username, realm);
-    }
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm) {
-        return getDelegate().getAllUserLoginFailures(realm);
-    }
-
-    @Override
-    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
-        return getDelegate().createUserSession(realm, user, ipAddress);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id, RealmModel realm) {
-        return getDelegate().getUserSession(id, realm);
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
-        return getDelegate().getUserSessions(user, realm);
-    }
-
-    @Override
-    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
-        return getDelegate().getUserSessions(realm, client);
-    }
-
-    @Override
-    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
-        return getDelegate().getActiveUserSessions(realm, client);
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        getDelegate().removeUserSession(session);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm, UserModel user) {
-        getDelegate().removeUserSessions(realm, user);
-    }
-
-    @Override
-    public void removeExpiredUserSessions(RealmModel realm) {
-        getDelegate().removeExpiredUserSessions(realm);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm) {
-        getDelegate().removeUserSessions(realm);
-    }
-
-    @Override
     public void registerUserInvalidation(String id) {
         //To change body of implemented methods use File | Settings | File Templates.
     }
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 2c973f3..922065d 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
@@ -875,83 +875,6 @@ public class RealmAdapter implements RealmModel {
         return getOAuthClientById(id);
     }
 
-
-    @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String username) {
-        if (updated != null) return updated.getUserLoginFailure(username);
-        return cacheSession.getUserLoginFailure(username, this);
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username) {
-        if (updated != null) return updated.addUserLoginFailure(username);
-        return cacheSession.addUserLoginFailure(username, this);
-    }
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures() {
-        if (updated != null) return updated.getAllUserLoginFailures();
-        return cacheSession.getAllUserLoginFailures(this);
-    }
-
-    @Override
-    public UserSessionModel createUserSession(UserModel user, String ipAddress) {
-        if (updated != null) return updated.createUserSession(user, ipAddress);
-        return cacheSession.createUserSession(this, user, ipAddress);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id) {
-        if (updated != null) return updated.getUserSession(id);
-        return cacheSession.getUserSession(id, this);
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user) {
-        if (updated != null) return updated.getUserSessions(user);
-        return cacheSession.getUserSessions(user, this);
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        if (updated != null) {
-            updated.removeUserSession(session);
-        } else {
-            cacheSession.removeUserSession(session);
-
-        }
-    }
-
-    @Override
-    public void removeUserSessions(UserModel user) {
-        if (updated != null) {
-            updated.removeUserSessions(user);
-        } else {
-            cacheSession.removeUserSessions(this, user);
-
-        }
-    }
-
-    @Override
-    public void removeExpiredUserSessions() {
-        if (updated != null) {
-            updated.removeExpiredUserSessions();
-        } else {
-            cacheSession.removeExpiredUserSessions(this);
-
-        }
-    }
-
-    @Override
-    public void removeUserSessions() {
-        if (updated != null) {
-            updated.removeUserSessions();
-        } else {
-            cacheSession.removeUserSessions(this);
-
-        }
-    }
-
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index 2e99658..6a07b5e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -4,16 +4,12 @@ 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.jpa.entities.ClientEntity;
-import org.keycloak.models.jpa.entities.ClientUserSessionAssociationEntity;
 import org.keycloak.models.jpa.entities.RoleEntity;
 import org.keycloak.models.jpa.entities.ScopeMappingEntity;
 
 import javax.persistence.EntityManager;
-import javax.persistence.Query;
 import javax.persistence.TypedQuery;
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -154,31 +150,6 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
-    public int getActiveUserSessions() {
-        Query query = em.createNamedQuery("getActiveClientSessions");
-        query.setParameter("clientId", getId());
-        Object count = query.getSingleResult();
-        return ((Number)count).intValue();
-    }
-
-    @Override
-    public Set<UserSessionModel> getUserSessions() {
-        Set<UserSessionModel> list = new HashSet<UserSessionModel>();
-        TypedQuery<ClientUserSessionAssociationEntity> query = em.createNamedQuery("getClientUserSessionByClient", ClientUserSessionAssociationEntity.class);
-        String id = getId();
-        query.setParameter("clientId", id);
-        List<ClientUserSessionAssociationEntity> results = query.getResultList();
-        for (ClientUserSessionAssociationEntity entity : results) {
-            list.add(new UserSessionAdapter(em, realm, entity.getSession()));
-        }
-        return list;
-    }
-
-    public void deleteUserSessionAssociation() {
-        em.createNamedQuery("removeClientUserSessionByClient").setParameter("clientId", getId()).executeUpdate();
-    }
-
-    @Override
     public Set<RoleModel> getRealmScopeMappings() {
         Set<RoleModel> roleMappings = getScopeMappings();
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
index 940e067..c1f6310 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
@@ -1,14 +1,24 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.*;
-import org.keycloak.models.jpa.entities.*;
+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.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;
+import org.keycloak.models.jpa.entities.UserEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.util.Time;
 
 import javax.persistence.EntityManager;
-import javax.persistence.Query;
 import javax.persistence.TypedQuery;
-import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -120,7 +130,6 @@ public class JpaModelProvider implements ModelProvider {
         }
 
         RealmAdapter adapter = new RealmAdapter(session, em, realm);
-        adapter.removeUserSessions();
         for (ApplicationEntity a : new LinkedList<ApplicationEntity>(realm.getApplications())) {
             adapter.removeApplication(a.getId());
         }
@@ -134,7 +143,6 @@ public class JpaModelProvider implements ModelProvider {
         }
 
         em.remove(realm);
-
         return true;
     }
 
@@ -145,15 +153,6 @@ public class JpaModelProvider implements ModelProvider {
     }
 
     @Override
-    public void removeAllData() {
-        // Should be sufficient to delete all realms. Rest data should be removed in cascade
-        List<RealmModel> realms = getRealms();
-        for (RealmModel realm : realms) {
-            removeRealm(realm.getId());
-        }
-    }
-
-    @Override
     public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
         TypedQuery<UserEntity> query = em.createNamedQuery("findUserByLinkAndRealm", UserEntity.class);
         RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
@@ -284,117 +283,4 @@ public class JpaModelProvider implements ModelProvider {
         return new OAuthClientAdapter(realm, client, em);
     }
 
-    @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm) {
-        String id = username + "-" + realm.getId();
-        UsernameLoginFailureEntity entity = em.find(UsernameLoginFailureEntity.class, id);
-        if (entity == null) return null;
-        return new UsernameLoginFailureAdapter(entity);
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm) {
-        UsernameLoginFailureModel model = getUserLoginFailure(username, realm);
-        if (model != null) return model;
-        String id = username + "-" + realm.getId();
-        UsernameLoginFailureEntity entity = new UsernameLoginFailureEntity();
-        entity.setId(id);
-        entity.setUsername(username);
-        RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
-        entity.setRealm(realmEntity);
-        em.persist(entity);
-        return new UsernameLoginFailureAdapter(entity);
-    }
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm) {
-        TypedQuery<UsernameLoginFailureEntity> query = em.createNamedQuery("getAllFailures", UsernameLoginFailureEntity.class);
-        List<UsernameLoginFailureEntity> entities = query.getResultList();
-        List<UsernameLoginFailureModel> models = new ArrayList<UsernameLoginFailureModel>();
-        for (UsernameLoginFailureEntity entity : entities) {
-            models.add(new UsernameLoginFailureAdapter(entity));
-        }
-        return models;
-    }
-
-    @Override
-    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
-        UserSessionEntity entity = new UserSessionEntity();
-        entity.setRealmId(realm.getId());
-        entity.setUserId(user.getId());
-        entity.setIpAddress(ipAddress);
-
-        int currentTime = Time.currentTime();
-
-        entity.setStarted(currentTime);
-        entity.setLastSessionRefresh(currentTime);
-
-        em.persist(entity);
-        return new UserSessionAdapter(em, realm, entity);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id, RealmModel realm) {
-        UserSessionEntity entity = em.find(UserSessionEntity.class, id);
-        return entity != null ? new UserSessionAdapter(em, realm, entity) : null;
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
-        List<UserSessionModel> sessions = new LinkedList<UserSessionModel>();
-        for (UserSessionEntity e : em.createNamedQuery("getUserSessionByUser", UserSessionEntity.class)
-                .setParameter("userId", user.getId()).getResultList()) {
-            sessions.add(new UserSessionAdapter(em, realm, e));
-        }
-        return sessions;
-    }
-
-    @Override
-    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
-        Set<UserSessionModel> list = new HashSet<UserSessionModel>();
-        TypedQuery<ClientUserSessionAssociationEntity> query = em.createNamedQuery("getClientUserSessionByClient", ClientUserSessionAssociationEntity.class);
-        String id = client.getId();
-        query.setParameter("clientId", id);
-        List<ClientUserSessionAssociationEntity> results = query.getResultList();
-        for (ClientUserSessionAssociationEntity entity : results) {
-            list.add(new UserSessionAdapter(em, realm, entity.getSession()));
-        }
-        return list;
-    }
-
-    @Override
-    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
-        Query query = em.createNamedQuery("getActiveClientSessions");
-        query.setParameter("clientId", client.getId());
-        Object count = query.getSingleResult();
-        return ((Number)count).intValue();
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        em.remove(((UserSessionAdapter) session).getEntity());
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm, UserModel user) {
-        em.createNamedQuery("removeClientUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
-        em.createNamedQuery("removeUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
-    }
-
-    @Override
-    public void removeExpiredUserSessions(RealmModel realm) {
-        TypedQuery<UserSessionEntity> query = em.createNamedQuery("getUserSessionExpired", UserSessionEntity.class)
-                .setParameter("maxTime", Time.currentTime() - realm.getSsoSessionMaxLifespan())
-                .setParameter("idleTime", Time.currentTime() - realm.getSsoSessionIdleTimeout());
-        List<UserSessionEntity> results = query.getResultList();
-        for (UserSessionEntity entity : results) {
-            em.remove(entity);
-        }
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm) {
-        em.createNamedQuery("removeClientUserSessionByRealm").setParameter("realmId", realm.getId()).executeUpdate();
-        em.createNamedQuery("removeRealmUserSessions").setParameter("realmId", realm.getId()).executeUpdate();
-    }
 }
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 23602ec..a656b0a 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -1,17 +1,21 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.AuthenticationLinkModel;
+import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.CredentialValidation;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.RoleContainerModel;
+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.UserSessionModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.jpa.entities.ApplicationEntity;
-import org.keycloak.models.jpa.entities.AuthenticationLinkEntity;
 import org.keycloak.models.jpa.entities.AuthenticationProviderEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
@@ -20,26 +24,12 @@ 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.UserSessionEntity;
 import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
-import org.keycloak.models.jpa.entities.UsernameLoginFailureEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
-import org.keycloak.models.ApplicationModel;
-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.UserModel;
 import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.util.Time;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
-
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.util.ArrayList;
@@ -49,13 +39,10 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static org.keycloak.models.utils.Pbkdf2PasswordEncoder.*;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -426,32 +413,17 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public UserModel getUser(String name) {
-        return session.getUserByUsername(name, this);
-    }
-
-    @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String username) {
-        return session.getUserLoginFailure(username, this);
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username) {
-        return session.addUserLoginFailure(username, this);
-    }
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures() {
-        return session.getAllUserLoginFailures(this);
+        return session.model().getUserByUsername(name, this);
     }
 
     @Override
     public UserModel getUserByEmail(String email) {
-        return session.getUserByEmail(email, this);
+        return session.model().getUserByEmail(email, this);
     }
 
     @Override
     public UserModel getUserById(String id) {
-        return session.getUserById(id, this);
+        return session.model().getUserById(id, this);
     }
 
     @Override
@@ -500,9 +472,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     private void removeUser(UserEntity user) {
-        em.createNamedQuery("removeClientUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
-        em.createNamedQuery("removeUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
-
         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) {
@@ -629,8 +598,6 @@ public class RealmAdapter implements RealmModel {
         ApplicationModel application = getApplicationById(id);
         if (application == null) return false;
 
-        em.createNamedQuery("removeClientUserSessionByClient").setParameter("clientId", application.getId()).executeUpdate();
-
         for (RoleModel role : application.getRoles()) {
             application.removeRole(role);
         }
@@ -661,7 +628,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public ApplicationModel getApplicationById(String id) {
-        return session.getApplicationById(id, this);
+        return session.model().getApplicationById(id, this);
     }
 
     @Override
@@ -671,17 +638,17 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
-        return session.getUserBySocialLink(socialLink, this);
+        return session.model().getUserBySocialLink(socialLink, this);
     }
 
     @Override
     public Set<SocialLinkModel> getSocialLinks(UserModel user) {
-        return session.getSocialLinks(user, this);
+        return session.model().getSocialLinks(user, this);
     }
 
     @Override
     public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
-        return session.getSocialLink(user, socialProvider, this);
+        return session.model().getSocialLink(user, socialProvider, this);
     }
 
     @Override
@@ -744,17 +711,17 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public List<UserModel> getUsers() {
-        return session.getUsers(this);
+        return session.model().getUsers(this);
     }
 
     @Override
     public List<UserModel> searchForUser(String search) {
-        return session.searchForUser(search, this);
+        return session.model().searchForUser(search, this);
     }
 
     @Override
     public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
-        return session.searchForUserByAttributes(attributes, this);
+        return session.model().searchForUserByAttributes(attributes, this);
     }
 
     @Override
@@ -778,7 +745,6 @@ public class RealmAdapter implements RealmModel {
     public boolean removeOAuthClient(String id) {
         OAuthClientModel oauth = getOAuthClientById(id);
         if (oauth == null) return false;
-        ((OAuthClientAdapter)oauth).deleteUserSessionAssociation();
         OAuthClientEntity client = (OAuthClientEntity) ((OAuthClientAdapter) oauth).getEntity();
         em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where client = :client").setParameter("client", client).executeUpdate();
         em.remove(client);
@@ -798,7 +764,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public OAuthClientModel getOAuthClientById(String id) {
-        return session.getOAuthClientById(id, this);
+        return session.model().getOAuthClientById(id, this);
     }
 
 
@@ -960,7 +926,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public RoleModel getRoleById(String id) {
-        return session.getRoleById(id, this);
+        return session.model().getRoleById(id, this);
     }
 
     @Override
@@ -1103,40 +1069,4 @@ public class RealmAdapter implements RealmModel {
         em.flush();
     }
 
-    @Override
-    public UserSessionModel createUserSession(UserModel user, String ipAddress) {
-        return session.createUserSession(this, user, ipAddress);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id) {
-        return session.getUserSession(id, this);
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user) {
-        return session.getUserSessions(user, this);
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        this.session.removeUserSession(session);
-    }
-
-    @Override
-    public void removeUserSessions() {
-        session.removeUserSessions(this);
-
-    }
-
-    @Override
-    public void removeUserSessions(UserModel user) {
-        session.removeUserSessions(this, user);
-    }
-
-    @Override
-    public void removeExpiredUserSessions() {
-        session.removeExpiredUserSessions(this);
-    }
-
 }
diff --git a/model/jpa/src/test/resources/META-INF/persistence.xml b/model/jpa/src/test/resources/META-INF/persistence.xml
index a150d05..7391d71 100755
--- a/model/jpa/src/test/resources/META-INF/persistence.xml
+++ b/model/jpa/src/test/resources/META-INF/persistence.xml
@@ -15,10 +15,7 @@
         <class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
         <class>org.keycloak.models.jpa.entities.AuthenticationLinkEntity</class>
         <class>org.keycloak.models.jpa.entities.UserEntity</class>
-        <class>org.keycloak.models.jpa.entities.UserSessionEntity</class>
-        <class>org.keycloak.models.jpa.entities.ClientUserSessionAssociationEntity</class>
         <class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
-        <class>org.keycloak.models.jpa.entities.UsernameLoginFailureEntity</class>
         <class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
 
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
@@ -33,38 +30,4 @@
             <property name="hibernate.format_sql" value="true" />
         </properties>
     </persistence-unit>
-
-    <!--
-    <persistence-unit name="picketlink-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
-        <provider>org.hibernate.ejb.HibernatePersistence</provider>
-
-        <class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
-        <class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
-        <class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
-        <class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
-
-        <exclude-unlisted-classes>true</exclude-unlisted-classes>
-
-        <properties>
-            <property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
-            <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
-            <property name="hibernate.connection.username" value="sa"/>
-            <property name="hibernate.connection.password" value=""/>
-            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
-            <property name="hibernate.show_sql" value="false" />
-            <property name="hibernate.format_sql" value="true" />
-        </properties>
-    </persistence-unit>
-    -->
 </persistence>
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 2796f6a..d298487 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
@@ -5,7 +5,6 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.entities.ClientEntity;
 import org.keycloak.models.mongo.api.MongoIdentifiableEntity;
 import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
@@ -32,7 +31,7 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
         this.clientEntity = clientEntity;
         this.realm = realm;
         this.session = session;
-        this.model = session.getModel();
+        this.model = session.model();
     }
 
     @Override
@@ -175,16 +174,6 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
     }
 
     @Override
-    public Set<UserSessionModel> getUserSessions() {
-        return model.getUserSessions(realm, this);
-    }
-
-    @Override
-    public int getActiveUserSessions() {
-        return model.getActiveUserSessions(realm, this);
-    }
-
-    @Override
     public Set<RoleModel> getScopeMappings() {
         Set<RoleModel> result = new HashSet<RoleModel>();
         List<MongoRoleEntity> roles = MongoModelUtils.getAllScopesOfClient(this, invocationContext);
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java
index 7d567ca..f99ae30 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java
@@ -325,138 +325,138 @@ public class MongoModelProvider implements ModelProvider {
 
         return new OAuthClientAdapter(session, realm, clientEntity, invocationContext);
     }
-
-    @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm) {
-        DBObject query = new QueryBuilder()
-                .and("username").is(username)
-                .and("realmId").is(realm.getId())
-                .get();
-        MongoUsernameLoginFailureEntity user = getMongoStore().loadSingleEntity(MongoUsernameLoginFailureEntity.class, query, invocationContext);
-
-        if (user == null) {
-            return null;
-        } else {
-            return new UsernameLoginFailureAdapter(invocationContext, user);
-        }
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm) {
-        UsernameLoginFailureModel userLoginFailure = getUserLoginFailure(username, realm);
-        if (userLoginFailure != null) {
-            return userLoginFailure;
-        }
-
-        MongoUsernameLoginFailureEntity userEntity = new MongoUsernameLoginFailureEntity();
-        userEntity.setUsername(username);
-        userEntity.setRealmId(realm.getId());
-
-        getMongoStore().insertEntity(userEntity, invocationContext);
-        return new UsernameLoginFailureAdapter(invocationContext, userEntity);
-    }
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(realm.getId())
-                .get();
-        List<MongoUsernameLoginFailureEntity> failures = getMongoStore().loadEntities(MongoUsernameLoginFailureEntity.class, query, invocationContext);
-
-        List<UsernameLoginFailureModel> result = new ArrayList<UsernameLoginFailureModel>();
-
-        if (failures == null) return result;
-        for (MongoUsernameLoginFailureEntity failure : failures) {
-            result.add(new UsernameLoginFailureAdapter(invocationContext, failure));
-        }
-
-        return result;
-    }
-
-    @Override
-    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
-        MongoUserSessionEntity entity = new MongoUserSessionEntity();
-        entity.setRealmId(realm.getId());
-        entity.setUser(user.getId());
-        entity.setIpAddress(ipAddress);
-
-        int currentTime = Time.currentTime();
-
-        entity.setStarted(currentTime);
-        entity.setLastSessionRefresh(currentTime);
-
-        getMongoStore().insertEntity(entity, invocationContext);
-        return new UserSessionAdapter(entity, realm, invocationContext);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id, RealmModel realm) {
-        MongoUserSessionEntity entity = getMongoStore().loadEntity(MongoUserSessionEntity.class, id, invocationContext);
-        if (entity == null) {
-            return null;
-        } else {
-            return new UserSessionAdapter(entity, realm, invocationContext);
-        }
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
-        DBObject query = new BasicDBObject("user", user.getId());
-        List<UserSessionModel> sessions = new LinkedList<UserSessionModel>();
-        for (MongoUserSessionEntity e : getMongoStore().loadEntities(MongoUserSessionEntity.class, query, invocationContext)) {
-            sessions.add(new UserSessionAdapter(e, realm, invocationContext));
-        }
-        return sessions;
-    }
-
-    @Override
-    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
-        DBObject query = new QueryBuilder()
-                .and("associatedClientIds").is(client.getId())
-                .get();
-        List<MongoUserSessionEntity> sessions = getMongoStore().loadEntities(MongoUserSessionEntity.class, query, invocationContext);
-
-        Set<UserSessionModel> result = new HashSet<UserSessionModel>();
-        for (MongoUserSessionEntity session : sessions) {
-            result.add(new UserSessionAdapter(session, realm, invocationContext));
-        }
-        return result;
-    }
-
-    @Override
-    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
-        return getUserSessions(realm, client).size();
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        getMongoStore().removeEntity(((UserSessionAdapter) session).getMongoEntity(), invocationContext);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm, UserModel user) {
-        DBObject query = new BasicDBObject("user", user.getId());
-        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
-    }
-
-    @Override
-    public void removeUserSessions(RealmModel realm) {
-        DBObject query = new BasicDBObject("realmId", realm.getId());
-        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
-    }
-
-    @Override
-    public void removeExpiredUserSessions(RealmModel realm) {
-        int currentTime = Time.currentTime();
-        DBObject query = new QueryBuilder()
-                .and("started").lessThan(currentTime - realm.getSsoSessionMaxLifespan())
-                .get();
-
-        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
-        query = new QueryBuilder()
-                .and("lastSessionRefresh").lessThan(currentTime - realm.getSsoSessionIdleTimeout())
-                .get();
-
-        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
-    }
+//
+//    @Override
+//    public UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm) {
+//        DBObject query = new QueryBuilder()
+//                .and("username").is(username)
+//                .and("realmId").is(realm.getId())
+//                .get();
+//        MongoUsernameLoginFailureEntity user = getMongoStore().loadSingleEntity(MongoUsernameLoginFailureEntity.class, query, invocationContext);
+//
+//        if (user == null) {
+//            return null;
+//        } else {
+//            return new UsernameLoginFailureAdapter(invocationContext, user);
+//        }
+//    }
+//
+//    @Override
+//    public UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm) {
+//        UsernameLoginFailureModel userLoginFailure = getUserLoginFailure(username, realm);
+//        if (userLoginFailure != null) {
+//            return userLoginFailure;
+//        }
+//
+//        MongoUsernameLoginFailureEntity userEntity = new MongoUsernameLoginFailureEntity();
+//        userEntity.setUsername(username);
+//        userEntity.setRealmId(realm.getId());
+//
+//        getMongoStore().insertEntity(userEntity, invocationContext);
+//        return new UsernameLoginFailureAdapter(invocationContext, userEntity);
+//    }
+//
+//    @Override
+//    public List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm) {
+//        DBObject query = new QueryBuilder()
+//                .and("realmId").is(realm.getId())
+//                .get();
+//        List<MongoUsernameLoginFailureEntity> failures = getMongoStore().loadEntities(MongoUsernameLoginFailureEntity.class, query, invocationContext);
+//
+//        List<UsernameLoginFailureModel> result = new ArrayList<UsernameLoginFailureModel>();
+//
+//        if (failures == null) return result;
+//        for (MongoUsernameLoginFailureEntity failure : failures) {
+//            result.add(new UsernameLoginFailureAdapter(invocationContext, failure));
+//        }
+//
+//        return result;
+//    }
+
+//    @Override
+//    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
+//        MongoUserSessionEntity entity = new MongoUserSessionEntity();
+//        entity.setRealmId(realm.getId());
+//        entity.setUser(user.getId());
+//        entity.setIpAddress(ipAddress);
+//
+//        int currentTime = Time.currentTime();
+//
+//        entity.setStarted(currentTime);
+//        entity.setLastSessionRefresh(currentTime);
+//
+//        getMongoStore().insertEntity(entity, invocationContext);
+//        return new UserSessionAdapter(entity, realm, invocationContext);
+//    }
+//
+//    @Override
+//    public UserSessionModel getUserSession(String id, RealmModel realm) {
+//        MongoUserSessionEntity entity = getMongoStore().loadEntity(MongoUserSessionEntity.class, id, invocationContext);
+//        if (entity == null) {
+//            return null;
+//        } else {
+//            return new UserSessionAdapter(entity, realm, invocationContext);
+//        }
+//    }
+//
+//    @Override
+//    public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
+//        DBObject query = new BasicDBObject("user", user.getId());
+//        List<UserSessionModel> sessions = new LinkedList<UserSessionModel>();
+//        for (MongoUserSessionEntity e : getMongoStore().loadEntities(MongoUserSessionEntity.class, query, invocationContext)) {
+//            sessions.add(new UserSessionAdapter(e, realm, invocationContext));
+//        }
+//        return sessions;
+//    }
+//
+//    @Override
+//    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
+//        DBObject query = new QueryBuilder()
+//                .and("associatedClientIds").is(client.getId())
+//                .get();
+//        List<MongoUserSessionEntity> sessions = getMongoStore().loadEntities(MongoUserSessionEntity.class, query, invocationContext);
+//
+//        Set<UserSessionModel> result = new HashSet<UserSessionModel>();
+//        for (MongoUserSessionEntity session : sessions) {
+//            result.add(new UserSessionAdapter(session, realm, invocationContext));
+//        }
+//        return result;
+//    }
+//
+//    @Override
+//    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
+//        return getUserSessions(realm, client).size();
+//    }
+//
+//    @Override
+//    public void removeUserSession(UserSessionModel session) {
+//        getMongoStore().removeEntity(((UserSessionAdapter) session).getMongoEntity(), invocationContext);
+//    }
+//
+//    @Override
+//    public void removeUserSessions(RealmModel realm, UserModel user) {
+//        DBObject query = new BasicDBObject("user", user.getId());
+//        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
+//    }
+//
+//    @Override
+//    public void removeUserSessions(RealmModel realm) {
+//        DBObject query = new BasicDBObject("realmId", realm.getId());
+//        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
+//    }
+//
+//    @Override
+//    public void removeExpiredUserSessions(RealmModel realm) {
+//        int currentTime = Time.currentTime();
+//        DBObject query = new QueryBuilder()
+//                .and("started").lessThan(currentTime - realm.getSsoSessionMaxLifespan())
+//                .get();
+//
+//        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
+//        query = new QueryBuilder()
+//                .and("lastSessionRefresh").lessThan(currentTime - realm.getSsoSessionIdleTimeout())
+//                .get();
+//
+//        getMongoStore().removeEntities(MongoUserSessionEntity.class, query, invocationContext);
+//    }
 }
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 dd62a07..96806a8 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
@@ -18,7 +18,6 @@ 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.entities.AuthenticationProviderEntity;
 import org.keycloak.models.entities.RequiredCredentialEntity;
@@ -63,7 +62,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         super(invocationContext);
         this.realm = realmEntity;
         this.session = session;
-        this.model = session.getModel();
+        this.model = session.model();
     }
 
     @Override
@@ -446,22 +445,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public UsernameLoginFailureModel getUserLoginFailure(String name) {
-        return model.getUserLoginFailure(name, this);
-    }
-
-    @Override
-    public UsernameLoginFailureModel addUserLoginFailure(String username) {
-        return model.addUserLoginFailure(username, this);
-    }
-
-
-    @Override
-    public List<UsernameLoginFailureModel> getAllUserLoginFailures() {
-        return model.getAllUserLoginFailures(this);
-    }
-
-    @Override
     public UserModel getUserByEmail(String email) {
         return model.getUserByEmail(email, this);
     }
@@ -1014,41 +997,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
-    public UserSessionModel createUserSession(UserModel user, String ipAddress) {
-        return model.createUserSession(this, user, ipAddress);
-    }
-
-    @Override
-    public UserSessionModel getUserSession(String id) {
-        return model.getUserSession(id, this);
-    }
-
-    @Override
-    public List<UserSessionModel> getUserSessions(UserModel user) {
-        return model.getUserSessions(user, this);
-    }
-
-    @Override
-    public void removeUserSession(UserSessionModel session) {
-        this.model.removeUserSession(session);
-    }
-
-    @Override
-    public void removeUserSessions(UserModel user) {
-        this.model.removeUserSessions(this, user);
-    }
-
-    @Override
-    public void removeUserSessions() {
-        this.model.removeUserSessions(this);
-    }
-
-    @Override
-    public void removeExpiredUserSessions() {
-        this.model.removeExpiredUserSessions(this);
-    }
-
-    @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || !(o instanceof RealmModel)) return false;

model/pom.xml 12(+7 -5)

diff --git a/model/pom.xml b/model/pom.xml
index 9011480..3fed2c6 100755
--- a/model/pom.xml
+++ b/model/pom.xml
@@ -27,14 +27,16 @@
     <modules>
         <module>api</module>
         <module>invalidation-cache</module>
+        <module>jpa</module>
         <module>mongo</module>
         <module>tests</module>
 
-        <module>hybrid</module>
-        <module>realms-jpa</module>
-        <module>users-jpa</module>
         <module>sessions-mem</module>
-        <module>sessions-jpa</module>
-        <module>tests-hybrid</module>
+
+        <!--<module>hybrid</module>-->
+        <!--<module>realms-jpa</module>-->
+        <!--<module>users-jpa</module>-->
+        <!--<module>sessions-jpa</module>-->
+        <!--<module>tests-hybrid</module>-->
     </modules>
 </project>
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaSessionProviderFactory.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaSessionProviderFactory.java
index c0c0cde..7241a76 100644
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaSessionProviderFactory.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaSessionProviderFactory.java
@@ -29,7 +29,7 @@ public class JpaSessionProviderFactory implements SessionProviderFactory {
 
     @Override
     public SessionProvider create(KeycloakSession session) {
-        return new JpaSessionProvider(emf.createEntityManager());
+        return new JpaUserSessionProvider(emf.createEntityManager());
     }
 
     @Override
diff --git a/model/sessions-mem/pom.xml b/model/sessions-mem/pom.xml
index 322fc5f..84c322e 100755
--- a/model/sessions-mem/pom.xml
+++ b/model/sessions-mem/pom.xml
@@ -27,8 +27,9 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-model-hybrid</artifactId>
+            <artifactId>keycloak-model-tests</artifactId>
             <version>${project.version}</version>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java
new file mode 100644
index 0000000..b1788d2
--- /dev/null
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/UsernameLoginFailureEntity.java
@@ -0,0 +1,65 @@
+package org.keycloak.models.sessions.mem.entities;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class UsernameLoginFailureEntity {
+
+    private String username;
+    private String realm;
+
+    private AtomicInteger failedLoginNotBefore = new AtomicInteger();
+    private AtomicInteger numFailures = new AtomicInteger();
+    private AtomicLong lastFailure = new AtomicLong();
+    private AtomicReference<String> lastIpFailure = new AtomicReference<String>();
+
+    public UsernameLoginFailureEntity(String username, String realm) {
+        this.username = username;
+        this.realm = realm;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getRealm() {
+        return realm;
+    }
+
+    public AtomicInteger getFailedLoginNotBefore() {
+        return failedLoginNotBefore;
+    }
+
+    public void setFailedLoginNotBefore(AtomicInteger failedLoginNotBefore) {
+        this.failedLoginNotBefore = failedLoginNotBefore;
+    }
+
+    public AtomicInteger getNumFailures() {
+        return numFailures;
+    }
+
+    public void setNumFailures(AtomicInteger numFailures) {
+        this.numFailures = numFailures;
+    }
+
+    public AtomicLong getLastFailure() {
+        return lastFailure;
+    }
+
+    public void setLastFailure(AtomicLong lastFailure) {
+        this.lastFailure = lastFailure;
+    }
+
+    public AtomicReference<String> getLastIpFailure() {
+        return lastIpFailure;
+    }
+
+    public void setLastIpFailure(AtomicReference<String> lastIpFailure) {
+        this.lastIpFailure = lastIpFailure;
+    }
+
+}
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
new file mode 100644
index 0000000..45e22cc
--- /dev/null
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
@@ -0,0 +1,244 @@
+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;
+import org.keycloak.models.UserSessionProvider;
+import org.keycloak.models.UsernameLoginFailureModel;
+import org.keycloak.models.sessions.mem.entities.UserSessionEntity;
+import org.keycloak.models.sessions.mem.entities.UserSessionKey;
+import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureEntity;
+import org.keycloak.models.sessions.mem.entities.UsernameLoginFailureKey;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.util.Time;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class MemUserSessionProvider implements UserSessionProvider {
+
+    private final KeycloakSession session;
+    private final ConcurrentHashMap<UserSessionKey, UserSessionEntity> sessions;
+    private final ConcurrentHashMap<UsernameLoginFailureKey, UsernameLoginFailureEntity> loginFailures;
+    private DummyKeycloakTransaction tx;
+
+    public MemUserSessionProvider(KeycloakSession session, ConcurrentHashMap<UserSessionKey, UserSessionEntity> sessions, ConcurrentHashMap<UsernameLoginFailureKey, UsernameLoginFailureEntity> loginFailures) {
+        this.session = session;
+        this.sessions = sessions;
+        this.loginFailures = loginFailures;
+    }
+
+    @Override
+    public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
+        String id = KeycloakModelUtils.generateId();
+
+        UserSessionEntity entity = new UserSessionEntity();
+        entity.setId(id);
+        entity.setRealm(realm.getId());
+        entity.setUser(user.getId());
+        entity.setIpAddress(ipAddress);
+
+        int currentTime = Time.currentTime();
+
+        entity.setStarted(currentTime);
+        entity.setLastSessionRefresh(currentTime);
+
+        sessions.put(new UserSessionKey(realm.getId(), id), entity);
+
+        return new UserSessionAdapter(session, entity);
+    }
+
+    @Override
+    public UserSessionModel getUserSession(RealmModel realm, String id) {
+        UserSessionEntity entity = sessions.get(new UserSessionKey(realm.getId(), id));
+        return entity != null ? new UserSessionAdapter(session, entity) : null;
+    }
+
+    @Override
+    public List<UserSessionModel> getUserSessions(RealmModel realm, UserModel user) {
+        List<UserSessionModel> userSessions = new LinkedList<UserSessionModel>();
+        for (UserSessionEntity s : sessions.values()) {
+            if (s.getRealm().equals(realm.getId()) && s.getUser().equals(user.getId())) {
+                userSessions.add(new UserSessionAdapter(session, s));
+            }
+        }
+        return userSessions;
+    }
+
+    @Override
+    public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
+        Set<UserSessionModel> clientSessions = new HashSet<UserSessionModel>();
+        for (UserSessionEntity s : sessions.values()) {
+            if (s.getRealm().equals(realm.getId()) && s.getClients().contains(client.getClientId())) {
+                clientSessions.add(new UserSessionAdapter(session, s));
+            }
+        }
+        return clientSessions;
+    }
+
+    @Override
+    public int getActiveUserSessions(RealmModel realm, ClientModel client) {
+        int count = 0;
+        for (UserSessionEntity s : sessions.values()) {
+            if (s.getRealm().equals(realm.getId()) && s.getClients().contains(client.getClientId())) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    @Override
+    public void removeUserSession(RealmModel realm, UserSessionModel session) {
+        sessions.remove(new UserSessionKey(realm.getId(), session.getId()));
+    }
+
+    @Override
+    public void removeUserSessions(RealmModel realm, UserModel user) {
+        Iterator<UserSessionEntity> itr = sessions.values().iterator();
+        while (itr.hasNext()) {
+            UserSessionEntity s = itr.next();
+            if (s.getRealm().equals(realm.getId()) && s.getUser().equals(user.getId())) {
+                itr.remove();
+            }
+        }
+    }
+
+    @Override
+    public void removeExpiredUserSessions(RealmModel realm) {
+        Iterator<UserSessionEntity> itr = sessions.values().iterator();
+        while (itr.hasNext()) {
+            UserSessionEntity s = itr.next();
+            if (s.getRealm().equals(realm.getId()) && (s.getLastSessionRefresh() < Time.currentTime() - realm.getSsoSessionIdleTimeout() || s.getStarted() < Time.currentTime() - realm.getSsoSessionMaxLifespan())) {
+                itr.remove();
+            }
+        }
+    }
+
+    @Override
+    public void removeUserSessions(RealmModel realm) {
+        Iterator<UserSessionEntity> itr = sessions.values().iterator();
+        while (itr.hasNext()) {
+            UserSessionEntity s = itr.next();
+            if (s.getRealm().equals(realm.getId())) {
+                itr.remove();
+            }
+        }
+    }
+
+    @Override
+    public UsernameLoginFailureModel getUserLoginFailure(RealmModel realm, String username) {
+        UsernameLoginFailureEntity entity = loginFailures.get(new UsernameLoginFailureKey(username, realm.getId()));
+        return entity != null ? new UsernameLoginFailureAdapter(entity) : null;
+    }
+
+    @Override
+    public UsernameLoginFailureModel addUserLoginFailure(RealmModel realm, String username) {
+        UsernameLoginFailureKey key = new UsernameLoginFailureKey(username, realm.getId());
+        return new UsernameLoginFailureAdapter(loginFailures.putIfAbsent(key, new UsernameLoginFailureEntity(username, realm.getId())));
+    }
+
+    @Override
+    public List<UsernameLoginFailureModel> getAllUserLoginFailures(RealmModel realm) {
+        List<UsernameLoginFailureModel> failures = new LinkedList<UsernameLoginFailureModel>();
+        for (UsernameLoginFailureEntity entity : loginFailures.values()) {
+            if (entity.getRealm().equals(realm.getId())) {
+                failures.add(new UsernameLoginFailureAdapter(entity));
+            }
+        }
+        return failures;
+    }
+
+    @Override
+    public void onRealmRemoved(RealmModel realm) {
+        removeUserSessions(realm);
+
+        Iterator<UsernameLoginFailureEntity> itr = loginFailures.values().iterator();
+        while (itr.hasNext()) {
+            if (itr.next().getRealm().equals(realm.getId())) {
+                itr.remove();
+            }
+        }
+    }
+
+    @Override
+    public void onClientRemoved(RealmModel realm, ClientModel client) {
+        Iterator<UserSessionEntity> itr = sessions.values().iterator();
+        while (itr.hasNext()) {
+            UserSessionEntity s = itr.next();
+            if (s.getRealm().equals(realm.getId())) {
+                itr.remove();
+            }
+        }
+
+        for (UserSessionEntity s : sessions.values()) {
+            if (s.getRealm().equals(realm.getId())) {
+                s.getClients().remove(client.getClientId());
+            }
+        }
+    }
+
+    @Override
+    public void onUserRemoved(RealmModel realm, UserModel user) {
+        removeUserSessions(realm, user);
+
+        loginFailures.remove(new UsernameLoginFailureKey(realm.getId(), user.getUsername()));
+    }
+
+    @Override
+    public KeycloakTransaction getTransaction() {
+        if (tx == null) {
+            tx = new DummyKeycloakTransaction();
+        }
+        return tx;
+    }
+
+    @Override
+    public void close() {
+    }
+
+    public static class DummyKeycloakTransaction implements KeycloakTransaction {
+
+        public boolean rollBackOnly;
+        public boolean active;
+
+        @Override
+        public void begin() {
+            this.active = true;
+        }
+
+        @Override
+        public void commit() {
+        }
+
+        @Override
+        public void rollback() {
+        }
+
+        @Override
+        public void setRollbackOnly() {
+            this.rollBackOnly = true;
+        }
+
+        @Override
+        public boolean getRollbackOnly() {
+            return rollBackOnly;
+        }
+
+        @Override
+        public boolean isActive() {
+            return active;
+        }
+
+    }
+
+}
diff --git a/model/sessions-mem/src/main/resources/META-INF/services/org.keycloak.models.UserSessionProviderFactory b/model/sessions-mem/src/main/resources/META-INF/services/org.keycloak.models.UserSessionProviderFactory
new file mode 100644
index 0000000..a869fa1
--- /dev/null
+++ b/model/sessions-mem/src/main/resources/META-INF/services/org.keycloak.models.UserSessionProviderFactory
@@ -0,0 +1 @@
+org.keycloak.models.sessions.mem.MemUserSessionProviderFactory
\ No newline at end of file
diff --git a/model/sessions-mem/src/test/java/org/keycloak/models/sessions/mem/MemUserSessionProviderTest.java b/model/sessions-mem/src/test/java/org/keycloak/models/sessions/mem/MemUserSessionProviderTest.java
new file mode 100644
index 0000000..da9aec3
--- /dev/null
+++ b/model/sessions-mem/src/test/java/org/keycloak/models/sessions/mem/MemUserSessionProviderTest.java
@@ -0,0 +1,17 @@
+package org.keycloak.models.sessions.mem;
+
+import org.keycloak.model.test.AbstractUserSessionProviderTest;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.UserSessionProvider;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class MemUserSessionProviderTest extends AbstractUserSessionProviderTest {
+
+    @Override
+    public UserSessionProvider createProvider(KeycloakSession session) {
+        return new MemUserSessionProviderFactory().create(session);
+    }
+
+}
diff --git a/model/tests/pom.xml b/model/tests/pom.xml
index 3149597..4f6b938 100755
--- a/model/tests/pom.xml
+++ b/model/tests/pom.xml
@@ -87,6 +87,11 @@
             <scope>compile</scope>
         </dependency>
         <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
             <groupId>org.jboss.resteasy</groupId>
             <artifactId>resteasy-jaxrs</artifactId>
             <scope>provided</scope>
diff --git a/model/tests/src/main/java/org/keycloak/model/test/AbstractUserSessionProviderTest.java b/model/tests/src/main/java/org/keycloak/model/test/AbstractUserSessionProviderTest.java
new file mode 100644
index 0000000..9522abd
--- /dev/null
+++ b/model/tests/src/main/java/org/keycloak/model/test/AbstractUserSessionProviderTest.java
@@ -0,0 +1,152 @@
+package org.keycloak.model.test;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelProvider;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.UserSessionProvider;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public abstract class AbstractUserSessionProviderTest {
+
+    private KeycloakSession session;
+    private UserSessionProvider provider;
+    private RealmModel realm;
+    private UserModel user;
+    private ApplicationModel app1;
+    private ApplicationModel app2;
+    private OAuthClientModel client1;
+    private ModelProvider model;
+
+    @Before
+    public void before() {
+        session = EasyMock.createMock(KeycloakSession.class);
+
+        model = EasyMock.createMock(ModelProvider.class);
+        EasyMock.expect(session.model()).andReturn(model).anyTimes();
+
+        realm = EasyMock.createMock(RealmModel.class);
+        EasyMock.expect(realm.getId()).andReturn("realm-id").anyTimes();
+        EasyMock.expect(realm.getSsoSessionIdleTimeout()).andReturn(1).anyTimes();
+        EasyMock.expect(model.getRealm("realm-id")).andReturn(realm).anyTimes();
+
+        user = EasyMock.createMock(UserModel.class);
+        EasyMock.expect(user.getId()).andReturn("user-id").anyTimes();
+        EasyMock.expect(model.getUserById("user-id", realm)).andReturn(user).anyTimes();
+
+        app1 = EasyMock.createMock(ApplicationModel.class);
+        EasyMock.expect(app1.getClientId()).andReturn("app1").anyTimes();
+        EasyMock.expect(realm.findClient("app1")).andReturn(app1).anyTimes();
+
+        app2 = EasyMock.createMock(ApplicationModel.class);
+        EasyMock.expect(app2.getClientId()).andReturn("app2").anyTimes();
+        EasyMock.expect(realm.findClient("app2")).andReturn(app2).anyTimes();
+
+        client1 = EasyMock.createMock(OAuthClientModel.class);
+        EasyMock.expect(client1.getClientId()).andReturn("client1").anyTimes();
+        EasyMock.expect(realm.findClient("client1")).andReturn(client1).anyTimes();
+
+        EasyMock.replay(session, model, realm, user, app1, app2, client1);
+
+        provider = createProvider(session);
+        provider.getTransaction().begin();
+    }
+
+    @After
+    public void after() {
+        provider.getTransaction().commit();
+
+        provider.getTransaction().begin();
+        provider.onRealmRemoved(realm);
+        provider.getTransaction().commit();
+
+        provider.close();
+    }
+
+    public abstract UserSessionProvider createProvider(KeycloakSession session);
+
+    @Test
+    public void userSessions() throws InterruptedException {
+        UserSessionModel userSession = provider.createUserSession(realm, user, "127.0.0.1");
+        commit();
+
+        assertNotNull(provider.getUserSession(realm, userSession.getId()));
+        commit();
+
+        provider.removeUserSession(realm, provider.getUserSession(realm, userSession.getId()));
+        commit();
+
+        assertNull(provider.getUserSession(realm, userSession.getId()));
+
+        userSession = provider.createUserSession(realm, user, "127.0.0.1");
+        commit();
+
+        provider.removeUserSessions(realm, user);
+        commit();
+
+        assertNull(provider.getUserSession(realm, userSession.getId()));
+
+        userSession = provider.createUserSession(realm, user, "127.0.0.1");
+        commit();
+
+        Thread.sleep(2000);
+
+        provider.removeExpiredUserSessions(realm);
+        commit();
+
+        assertNull(provider.getUserSession(realm, userSession.getId()));
+    }
+
+    @Test
+    public void userSessionAssociations() {
+        UserSessionModel userSession = provider.createUserSession(realm, user, "127.0.0.1");
+
+        assertEquals(0, userSession.getClientAssociations().size());
+
+        userSession.associateClient(app1);
+        userSession.associateClient(client1);
+
+        assertEquals(2, userSession.getClientAssociations().size());
+        assertTrue(provider.getUserSessions(realm, app1).contains(userSession));
+        assertFalse(provider.getUserSessions(realm, app2).contains(userSession));
+        assertTrue(provider.getUserSessions(realm, client1).contains(userSession));
+
+        commit();
+
+        userSession = provider.getUserSession(realm, userSession.getId());
+
+        userSession.removeAssociatedClient(app1);
+        assertEquals(1, userSession.getClientAssociations().size());
+        assertEquals(client1, userSession.getClientAssociations().get(0));
+        assertFalse(provider.getUserSessions(realm, app1).contains(userSession));
+
+        commit();
+
+        userSession = provider.getUserSession(realm, userSession.getId());
+
+        userSession.removeAssociatedClient(client1);
+        assertEquals(0, userSession.getClientAssociations().size());
+        assertFalse(provider.getUserSessions(realm, client1).contains(userSession));
+    }
+
+    public void commit() {
+        provider.getTransaction().commit();
+        provider.getTransaction().begin();
+    }
+
+}
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 5f1063d..4fed6ac 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
@@ -56,7 +56,7 @@ public class AbstractModelTest {
     public void before() throws Exception {
         session = sessionFactory.create();
         session.getTransaction().begin();
-        model = session.getModel();
+        model = session.model();
         realmManager = new RealmManager(session);
     }
 
@@ -68,7 +68,7 @@ public class AbstractModelTest {
         session = sessionFactory.create();
         try {
             session.getTransaction().begin();
-            model = session.getModel();
+            model = session.model();
 
             RealmManager rm = new RealmManager(session);
             for (RealmModel realm : model.getRealms()) {
@@ -102,7 +102,7 @@ public class AbstractModelTest {
 
         session = sessionFactory.create();
         session.getTransaction().begin();
-        model = session.getModel();
+        model = session.model();
         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 3109fd3..7593ae5 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
@@ -17,6 +17,7 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.UserSessionProvider;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
@@ -732,88 +733,4 @@ public class AdapterTest extends AbstractModelTest {
         resetSession();
     }
 
-    @Test
-    public void userSessions() throws InterruptedException {
-        realmManager.createRealm("userSessions");
-        realmManager.getRealmByName("userSessions").setSsoSessionIdleTimeout(5);
-
-        UserModel user = realmManager.getRealmByName("userSessions").addUser("userSessions1");
-
-        UserSessionModel userSession = realmManager.getRealmByName("userSessions").createUserSession(user, "127.0.0.1");
-        commit();
-
-        assertNotNull(realmManager.getRealmByName("userSessions").getUserSession(userSession.getId()));
-        commit();
-
-        realmManager.getRealmByName("userSessions").removeUserSession(realmManager.getRealmByName("userSessions").getUserSession(userSession.getId()));
-        commit();
-
-        assertNull(realmManager.getRealmByName("userSessions").getUserSession(userSession.getId()));
-
-        userSession = realmManager.getRealmByName("userSessions").createUserSession(user, "127.0.0.1");
-        commit();
-
-        realmManager.getRealmByName("userSessions").removeUserSessions(user);
-        commit();
-
-        assertNull(realmManager.getRealmByName("userSessions").getUserSession(userSession.getId()));
-
-        realmManager.getRealmByName("userSessions").setSsoSessionIdleTimeout(1);
-
-        userSession = realmManager.getRealmByName("userSessions").createUserSession(user, "127.0.0.1");
-        commit();
-
-        Thread.sleep(2000);
-
-        realmManager.getRealmByName("userSessions").removeExpiredUserSessions();
-        commit();
-
-        assertNull(realmManager.getRealmByName("userSessions").getUserSession(userSession.getId()));
-    }
-
-    @Test
-    public void userSessionAssociations() {
-        RealmModel realm = realmManager.createRealm("userSessions");
-        UserModel user = realm.addUser("userSessions1");
-        UserSessionModel userSession = realm.createUserSession(user, "127.0.0.1");
-
-        ApplicationModel app1 = realm.addApplication("app1");
-        ApplicationModel app2 = realm.addApplication("app2");
-        OAuthClientModel client1 = realm.addOAuthClient("client1");
-
-        Assert.assertEquals(0, userSession.getClientAssociations().size());
-
-        userSession.associateClient(app1);
-        userSession.associateClient(client1);
-
-        Assert.assertEquals(2, userSession.getClientAssociations().size());
-        Assert.assertTrue(app1.getUserSessions().contains(userSession));
-        Assert.assertFalse(app2.getUserSessions().contains(userSession));
-        Assert.assertTrue(client1.getUserSessions().contains(userSession));
-
-        commit();
-
-        // Refresh all
-        realm = realmManager.getRealm("userSessions");
-        userSession = realm.getUserSession(userSession.getId());
-        app1 = realm.getApplicationByName("app1");
-        client1 = realm.getOAuthClient("client1");
-
-        userSession.removeAssociatedClient(app1);
-        Assert.assertEquals(1, userSession.getClientAssociations().size());
-        Assert.assertEquals(client1, userSession.getClientAssociations().get(0));
-        Assert.assertFalse(app1.getUserSessions().contains(userSession));
-
-        commit();
-
-        // Refresh all
-        realm = realmManager.getRealm("userSessions");
-        userSession = realm.getUserSession(userSession.getId());
-        client1 = realm.getOAuthClient("client1");
-
-        userSession.removeAssociatedClient(client1);
-        Assert.assertEquals(0, userSession.getClientAssociations().size());
-        Assert.assertFalse(client1.getUserSessions().contains(userSession));
-    }
-
 }
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 0e7511e..5c18625 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
@@ -51,7 +51,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
 
     @Test
     public void authForm() {
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
     }
 
@@ -60,7 +60,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
         formData.remove(CredentialRepresentation.PASSWORD);
         formData.add(CredentialRepresentation.PASSWORD, "invalid");
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
     }
 
@@ -68,7 +68,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
     public void authFormMissingUsername() {
         formData.remove("username");
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.INVALID_USER, status);
     }
 
@@ -76,7 +76,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
     public void authFormMissingPassword() {
         formData.remove(CredentialRepresentation.PASSWORD);
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
     }
 
@@ -85,7 +85,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
         realm.addRequiredCredential(CredentialRepresentation.TOTP);
         user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
     }
 
@@ -93,7 +93,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
     public void authFormUserDisabled() {
         user.setEnabled(false);
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
     }
 
@@ -115,7 +115,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
 
         formData.add(CredentialRepresentation.TOTP, token);
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
     }
 
@@ -126,7 +126,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
         formData.remove(CredentialRepresentation.PASSWORD);
         formData.add(CredentialRepresentation.PASSWORD, "invalid");
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
     }
 
@@ -137,7 +137,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
         formData.remove(CredentialRepresentation.TOTP);
         formData.add(CredentialRepresentation.TOTP, "invalid");
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
     }
 
@@ -147,7 +147,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
 
         formData.remove(CredentialRepresentation.TOTP);
 
-        AuthenticationStatus status = am.authenticateForm(dummyConnection, realm, formData);
+        AuthenticationStatus status = am.authenticateForm(session, dummyConnection, realm, formData);
         Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
     }
 
@@ -166,7 +166,7 @@ public class AuthenticationManagerTest extends AbstractModelTest {
         realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
         protector = new BruteForceProtector(sessionFactory);
         protector.start();
-        am = new AuthenticationManager(session, protector);
+        am = new AuthenticationManager(protector);
 
         user = realm.addUser("test");
         user.setEnabled(true);
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 f2b3a77..12c11c9 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
@@ -65,7 +65,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
         credential.setValue("password");
         john.updateCredential(credential);
 
-        am = new AuthenticationManager(session);
+        am = new AuthenticationManager();
     }
 
 
@@ -74,10 +74,10 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
         MultivaluedMap<String, String> formData = createFormData("john", "password");
 
         // Authenticate user with realm1
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm1, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm1, formData));
 
         // Verify that user doesn't exists in realm2 and can't authenticate here
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(null, realm2, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm2, formData));
         Assert.assertNull(realm2.getUser("john"));
 
         // Add externalModel authenticationProvider into realm2 and point to realm1
@@ -88,7 +88,7 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
             ResteasyProviderFactory.pushContext(KeycloakSession.class, session);
 
             // Authenticate john in realm2 and verify that now he exists here.
-            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm2, formData));
+            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm2, formData));
             UserModel john2 = realm2.getUser("john");
             Assert.assertNotNull(john2);
             Assert.assertEquals("john", john2.getUsername());
@@ -130,8 +130,8 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
                 Assert.fail("Error not expected");
             }
             MultivaluedMap<String, String> formData = createFormData("john", "password-updated");
-            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm1, formData));
-            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm2, formData));
+            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm1, formData));
+            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm2, formData));
 
 
             // Switch to disallow password update propagation to realm1
@@ -145,8 +145,8 @@ public class AuthProvidersExternalModelTest extends AbstractModelTest {
                 Assert.fail("Error not expected");
             }
             formData = createFormData("john", "password-updated2");
-            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm1, formData));
-            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm2, formData));
+            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm1, formData));
+            Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm2, formData));
 
 
             // Allow passwordUpdate propagation again
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 10383de..ae927f8 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
@@ -68,7 +68,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
         realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
         this.embeddedServer.setupLdapInRealm(realm);
 
-        am = new AuthenticationManager(session);
+        am = new AuthenticationManager();
     }
 
     @Test
@@ -79,14 +79,14 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
         LDAPTestUtils.setLdapPassword(session, realm, "johnkeycloak", "password");
 
         // Verify that user doesn't exists in realm2 and can't authenticate here
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm, formData));
         Assert.assertNull(realm.getUser("johnkeycloak"));
 
         // Add ldap authenticationProvider
         setupAuthenticationProviders();
 
         // Authenticate john and verify that now he exists in realm
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
         UserModel john = realm.getUser("johnkeycloak");
         Assert.assertNotNull(john);
         Assert.assertEquals("johnkeycloak", john.getUsername());
@@ -114,25 +114,25 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
 
         // User doesn't exists
         MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("invalid", "invalid");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_USER, am.authenticateForm(session, null, realm, formData));
 
         // User exists in ldap
         formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "invalid");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm, formData));
 
         // User exists in realm
         formData = AuthProvidersExternalModelTest.createFormData("realmUser", "invalid");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm, formData));
 
         // User disabled
         realmUser.setEnabled(false);
         formData = AuthProvidersExternalModelTest.createFormData("realmUser", "pass");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.ACCOUNT_DISABLED, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.ACCOUNT_DISABLED, am.authenticateForm(session, null, realm, formData));
 
         // Successful authentication
         realmUser.setEnabled(true);
         formData = AuthProvidersExternalModelTest.createFormData("realmUser", "pass");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
     }
 
     @Test
@@ -144,7 +144,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
 
         // First authenticate successfully to sync john into realm
         MultivaluedMap<String, String> formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
 
         // Change credential and validate that user can authenticate
         AuthenticationProviderManager authProviderManager = AuthenticationProviderManager.getManager(realm, session);
@@ -157,7 +157,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
             Assert.fail("Error not expected");
         }
         formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password-updated");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.SUCCESS, am.authenticateForm(session, null, realm, formData));
 
         // Password updated just in LDAP, so validating directly in realm should fail
         Assert.assertFalse(realm.validatePassword(john, "password-updated"));
@@ -173,7 +173,7 @@ public class AuthProvidersLDAPTest extends AbstractModelTest {
             Assert.fail("Error not expected");
         }
         formData = AuthProvidersExternalModelTest.createFormData("johnkeycloak", "password-updated2");
-        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(null, realm, formData));
+        Assert.assertEquals(AuthenticationManager.AuthenticationStatus.INVALID_CREDENTIALS, am.authenticateForm(session, null, realm, formData));
     }
 
     /**

pom.xml 6(+6 -0)

diff --git a/pom.xml b/pom.xml
index 0e187f8..e92e9db 100755
--- a/pom.xml
+++ b/pom.xml
@@ -269,6 +269,12 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.easymock</groupId>
+                <artifactId>easymock</artifactId>
+                <version>3.2</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
                 <groupId>org.hibernate.javax.persistence</groupId>
                 <artifactId>hibernate-jpa-2.0-api</artifactId>
                 <version>${hibernate.javax.persistence.version}</version>

server/pom.xml 5(+5 -0)

diff --git a/server/pom.xml b/server/pom.xml
index 2d8e61d..89423cf 100755
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -54,6 +54,11 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-sessions-mem</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
             <artifactId>keycloak-audit-api</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/server/src/main/resources/META-INF/keycloak-server.json b/server/src/main/resources/META-INF/keycloak-server.json
index 7e3f246..8dc062e 100755
--- a/server/src/main/resources/META-INF/keycloak-server.json
+++ b/server/src/main/resources/META-INF/keycloak-server.json
@@ -14,6 +14,10 @@
         "provider": "jpa"
     },
 
+    "userSessions": {
+        "provider" : "mem"
+    },
+
     "modelCache": {
         "provider": "${keycloak.model.cache.provider:}"
     },
diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
index 99db9b1..e26cd74 100755
--- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
+++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
@@ -3,6 +3,7 @@ package org.keycloak.services;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.ModelProvider;
+import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.cache.CacheModelProvider;
 import org.keycloak.provider.Provider;
 import org.keycloak.provider.ProviderFactory;
@@ -75,10 +76,15 @@ public class DefaultKeycloakSession implements KeycloakSession {
         return providers;
     }
 
-    public ModelProvider getModel() {
+    public ModelProvider model() {
         return model;
     }
 
+    @Override
+    public UserSessionProvider sessions() {
+        return getProvider(UserSessionProvider.class);
+    }
+
     public void close() {
         for (Provider p : providers.values()) {
             p.close();
diff --git a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
index f73d30d..69dc76f 100755
--- a/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AppAuthManager.java
@@ -14,15 +14,12 @@ import javax.ws.rs.core.UriInfo;
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class AppAuthManager extends AuthenticationManager {
-    protected static Logger logger = Logger.getLogger(AppAuthManager.class);
 
-    public AppAuthManager(KeycloakSession session) {
-        super(session);
-    }
+    protected static Logger logger = Logger.getLogger(AppAuthManager.class);
 
     @Override
-    public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
-        AuthResult authResult = super.authenticateIdentityCookie(realm, uriInfo, headers);
+    public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
+        AuthResult authResult = super.authenticateIdentityCookie(session, realm, uriInfo, headers);
         if (authResult == null) return null;
         Cookie remember = headers.getCookies().get(AuthenticationManager.KEYCLOAK_REMEMBER_ME);
         boolean rememberMe = remember != null;
@@ -44,10 +41,10 @@ public class AppAuthManager extends AuthenticationManager {
         return tokenString;
     }
 
-    public AuthResult authenticateBearerToken(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
+    public AuthResult authenticateBearerToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
         String tokenString = extractAuthorizationHeaderToken(headers);
         if (tokenString == null) return null;
-        AuthResult authResult = verifyIdentityToken(realm, uriInfo, true, tokenString);
+        AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, true, tokenString);
         return authResult;
     }
 
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 76f1376..56cee64 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -8,7 +8,6 @@ import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
@@ -40,7 +39,7 @@ public class ApplianceBootstrap {
 
     public void bootstrap(KeycloakSession session, String contextPath) {
         String adminRealmName = Config.getAdminRealm();
-        if (session.getModel().getRealm(adminRealmName) != null) {
+        if (session.model().getRealm(adminRealmName) != null) {
             return;
         }
 
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index 49a1ab5..1f186b1 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -10,6 +10,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionProvider;
 import org.keycloak.representations.adapters.config.BaseRealmConfig;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
@@ -150,6 +151,18 @@ public class ApplicationManager {
         return app;
     }
 
+    public boolean removeApplication(RealmModel realm, ApplicationModel application) {
+        if (realm.removeApplication(application.getId())) {
+            UserSessionProvider sessions = realmManager.getSession().sessions();
+            if (sessions != null) {
+                sessions.onClientRemoved(realm, application);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     public UserCredentialModel generateSecret(ApplicationModel app) {
         UserCredentialModel secret = UserCredentialModel.generateSecret();
         app.setSecret(secret.getValue());
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 96aab65..c179812 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -45,37 +45,34 @@ public class AuthenticationManager {
     public static final String KEYCLOAK_SESSION_COOKIE = "KEYCLOAK_SESSION";
     public static final String KEYCLOAK_REMEMBER_ME = "KEYCLOAK_REMEMBER_ME";
 
-    protected KeycloakSession session;
     protected BruteForceProtector protector;
 
-    public AuthenticationManager(KeycloakSession session) {
-        this.session = session;
+    public AuthenticationManager() {
     }
 
-    public AuthenticationManager(KeycloakSession session, BruteForceProtector protector) {
-        this.session = session;
+    public AuthenticationManager(BruteForceProtector protector) {
         this.protector = protector;
     }
 
-    public static boolean isSessionValid(RealmModel realm, UserSessionModel session) {
-        if (session == null) return false;
+    public static boolean isSessionValid(RealmModel realm, UserSessionModel userSession) {
+        if (userSession == null) return false;
         int currentTime = Time.currentTime();
-        int max = session.getStarted() + realm.getSsoSessionMaxLifespan();
-        boolean valid = session != null && session.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime;
+        int max = userSession.getStarted() + realm.getSsoSessionMaxLifespan();
+        boolean valid = userSession != null && userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime;
         return valid;
     }
 
-    public static void logout(RealmModel realm, UserSessionModel session, UriInfo uriInfo) {
-        if (session == null) return;
-        UserModel user = session.getUser();
+    public static void logout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo) {
+        if (userSession == null) return;
+        UserModel user = userSession.getUser();
 
-        logger.infov("Logging out: {0} ({1})", user.getUsername(), session.getId());
+        logger.infov("Logging out: {0} ({1})", user.getUsername(), userSession.getId());
 
-        realm.removeUserSession(session);
+        session.sessions().removeUserSession(realm, userSession);
         expireIdentityCookie(realm, uriInfo);
         expireRememberMeCookie(realm, uriInfo);
 
-        new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), session.getId());
+        new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), userSession.getId());
 
     }
 
@@ -161,11 +158,11 @@ public class AuthenticationManager {
         CookieHelper.addCookie(cookieName, "", path, null, "Expiring cookie", 0, secureOnly, httpOnly);
     }
 
-    public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
-        return authenticateIdentityCookie(realm, uriInfo, headers, true);
+    public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
+        return authenticateIdentityCookie(session, realm, uriInfo, headers, true);
     }
 
-    public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers, boolean checkActive) {
+    public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, boolean checkActive) {
         logger.info("authenticateIdentityCookie");
         Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE);
         if (cookie == null) {
@@ -174,7 +171,7 @@ public class AuthenticationManager {
         }
 
         String tokenString = cookie.getValue();
-        AuthResult authResult = verifyIdentityToken(realm, uriInfo, checkActive, tokenString);
+        AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, checkActive, tokenString);
         if (authResult == null) {
             expireIdentityCookie(realm, uriInfo);
             return null;
@@ -183,7 +180,7 @@ public class AuthenticationManager {
         return authResult;
     }
 
-    protected AuthResult verifyIdentityToken(RealmModel realm, UriInfo uriInfo, boolean checkActive, String tokenString) {
+    protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, boolean checkActive, String tokenString) {
         try {
             AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
             logger.info("identity token verified");
@@ -205,21 +202,21 @@ public class AuthenticationManager {
                 return null;
             }
 
-            UserSessionModel session = realm.getUserSession(token.getSessionState());
-            if (!isSessionValid(realm, session)) {
-                if (session != null) logout(realm, session, uriInfo);
+            UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState());
+            if (!isSessionValid(realm, userSession)) {
+                if (userSession != null) logout(session, realm, userSession, uriInfo);
                 logger.info("User session not active");
                 return null;
             }
 
-            return new AuthResult(user, session, token);
+            return new AuthResult(user, userSession, token);
         } catch (VerificationException e) {
             logger.info("Failed to verify identity token", e);
         }
         return null;
     }
 
-    public AuthenticationStatus authenticateForm(ClientConnection clientConnection, RealmModel realm, MultivaluedMap<String, String> formData) {
+    public AuthenticationStatus authenticateForm(KeycloakSession session, ClientConnection clientConnection, RealmModel realm, MultivaluedMap<String, String> formData) {
         String username = formData.getFirst(FORM_USERNAME);
         if (username == null) {
             logger.warn("Username not provided");
@@ -227,12 +224,12 @@ public class AuthenticationManager {
         }
 
         if (realm.isBruteForceProtected()) {
-            if (protector.isTemporarilyDisabled(realm, username)) {
+            if (protector.isTemporarilyDisabled(session, realm, username)) {
                 return AuthenticationStatus.ACCOUNT_TEMPORARILY_DISABLED;
             }
         }
 
-        AuthenticationStatus status = authenticateInternal(realm, formData, username);
+        AuthenticationStatus status = authenticateInternal(session, realm, formData, username);
         if (realm.isBruteForceProtected()) {
             switch (status) {
                 case SUCCESS:
@@ -255,7 +252,7 @@ public class AuthenticationManager {
         return status;
     }
 
-    protected AuthenticationStatus authenticateInternal(RealmModel realm, MultivaluedMap<String, String> formData, String username) {
+    protected AuthenticationStatus authenticateInternal(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, String username) {
         UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
         if (user == null) {
             AuthUser authUser = AuthenticationProviderManager.getManager(realm, session).getUser(username);
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 09593b8..69fdab1 100755
--- a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
+++ b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java
@@ -83,7 +83,7 @@ public class BruteForceProtector implements Runnable {
         logFailure(event);
         UsernameLoginFailureModel user = getUserModel(session, event);
         if (user == null) {
-            user = realm.addUserLoginFailure(event.username);
+            user = session.sessions().addUserLoginFailure(realm, event.username);
         }
         user.setLastIPFailure(event.ip);
         long currentTime = System.currentTimeMillis();
@@ -122,13 +122,13 @@ public class BruteForceProtector implements Runnable {
     protected UsernameLoginFailureModel getUserModel(KeycloakSession session, LoginEvent event) {
         RealmModel realm = getRealmModel(session, event);
         if (realm == null) return null;
-        UsernameLoginFailureModel user = realm.getUserLoginFailure(event.username);
+        UsernameLoginFailureModel user = session.sessions().getUserLoginFailure(realm, event.username);
         if (user == null) return null;
         return user;
     }
 
     protected RealmModel getRealmModel(KeycloakSession session, LoginEvent event) {
-        RealmModel realm = session.getModel().getRealm(event.realmId);
+        RealmModel realm = session.model().getRealm(event.realmId);
         if (realm == null) return null;
         return realm;
     }
@@ -237,8 +237,8 @@ public class BruteForceProtector implements Runnable {
         }
     }
 
-    public boolean isTemporarilyDisabled(RealmModel realm, String username) {
-        UsernameLoginFailureModel failure = realm.getUserLoginFailure(username);
+    public boolean isTemporarilyDisabled(KeycloakSession session, RealmModel realm, String username) {
+        UsernameLoginFailureModel failure = session.sessions().getUserLoginFailure(realm, username);
         if (failure == null) {
             return false;
         }
diff --git a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
index 56559cb..df13eb4 100755
--- a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -2,9 +2,11 @@ package org.keycloak.services.managers;
 
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.annotate.JsonPropertyOrder;
+import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserSessionProvider;
 import org.keycloak.representations.adapters.config.BaseRealmConfig;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
@@ -22,12 +24,18 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class OAuthClientManager {
+
+    private RealmManager realmManager;
     protected RealmModel realm;
 
     public OAuthClientManager(RealmModel realm) {
         this.realm = realm;
     }
 
+    public OAuthClientManager(RealmManager realmManager) {
+        this.realmManager = realmManager;
+    }
+
     public UserCredentialModel generateSecret(OAuthClientModel app) {
         UserCredentialModel secret = UserCredentialModel.generateSecret();
         app.setSecret(secret.getValue());
@@ -47,6 +55,18 @@ public class OAuthClientManager {
         return model;
     }
 
+    public boolean removeClient(RealmModel realm, OAuthClientModel client) {
+        if (realm.removeOAuthClient(client.getId())) {
+            UserSessionProvider sessions = realmManager.getSession().sessions();
+            if (sessions != null) {
+                realmManager.getSession().sessions().onClientRemoved(realm, client);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
         if (rep.getName() != null) model.setClientId(rep.getName());
         if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
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 e4359d2..29cc8b2 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -19,6 +19,7 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
@@ -31,7 +32,6 @@ import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.ScopeMappingRepresentation;
 import org.keycloak.representations.idm.SocialLinkRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.representations.idm.UserRoleMappingRepresentation;
 
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
@@ -67,7 +67,11 @@ public class RealmManager {
 
     public RealmManager(KeycloakSession session) {
         this.session = session;
-        this.model = session.getModel();
+        this.model = session.model();
+    }
+
+    public KeycloakSession getSession() {
+        return session;
     }
 
     public RealmModel getKeycloakAdminstrationRealm() {
@@ -148,7 +152,12 @@ public class RealmManager {
     public boolean removeRealm(RealmModel realm) {
         boolean removed = model.removeRealm(realm.getId());
         if (removed) {
-            getKeycloakAdminstrationRealm().removeApplication(realm.getMasterAdminApp().getId());
+            new ApplicationManager(this).removeApplication(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp());
+
+            UserSessionProvider sessions = session.sessions();
+            if (sessions != null) {
+                sessions.onRealmRemoved(realm);
+            }
         }
         return removed;
     }
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 73270e9..6ab2b75 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -11,6 +11,7 @@ import org.keycloak.jose.jws.crypto.RSAProvider;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClaimMask;
 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;
@@ -26,14 +27,12 @@ import org.keycloak.util.Time;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.UriInfo;
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Stateful object that creates tokens and manages oauth access codes
@@ -44,22 +43,6 @@ import java.util.concurrent.ConcurrentHashMap;
 public class TokenManager {
     protected static final Logger logger = Logger.getLogger(TokenManager.class);
 
-    /*
-    protected Map<String, AccessCodeEntry> accessCodeMap = new ConcurrentHashMap<String, AccessCodeEntry>();
-
-    public void clearAccessCodes() {
-        accessCodeMap.clear();
-    }
-
-    public AccessCodeEntry getAccessCode(String key) {
-        return accessCodeMap.get(key);
-    }
-
-    public AccessCodeEntry pullAccessCode(String key) {
-        return accessCodeMap.remove(key);
-    }
-    */
-
     public AccessCodeEntry parseCode(String code, RealmModel realm) {
         try {
             JWSInput input = new JWSInput(code);
@@ -114,7 +97,7 @@ public class TokenManager {
 
     }
 
-    public AccessToken refreshAccessToken(UriInfo uriInfo, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException {
+    public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException {
         JWSInput jws = new JWSInput(encodedRefreshToken);
         RefreshToken refreshToken = null;
         try {
@@ -144,10 +127,10 @@ public class TokenManager {
             throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "User disabled", "User disabled");
         }
 
-        UserSessionModel session = realm.getUserSession(refreshToken.getSessionState());
+        UserSessionModel userSession = session.sessions().getUserSession(realm, refreshToken.getSessionState());
         int currentTime = Time.currentTime();
-        if (!AuthenticationManager.isSessionValid(realm, session)) {
-            AuthenticationManager.logout(realm, session, uriInfo);
+        if (!AuthenticationManager.isSessionValid(realm, userSession)) {
+            AuthenticationManager.logout(session, realm, userSession, uriInfo);
             throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session not active", "Session not active");
         }
 
@@ -198,13 +181,13 @@ public class TokenManager {
             }
         }
 
-        AccessToken accessToken = initToken(realm, client, user, session);
+        AccessToken accessToken = initToken(realm, client, user, userSession);
         accessToken.setRealmAccess(refreshToken.getRealmAccess());
         accessToken.setResourceAccess(refreshToken.getResourceAccess());
 
         // only refresh session if next token refresh will be after idle timeout
-        if (currentTime + realm.getAccessTokenLifespan() > session.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout()) {
-            session.setLastSessionRefresh(currentTime);
+        if (currentTime + realm.getAccessTokenLifespan() > userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout()) {
+            userSession.setLastSessionRefresh(currentTime);
         }
 
         return accessToken;
diff --git a/services/src/main/java/org/keycloak/services/managers/UserManager.java b/services/src/main/java/org/keycloak/services/managers/UserManager.java
new file mode 100644
index 0000000..4a18d30
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/UserManager.java
@@ -0,0 +1,30 @@
+package org.keycloak.services.managers;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionProvider;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class UserManager {
+
+    private KeycloakSession session;
+
+    public UserManager(KeycloakSession session) {
+        this.session = session;
+    }
+
+    public boolean removeUser(RealmModel realm, UserModel user) {
+        if (realm.removeUser(user.getUsername())) {
+            UserSessionProvider sessions = session.sessions();
+            if (sessions != null) {
+                sessions.onUserRemoved(realm, user);
+            }
+            return true;
+        }
+        return false;
+    }
+
+}
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 2bf2dbd..68fe12f 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -132,7 +132,7 @@ public class AccountService {
         this.realm = realm;
         this.application = application;
         this.audit = audit;
-        this.authManager = new AppAuthManager(session);
+        this.authManager = new AppAuthManager();
     }
 
     public void init() {
@@ -141,11 +141,11 @@ public class AccountService {
         account = session.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(uriInfo);
 
         boolean passwordUpdateSupported = false;
-        AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
+        AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers);
         if (authResult != null) {
             auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, true);
         } else {
-            authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
+            authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
             if (authResult != null) {
                 auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, false);
             }
@@ -288,7 +288,7 @@ public class AccountService {
     @GET
     public Response sessionsPage() {
         if (auth != null) {
-            account.setSessions(realm.getUserSessions(auth.getUser()));
+            account.setSessions(session.sessions().getUserSessions(realm, auth.getUser()));
         }
         return forwardToPage("sessions", AccountPages.SESSIONS);
     }
@@ -369,7 +369,7 @@ public class AccountService {
         require(AccountRoles.MANAGE_ACCOUNT);
 
         UserModel user = auth.getUser();
-        realm.removeUserSessions(user);
+        session.sessions().removeUserSessions(realm, user);
 
         return Response.seeOther(Urls.accountSessionsPage(uriInfo.getBaseUri(), realm.getName())).build();
     }
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 d3f6920..e9c5a10 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
@@ -12,7 +12,6 @@ import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -79,7 +78,7 @@ public class AdminConsole {
 
     public AdminConsole(RealmModel realm) {
         this.realm = realm;
-        this.authManager = new AppAuthManager(session);
+        this.authManager = new AppAuthManager();
     }
 
     public static class WhoAmI {
@@ -174,7 +173,7 @@ public class AdminConsole {
     @NoCache
     public Response whoAmI(final @Context HttpHeaders headers) {
         RealmManager realmManager = new RealmManager(session);
-        AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
+        AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
         if (authResult == null) {
             return Response.status(401).build();
         }
@@ -225,7 +224,7 @@ public class AdminConsole {
     }
 
     private void addMasterRealmAccess(RealmModel masterRealm, UserModel user, Map<String, Set<String>> realmAdminAccess) {
-        List<RealmModel> realms = session.getModel().getRealms();
+        List<RealmModel> realms = session.model().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/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index 98a29f4..07c7525 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -55,7 +55,7 @@ public class AdminRoot {
 
     public AdminRoot(TokenManager tokenManager) {
         this.tokenManager = tokenManager;
-        this.authManager = new AppAuthManager(null);
+        this.authManager = new AppAuthManager();
     }
 
     public static UriBuilder adminBaseUrl(UriInfo uriInfo) {
@@ -142,7 +142,7 @@ public class AdminRoot {
         if (realm == null) {
             throw new UnauthorizedException("Unknown realm in token");
         }
-        AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(realm, uriInfo, headers);
+        AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
         if (authResult == null) {
             logger.debug("Token not valid");
             throw new UnauthorizedException("Bearer");
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 9f4527b..6814ae8 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
@@ -167,7 +167,7 @@ public class ApplicationResource {
     public void deleteApplication() {
         auth.requireManage();
 
-        realm.removeApplication(application.getId());
+        new ApplicationManager(new RealmManager(session)).removeApplication(realm, application);
     }
 
 
@@ -327,7 +327,7 @@ public class ApplicationResource {
     public Map<String, Integer> getApplicationSessionCount() {
         auth.requireView();
         Map<String, Integer> map = new HashMap<String, Integer>();
-        map.put("count", application.getActiveUserSessions());
+        map.put("count", session.sessions().getActiveUserSessions(application.getRealm(), application));
         return map;
     }
 
@@ -343,8 +343,8 @@ public class ApplicationResource {
     public List<UserSessionRepresentation> getUserSessions() {
         auth.requireView();
         List<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
-        for (UserSessionModel session : application.getUserSessions()) {
-            UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
+        for (UserSessionModel userSession : session.sessions().getUserSessions(application.getRealm(), application)) {
+            UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession);
             sessions.add(rep);
         }
         return sessions;
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 ac318b6..d8b6d65 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
@@ -12,6 +12,7 @@ import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.OAuthClientManager;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.util.JsonSerialization;
@@ -133,7 +134,7 @@ public class OAuthClientResource  {
     public void deleteOAuthClient() {
         auth.requireManage();
 
-        realm.removeOAuthClient(oauthClient.getId());
+        new OAuthClientManager(new RealmManager(session)).removeClient(realm, oauthClient);
     }
 
 
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 1009812..b924349 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
@@ -204,7 +204,7 @@ public class RealmAdminResource {
     @POST
     public void logoutAll() {
         auth.requireManage();
-        realm.removeUserSessions();
+        session.sessions().removeUserSessions(realm);
         new ResourceAdminManager().logoutAll(uriInfo.getRequestUri(), realm);
     }
 
@@ -217,10 +217,10 @@ public class RealmAdminResource {
     @Path("sessions/{session}")
     @DELETE
     public void deleteSession(@PathParam("session") String sessionId) {
-        UserSessionModel session = realm.getUserSession(sessionId);
-        if (session == null) throw new NotFoundException("Sesssion not found");
-        realm.removeUserSession(session);
-        new ResourceAdminManager().logoutSession(uriInfo.getRequestUri(), realm, session.getId());
+        UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
+        if (userSession == null) throw new NotFoundException("Sesssion not found");
+        session.sessions().removeUserSession(realm, userSession);
+        new ResourceAdminManager().logoutSession(uriInfo.getRequestUri(), realm, userSession.getId());
     }
 
     /**
@@ -236,10 +236,10 @@ public class RealmAdminResource {
     public Map<String, Integer> getApplicationSessionStats() {
         auth.requireView();
         Map<String, Integer> stats = new HashMap<String, Integer>();
-        for (ApplicationModel applicationModel : realm.getApplications()) {
-            int size = applicationModel.getActiveUserSessions();
+        for (ApplicationModel application : realm.getApplications()) {
+            int size = session.sessions().getActiveUserSessions(application.getRealm(), application);
             if (size == 0) continue;
-            stats.put(applicationModel.getName(), size);
+            stats.put(application.getName(), size);
         }
         return stats;
     }
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 e566206..35f8176 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
@@ -6,7 +6,6 @@ import org.jboss.resteasy.plugins.providers.multipart.InputPart;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.jboss.resteasy.util.GenericType;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
@@ -15,7 +14,6 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.ForbiddenException;
-import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
@@ -87,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.getModel().getRealms();
+            List<RealmModel> realms = session.model().getRealms();
             for (RealmModel realm : realms) {
                 addRealmRep(reps, realm, realm.getMasterAdminApp());
             }
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 5b503a5..e86781d 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
@@ -30,9 +30,9 @@ import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.TokenManager;
+import org.keycloak.services.managers.UserManager;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.Urls;
-import org.keycloak.util.Time;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -228,7 +228,7 @@ public class UsersResource {
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-        List<UserSessionModel> sessions = realm.getUserSessions(user);
+        List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user);
         List<UserSessionRepresentation> reps = new ArrayList<UserSessionRepresentation>();
         for (UserSessionModel session : sessions) {
             UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
@@ -276,7 +276,7 @@ public class UsersResource {
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-        realm.removeUserSessions(user);
+        session.sessions().removeUserSessions(realm, user);
         new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), null);
     }
 
@@ -291,7 +291,12 @@ public class UsersResource {
     public void deleteUser(final @PathParam("username") String username) {
         auth.requireManage();
 
-        realm.removeUser(username);
+        UserModel user = realm.getUser(username);
+        if (user == null) {
+            throw new NotFoundException("User not found");
+        }
+
+        new UserManager(session).removeUser(realm, user);
     }
 
     /**
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 c44f39d..5027f19 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
@@ -42,7 +42,6 @@ import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AccessCodeEntry;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.TokenManager;
-import org.keycloak.services.util.CookieHelper;
 
 import javax.ws.rs.core.Cookie;
 import javax.ws.rs.core.MultivaluedMap;
@@ -90,7 +89,7 @@ public class OAuthFlows {
     }
 
 
-    public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel session, String state, String redirect, boolean rememberMe) {
+    public Response redirectAccessCode(AccessCodeEntry accessCode, UserSessionModel userSession, String state, String redirect, boolean rememberMe) {
         String code = accessCode.getCode();
         UriBuilder redirectUri = UriBuilder.fromUri(redirect).queryParam(OAuth2Constants.CODE, code);
         log.debugv("redirectAccessCode: state: {0}", state);
@@ -103,17 +102,17 @@ public class OAuthFlows {
         Cookie sessionCookie = request.getHttpHeaders().getCookies().get(AuthenticationManager.KEYCLOAK_SESSION_COOKIE);
         if (sessionCookie != null) {
             String oldSessionId = sessionCookie.getValue().split("/")[2];
-            if (!oldSessionId.equals(session.getId())) {
-                UserSessionModel oldSession = realm.getUserSession(oldSessionId);
+            if (!oldSessionId.equals(userSession.getId())) {
+                UserSessionModel oldSession = session.sessions().getUserSession(realm, oldSessionId);
                 if (oldSession != null) {
                     log.debugv("Removing old user session: session: {0}", oldSessionId);
-                    realm.removeUserSession(oldSession);
+                    session.sessions().removeUserSession(realm, oldSession);
                 }
             }
         }
 
         // refresh the cookies!
-        authManager.createLoginCookie(realm, accessCode.getUser(), session, uriInfo, rememberMe);
+        authManager.createLoginCookie(realm, accessCode.getUser(), userSession, uriInfo, rememberMe);
         if (rememberMe) authManager.createRememberMeCookie(realm, uriInfo);
         return location.build();
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index 1e15cf4..fb406ab 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -94,7 +94,7 @@ public class RealmsResource {
                                        @QueryParam("client_id") String client_id,
                                        @QueryParam("origin") String origin) {
         logger.info("getLoginStatusIframe");
-        AuthenticationManager auth = new AuthenticationManager(session);
+        AuthenticationManager auth = new AuthenticationManager();
 
         //logger.info("getting login-status-iframe.html for client_id: " + client_id);
         RealmManager realmManager = new RealmManager(session);
@@ -103,7 +103,7 @@ public class RealmsResource {
         if (client == null) {
             throw new NotFoundException("could not find client: " + client_id);
         }
-        AuthenticationManager.AuthResult result = auth.authenticateIdentityCookie(realm, uriInfo, headers);
+        AuthenticationManager.AuthResult result = auth.authenticateIdentityCookie(session, realm, uriInfo, headers);
         if (result == null) {
             throw new UnauthorizedException("not logged in, can't get page");
         }
@@ -148,7 +148,7 @@ public class RealmsResource {
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = locateRealm(name, realmManager);
         Audit audit = new AuditManager(realm, session, clientConnection).createAudit();
-        AuthenticationManager authManager = new AuthenticationManager(session, protector);
+        AuthenticationManager authManager = new AuthenticationManager(protector);
         TokenService tokenService = new TokenService(realm, tokenManager, audit, authManager);
         ResteasyProviderFactory.getInstance().injectProperties(tokenService);
         //resourceContext.initResource(tokenService);
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 64e680f..bfee8da 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -226,7 +226,7 @@ public class RequiredActionsService {
 
         // Password reset through email won't have an associated session
         if (accessCode.getSessionState() == null) {
-            UserSessionModel userSession = realm.createUserSession(realm.getUserById(accessCode.getUser().getId()), clientConnection.getRemoteAddr());
+            UserSessionModel userSession = session.sessions().createUserSession(realm, realm.getUserById(accessCode.getUser().getId()), clientConnection.getRemoteAddr());
             accessCode.getToken().setSessionState(userSession.getId());
             audit.session(userSession);
         }
@@ -299,7 +299,7 @@ public class RequiredActionsService {
         String redirect = uriInfo.getQueryParameters().getFirst(OAuth2Constants.REDIRECT_URI);
         String clientId = uriInfo.getQueryParameters().getFirst(OAuth2Constants.CLIENT_ID);
 
-        AuthenticationManager authManager = new AuthenticationManager(session);
+        AuthenticationManager authManager = new AuthenticationManager();
 
         ClientModel client = realm.findClient(clientId);
         if (client == null) {
@@ -397,19 +397,19 @@ public class RequiredActionsService {
             logger.debugv("redirectOauth: redirecting to: {0}", accessCode.getRedirectUri());
             accessCode.resetExpiration();
 
-            AuthenticationManager authManager = new AuthenticationManager(session);
+            AuthenticationManager authManager = new AuthenticationManager();
 
-            UserSessionModel session = realm.getUserSession(accessCode.getSessionState());
-            if (!AuthenticationManager.isSessionValid(realm, session)) {
-                AuthenticationManager.logout(realm, session, uriInfo);
+            UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState());
+            if (!AuthenticationManager.isSessionValid(realm, userSession)) {
+                AuthenticationManager.logout(session, realm, userSession, uriInfo);
                 return Flows.oauth(this.session, realm, request, uriInfo, authManager, tokenManager).redirectError(accessCode.getClient(), "access_denied", accessCode.getState(), accessCode.getRedirectUri());
             }
-            audit.session(session);
+            audit.session(userSession);
 
             audit.success();
 
             return Flows.oauth(this.session, realm, request, uriInfo, authManager, tokenManager).redirectAccessCode(accessCode,
-                    session, accessCode.getState(), accessCode.getRedirectUri());
+                    userSession, accessCode.getState(), accessCode.getRedirectUri());
         }
     }
 
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 2da3ec8..55dae8f 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -125,7 +125,7 @@ public class SocialResource {
                 .detail(Details.RESPONSE_TYPE, initialRequest.get(OAuth2Constants.RESPONSE_TYPE))
                 .detail(Details.AUTH_METHOD, "social@" + provider.getId());
 
-        AuthenticationManager authManager = new AuthenticationManager(session);
+        AuthenticationManager authManager = new AuthenticationManager();
         OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
 
         if (!realm.isEnabled()) {
@@ -251,10 +251,10 @@ public class SocialResource {
             return oauth.forwardToSecurityFailure("Your account is not enabled.");
         }
 
-        UserSessionModel session = realm.createUserSession(user, clientConnection.getRemoteAddr());
-        audit.session(session);
+        UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr());
+        audit.session(userSession);
 
-        return oauth.processAccessCode(scope, state, redirectUri, client, user, session, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social@" + provider.getId(), audit);
+        return oauth.processAccessCode(scope, state, redirectUri, client, user, userSession, socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(), false, "social@" + provider.getId(), audit);
     }
 
     @GET
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 371d8c4..f2691a7 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -249,7 +249,7 @@ public class TokenService {
             return createError("realm_disabled", "Realm is disabled", Response.Status.UNAUTHORIZED);
         }
 
-        AuthenticationStatus authenticationStatus = authManager.authenticateForm(clientConnection, realm, form);
+        AuthenticationStatus authenticationStatus = authManager.authenticateForm(session, clientConnection, realm, form);
         Map<String, String> err;
 
         switch (authenticationStatus) {
@@ -281,12 +281,12 @@ public class TokenService {
 
         String scope = form.getFirst(OAuth2Constants.SCOPE);
 
-        UserSessionModel session = realm.createUserSession(user, clientConnection.getRemoteAddr());
-        session.associateClient(client);
-        audit.session(session);
+        UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr());
+        userSession.associateClient(client);
+        audit.session(userSession);
 
         AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit)
-                .generateAccessToken(scope, client, user, session)
+                .generateAccessToken(scope, client, user, userSession)
                 .generateRefreshToken()
                 .generateIDToken()
                 .build();
@@ -327,7 +327,7 @@ public class TokenService {
         String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN);
         AccessToken accessToken;
         try {
-            accessToken = tokenManager.refreshAccessToken(uriInfo, realm, client, refreshToken, audit);
+            accessToken = tokenManager.refreshAccessToken(session, uriInfo, realm, client, refreshToken, audit);
         } catch (OAuthErrorException e) {
             Map<String, String> error = new HashMap<String, String>();
             error.put(OAuth2Constants.ERROR, e.getError());
@@ -412,7 +412,7 @@ public class TokenService {
             return oauth.redirectError(client, "access_denied", state, redirect);
         }
 
-        AuthenticationStatus status = authManager.authenticateForm(clientConnection, realm, formData);
+        AuthenticationStatus status = authManager.authenticateForm(session, clientConnection, realm, formData);
 
         if (remember) {
             authManager.createRememberMeCookie(realm, uriInfo);
@@ -428,10 +428,10 @@ public class TokenService {
         switch (status) {
             case SUCCESS:
             case ACTIONS_REQUIRED:
-                UserSessionModel session = realm.createUserSession(user, clientConnection.getRemoteAddr());
-		        audit.session(session);
+                UserSessionModel userSession = session.sessions().createUserSession(realm, user, clientConnection.getRemoteAddr());
+		        audit.session(userSession);
 
-                return oauth.processAccessCode(scopeParam, state, redirect, client, user, session, username, remember, "form", audit);
+                return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, username, remember, "form", audit);
             case ACCOUNT_TEMPORARILY_DISABLED:
                 audit.error(Errors.USER_TEMPORARILY_DISABLED);
                 return Flows.forms(this.session, realm, uriInfo).setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).setFormData(formData).createLogin();
@@ -686,9 +686,9 @@ public class TokenService {
                     .build();
         }
 
-        UserSessionModel session = realm.getUserSession(accessCode.getSessionState());
-        if (!AuthenticationManager.isSessionValid(realm, session)) {
-            AuthenticationManager.logout(realm, session, uriInfo);
+        UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState());
+        if (!AuthenticationManager.isSessionValid(realm, userSession)) {
+            AuthenticationManager.logout(session, realm, userSession, uriInfo);
             Map<String, String> res = new HashMap<String, String>();
             res.put(OAuth2Constants.ERROR, "invalid_grant");
             res.put(OAuth2Constants.ERROR_DESCRIPTION, "Session not active");
@@ -699,7 +699,7 @@ public class TokenService {
 
         logger.debug("accessRequest SUCCESS");
 
-        session.associateClient(client);
+        userSession.associateClient(client);
 
         AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit)
                 .accessToken(accessCode.getToken())
@@ -825,7 +825,7 @@ public class TokenService {
         }
 
         logger.info("Checking cookie...");
-        AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
+        AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers);
         if (authResult != null) {
             UserModel user = authResult.getUser();
             UserSessionModel session = authResult.getSession();
@@ -924,11 +924,11 @@ public class TokenService {
         }
 
         // authenticate identity cookie, but ignore an access token timeout as we're logging out anyways.
-        AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(realm, uriInfo, headers, false);
+        AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers, false);
         if (authResult != null) {
             logout(authResult.getSession());
         } else if (sessionState != null) {
-            UserSessionModel userSession = realm.getUserSession(sessionState);
+            UserSessionModel userSession = session.sessions().getUserSession(realm, sessionState);
             if (userSession != null) {
                 logout(userSession);
             } else {
@@ -946,10 +946,9 @@ public class TokenService {
         }
     }
 
-    private void logout(UserSessionModel session) {
-        UserModel user = session.getUser();
-        authManager.logout(realm, session, uriInfo);
-        audit.user(user).session(session).success();
+    private void logout(UserSessionModel userSession) {
+        authManager.logout(session, realm, userSession, uriInfo);
+        audit.user(userSession.getUser()).session(userSession).success();
     }
 
     /**
@@ -993,13 +992,13 @@ public class TokenService {
             audit.detail(Details.REMEMBER_ME, "true");
         }
 
-        UserSessionModel session = realm.getUserSession(accessCodeEntry.getSessionState());
-        if (!AuthenticationManager.isSessionValid(realm, session)) {
-            AuthenticationManager.logout(realm, session, uriInfo);
+        UserSessionModel userSession = session.sessions().getUserSession(realm, accessCodeEntry.getSessionState());
+        if (!AuthenticationManager.isSessionValid(realm, userSession)) {
+            AuthenticationManager.logout(session, realm, userSession, uriInfo);
             audit.error(Errors.INVALID_CODE);
             return oauth.forwardToSecurityFailure("Session not active");
         }
-        audit.session(session);
+        audit.session(userSession);
 
         if (formData.containsKey("cancel")) {
             audit.error(Errors.REJECTED_BY_USER);
@@ -1009,7 +1008,7 @@ public class TokenService {
         audit.success();
 
         accessCodeEntry.resetExpiration();
-        return oauth.redirectAccessCode(accessCodeEntry, session, state, redirect);
+        return oauth.redirectAccessCode(accessCodeEntry, userSession, state, redirect);
     }
 
     @Path("oauth/oob")
diff --git a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java
index 5345423..425342b 100644
--- 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.getModel().getRealms()) {
+            for (RealmModel realm : session.model().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 c6f4361..e5f1d1c 100755
--- a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredUserSessions.java
+++ b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredUserSessions.java
@@ -2,6 +2,7 @@ package org.keycloak.services.scheduled;
 
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserSessionProvider;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -10,8 +11,9 @@ public class ClearExpiredUserSessions implements ScheduledTask {
 
     @Override
     public void run(KeycloakSession session) {
-        for (RealmModel realm : session.getModel().getRealms()) {
-            realm.removeExpiredUserSessions();
+        UserSessionProvider sessions = session.sessions();
+        for (RealmModel realm : session.model().getRealms()) {
+            sessions.removeExpiredUserSessions(realm);
         }
     }
 
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index 052f6b1..89590cf 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -127,6 +127,11 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-sessions-mem</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
             <artifactId>keycloak-invalidation-cache-model</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/testsuite/integration/src/main/resources/log4j.properties b/testsuite/integration/src/main/resources/log4j.properties
index 47ecd4e..e97cb41 100755
--- a/testsuite/integration/src/main/resources/log4j.properties
+++ b/testsuite/integration/src/main/resources/log4j.properties
@@ -5,3 +5,6 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] %m%n
 
 log4j.logger.org.keycloak=warn
+
+log4j.logger.org.xnio=off
+log4j.logger.org.hibernate=off
\ No newline at end of file
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 326c697..c314233 100755
--- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
@@ -23,6 +23,10 @@
         }
     },
 
+    "userSessions": {
+        "provider" : "mem"
+    },
+
     "modelCache": {
         "provider": "${keycloak.model.cache.provider:simple}"
     },
diff --git a/testsuite/integration/src/main/resources/META-INF/persistence.xml b/testsuite/integration/src/main/resources/META-INF/persistence.xml
index 39dd390..43b8e6b 100755
--- a/testsuite/integration/src/main/resources/META-INF/persistence.xml
+++ b/testsuite/integration/src/main/resources/META-INF/persistence.xml
@@ -15,9 +15,9 @@
         <class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
         <class>org.keycloak.models.jpa.entities.AuthenticationLinkEntity</class>
         <class>org.keycloak.models.jpa.entities.UserEntity</class>
-        <class>org.keycloak.models.jpa.entities.ClientUserSessionAssociationEntity</class>
-        <class>org.keycloak.models.jpa.entities.UserSessionEntity</class>
-        <class>org.keycloak.models.jpa.entities.UsernameLoginFailureEntity</class>
+        <!--<class>org.keycloak.models.jpa.entities.ClientUserSessionAssociationEntity</class>-->
+        <!--<class>org.keycloak.models.jpa.entities.UserSessionEntity</class>-->
+        <!--<class>org.keycloak.models.jpa.entities.UsernameLoginFailureEntity</class>-->
         <class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
         <class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
 
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 aba2beb..f403858 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
@@ -75,7 +75,7 @@ public class AdapterTest {
     @ClassRule
     public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
         @Override
-        protected void configure(RealmManager manager, RealmModel adminRealm) {
+        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
             RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
             RealmModel realm = manager.importRealm(representation);
 
@@ -100,7 +100,7 @@ public class AdapterTest {
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = adminRealm.getUser("admin");
-            UserSessionModel userSession = adminRealm.createUserSession(admin, null);
+            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null);
             AccessToken token = tm.createClientAccessToken(null, adminRealm, adminConsole, admin, userSession);
             return tm.encodeToken(adminRealm, token);
         } finally {
@@ -231,7 +231,7 @@ public class AdapterTest {
         Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.getModel().getRealmByName("demo");
+        RealmModel realm = session.model().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.getModel().getRealmByName("demo");
+        realm = session.model().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.getModel().getRealmByName("demo");
+        RealmModel realm = session.model().getRealmByName("demo");
         int originalIdle = realm.getSsoSessionIdleTimeout();
         realm.setSsoSessionIdleTimeout(1);
         session.getTransaction().commit();
@@ -274,8 +274,8 @@ public class AdapterTest {
         Thread.sleep(2000);
 
         session = keycloakRule.startSession();
-        realm = session.getModel().getRealmByName("demo");
-        realm.removeExpiredUserSessions();
+        realm = session.model().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.getModel().getRealmByName("demo");
+        realm = session.model().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.getModel().getRealmByName("demo");
+        RealmModel realm = session.model().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.getModel().getRealmByName("demo");
+        realm = session.model().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 96af4c1..ae4d367 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
@@ -28,6 +28,7 @@ import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
@@ -71,7 +72,7 @@ public class RelativeUriAdapterTest {
     @ClassRule
     public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){
         @Override
-        protected void configure(RealmManager manager, RealmModel adminRealm) {
+        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
             RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm-relative.json"), RealmRepresentation.class);
             RealmModel realm = manager.importRealm(representation);
 
@@ -86,8 +87,8 @@ public class RelativeUriAdapterTest {
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = adminRealm.getUser("admin");
-            UserSessionModel session = adminRealm.createUserSession(admin, null);
-            AccessToken token = tm.createClientAccessToken(null, adminRealm, adminConsole, admin, session);
+            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 7f44292..afd1c26 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
@@ -21,43 +21,26 @@
  */
 package org.keycloak.testsuite.admin;
 
-import org.jboss.resteasy.util.BasicAuthHelper;
 import org.junit.Assert;
 import org.junit.ClassRule;
-import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.Config;
-import org.keycloak.OAuth2Constants;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.adapters.action.SessionStats;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.AuthenticationProviderRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.ClaimManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
-import org.keycloak.services.resources.TokenService;
 import org.keycloak.services.resources.admin.AdminRoot;
-import org.keycloak.services.resources.admin.ApplicationResource;
-import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.adapter.CustomerDatabaseServlet;
-import org.keycloak.testsuite.adapter.CustomerServlet;
-import org.keycloak.testsuite.adapter.ProductServlet;
-import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
-import org.keycloak.testsuite.rule.WebResource;
-import org.keycloak.testsuite.rule.WebRule;
 import org.keycloak.testutils.KeycloakServer;
-import org.openqa.selenium.WebDriver;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
@@ -65,19 +48,12 @@ import javax.ws.rs.client.ClientRequestContext;
 import javax.ws.rs.client.ClientRequestFilter;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.Form;
-import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import java.io.IOException;
-import java.net.URI;
-import java.net.URL;
-import java.security.PublicKey;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -90,9 +66,7 @@ public class AdminAPITest {
     @ClassRule
     public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
         @Override
-        protected void configure(RealmManager manager, RealmModel adminRealm) {
-
-
+        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
         }
     };
 
@@ -105,7 +79,7 @@ public class AdminAPITest {
             ApplicationModel adminConsole = adminRealm.getApplicationByName(Constants.ADMIN_CONSOLE_APPLICATION);
             TokenManager tm = new TokenManager();
             UserModel admin = adminRealm.getUser("admin");
-            UserSessionModel userSession = adminRealm.createUserSession(admin, null);
+            UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, null);
             AccessToken token = tm.createClientAccessToken(null, adminRealm, adminConsole, admin, userSession);
             return tm.encodeToken(adminRealm, token);
         } finally {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
index d1f7d7d..a76b42a 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java
@@ -26,6 +26,7 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.OAuth2Constants;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -51,7 +52,7 @@ public class CompositeImportRoleTest {
     @ClassRule
     public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){
         @Override
-        protected void configure(RealmManager manager, RealmModel adminRealm) {
+        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
             RealmModel realm = manager.createRealm("Test");
             RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/testcomposite.json"), RealmRepresentation.class);
             manager.importRealm(representation, realm);
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 eaae048..5c7bc52 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
@@ -28,6 +28,7 @@ import org.junit.Test;
 import org.keycloak.OAuth2Constants;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
@@ -56,7 +57,7 @@ public class CompositeRoleTest {
     @ClassRule
     public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){
         @Override
-        protected void configure(RealmManager manager, RealmModel adminRealm) {
+        protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
             RealmModel realm = manager.createRealm("Test");
             manager.generateRealmKeys(realm);
             realmPublicKey = realm.getPublicKey();
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 1e74687..d9cdac3 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,8 +183,8 @@ public class RefreshTokenTest {
         String refreshId = oauth.verifyRefreshToken(tokenResponse.getRefreshToken()).getId();
 
         KeycloakSession session = keycloakRule.startSession();
-        RealmModel realm = session.getModel().getRealmByName("test");
-        UserSessionModel userSession = realm.getUserSession(sessionId);
+        RealmModel realm = session.model().getRealmByName("test");
+        UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
         int last = userSession.getLastSessionRefresh();
         session.getTransaction().commit();
         session.close();
@@ -199,8 +199,8 @@ public class RefreshTokenTest {
         Assert.assertEquals(200, tokenResponse.getStatusCode());
 
         session = keycloakRule.startSession();
-        realm = session.getModel().getRealmByName("test");
-        userSession = realm.getUserSession(sessionId);
+        realm = session.model().getRealmByName("test");
+        userSession = session.sessions().getUserSession(realm, sessionId);
         int next = userSession.getLastSessionRefresh();
         session.getTransaction().commit();
         session.close();
@@ -211,7 +211,7 @@ public class RefreshTokenTest {
 
 
         session = keycloakRule.startSession();
-        realm = session.getModel().getRealmByName("test");
+        realm = session.model().getRealmByName("test");
         int lastAccessTokenLifespan = realm.getAccessTokenLifespan();
         realm.setAccessTokenLifespan(100000);
         session.getTransaction().commit();
@@ -221,8 +221,8 @@ public class RefreshTokenTest {
         tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "password");
 
         session = keycloakRule.startSession();
-        realm = session.getModel().getRealmByName("test");
-        userSession = realm.getUserSession(sessionId);
+        realm = session.model().getRealmByName("test");
+        userSession = session.sessions().getUserSession(realm, sessionId);
         next = userSession.getLastSessionRefresh();
         session.getTransaction().commit();
         session.close();
@@ -231,7 +231,7 @@ public class RefreshTokenTest {
         Assert.assertThat(next, allOf(greaterThan(last), lessThan(last + 6)));
 
         session = keycloakRule.startSession();
-        realm = session.getModel().getRealmByName("test");
+        realm = session.model().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.getModel().getRealmByName("test");
+        realm = session.model().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.getModel().getRealmByName("test");
+        RealmModel realm = session.model().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.getModel().getRealmByName("test");
+        realm = session.model().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 0871feb..0ba9ed3 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,7 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         KeycloakSession session = server.getSessionFactory().create();
         session.getTransaction().begin();
         try {
-            UserModel user = session.getModel().getRealmByName(realm).getUser(name);
+            UserModel user = session.model().getRealmByName(realm).getUser(name);
             return user != null ? ModelToRepresentation.toRepresentation(user) : null;
         } finally {
             session.close();
@@ -51,7 +51,7 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         KeycloakSession session = server.getSessionFactory().create();
         session.getTransaction().begin();
         try {
-            return ModelToRepresentation.toRepresentation(session.getModel().getRealmByName(realm).getUserById(id));
+            return ModelToRepresentation.toRepresentation(session.model().getRealmByName(realm).getUserById(id));
         } finally {
             session.close();
         }
@@ -66,7 +66,7 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
 
             RealmModel adminstrationRealm = manager.getRealm(Config.getAdminRealm());
 
-            configure(manager, adminstrationRealm);
+            configure(session, manager, adminstrationRealm);
 
             session.getTransaction().commit();
         } finally {
@@ -74,7 +74,7 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         }
     }
 
-    protected void configure(RealmManager manager, RealmModel adminRealm) {
+    protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
 
     }
 
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 bb1ccf6..65395be 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,10 +100,10 @@ public class KeycloakRule extends AbstractKeycloakRule {
 
     public void removeUserSession(String sessionId) {
         KeycloakSession session = startSession();
-        RealmModel realm = session.getModel().getRealm("test");
-        UserSessionModel userSession = realm.getUserSession(sessionId);
+        RealmModel realm = session.model().getRealm("test");
+        UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
         assertNotNull(userSession);
-        realm.removeUserSession(userSession);
+        session.sessions().removeUserSession(realm, userSession);
         stopSession(session, true);
     }
 
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 53332db..eb532df 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.getModel().getRealm(adminRealmName) == null) {
+                if (keycloakSession.model().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 b523842..12f600c 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
@@ -5,7 +5,6 @@ import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
@@ -59,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.getModel().getRealm(realmId);
+        RealmModel realm = session.model().getRealm(realmId);
         if (realm == null) {
             throw new IllegalStateException("Realm '" + realmId + "' not found");
         }
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 dc74290..05d47c6 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
@@ -3,7 +3,6 @@ package org.keycloak.testsuite.performance;
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
-import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
@@ -68,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.getModel().getRealm(realmId);
+        RealmModel realm = session.model().getRealm(realmId);
         if (realm == null) {
             throw new IllegalStateException("Realm '" + realmId + "' not found");
         }
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 38d7ccb..7012d49 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.getModel().getRealm(realmId);
+        realm = session.model().getRealm(realmId);
         if (realm == null) {
             throw new IllegalStateException("Realm '" + realmId + "' not found");
         }
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
index f3cf2ed..4b89245 100644
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
@@ -170,7 +170,7 @@ public class PerfTools {
     }
 
     private int getUsersCount(String realmName, String prefix) {
-        RealmModel realm = session.getModel().getRealmByName(realmName);
+        RealmModel realm = session.model().getRealmByName(realmName);
 
         // TODO: method for count on model
         if (prefix == null) {