keycloak-uncached

Merge pull request #256 from patriot1burke/master refactor

3/2/2014 10:41:48 PM

Changes

admin-ui/src/main/resources/META-INF/resources/admin/partials/application-sessions.html 23(+0 -23)

model/mongo/pom.xml 274(+137 -137)

model/tests/pom.xml 138(+69 -69)

Details

diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index 58c5146..17cbe66 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -349,18 +349,6 @@ module.config([ '$routeProvider', function($routeProvider) {
             },
             controller : 'ApplicationInstallationCtrl'
         })
-        .when('/realms/:realm/applications/:application/sessions', {
-            templateUrl : 'partials/application-sessions.html',
-            resolve : {
-                realm : function(RealmLoader) {
-                    return RealmLoader();
-                },
-                application : function(ApplicationLoader) {
-                    return ApplicationLoader();
-                }
-            },
-            controller : 'ApplicationSessionsCtrl'
-        })
         .when('/create/application/:realm', {
             templateUrl : 'partials/application-detail.html',
             resolve : {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js
index 8bcacd1..5bfb651 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js
@@ -3,6 +3,10 @@ module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, 
     $scope.roles = roles;
     $scope.application = application;
 
+    for (var i = 0; i < roles.length; i++) {
+        console.log("role.id: " + roles[i].id + " role.name: " + roles[i].name);
+    }
+
     $scope.$watch(function() {
         return $location.path();
     }, function() {
@@ -39,11 +43,6 @@ module.controller('ApplicationCredentialsCtrl', function($scope, $location, real
     });
 });
 
-module.controller('ApplicationSessionsCtrl', function($scope, $location, realm, application) {
-    $scope.realm = realm;
-    $scope.application = application;
-});
-
 module.controller('ApplicationClaimsCtrl', function($scope, realm, application, claims,
                                                         ApplicationClaims,
                                                         $http, $location, Dialog, Notifications) {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
index 0a123bc..c83ddbc 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js
@@ -510,7 +510,7 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, appli
         // Update/save the selected application with new default roles.
         Application.update({
             realm: $scope.realm.realm,
-            id: $scope.application.name
+            application: $scope.application.name
         }, $scope.application, function () {
             Notifications.success("Your changes have been saved to the application.");
         });
@@ -534,7 +534,7 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, appli
         // Update/save the selected application with new default roles.
         Application.update({
             realm: $scope.realm.realm,
-            id: $scope.application.name
+            application: $scope.application.name
         }, $scope.application, function () {
             Notifications.success("Your changes have been saved to the application.");
         });
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html
index d201185..72ba62f 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html
@@ -7,7 +7,6 @@
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
     <div id="content">
         <ol class="breadcrumb" data-ng-hide="create">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
index eda1518..d7045ee 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
@@ -7,7 +7,6 @@
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
     <div id="content">
         <ol class="breadcrumb" data-ng-hide="create">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
index 70491bb..84e188c 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
@@ -7,7 +7,6 @@
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
     <div id="content">
         <ol class="breadcrumb" data-ng-show="create">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html
index d6ffd1e..e446a1c 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html
@@ -8,7 +8,6 @@
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
 
     <div class="top-nav" data-ng-show="create">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
index 3a93fc6..2e0f892 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
@@ -7,7 +7,6 @@
         <li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
 
     <div id="content">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
index 40e8d4d..0bc76e7 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
@@ -8,7 +8,6 @@
         <li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
 
     <div id="content">
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
index 98fa8ea..64a755b 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
@@ -8,7 +8,6 @@
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
         <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
         <li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
-        <li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
     </ul>
 
     <div id="content">
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 cc7eaff..46a7103 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -49,4 +49,6 @@ public interface ClientModel {
     boolean validateSecret(String secret);
     String getSecret();
     public void setSecret(String secret);
+
+    RealmModel getRealm();
 }
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 43dda29..89592e8 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -101,6 +101,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
 
     boolean removeUser(String name);
 
+    RoleModel getRoleById(String id);
+
     List<String> getDefaultRoles();
     
     void addDefaultRole(String name);
@@ -182,4 +184,6 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
     int getNotBefore();
 
     void setNotBefore(int notBefore);
+
+    boolean removeRoleById(String id);
 }
diff --git a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
index bd8bfab..62ecfdb 100755
--- a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
@@ -12,9 +12,8 @@ public interface RoleContainerModel {
 
     RoleModel addRole(String name);
 
-    boolean removeRoleById(String id);
+    boolean removeRole(RoleModel role);
 
     Set<RoleModel> getRoles();
 
-    RoleModel getRoleById(String id);
 }
diff --git a/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java b/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java
index a484477..742da11 100755
--- a/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java
+++ b/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java
@@ -1,31 +1,31 @@
-package org.keycloak.models;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class SocialLinkModel {
-
-    private String socialUsername;
-    private String socialProvider;
-
-    public SocialLinkModel(String socialProvider, String socialUsername) {
-        this.socialUsername = socialUsername;
-        this.socialProvider = socialProvider;
-    }
-
-    public String getSocialUsername() {
-        return socialUsername;
-    }
-
-    public void setSocialUsername(String socialUsername) {
-        this.socialUsername = socialUsername;
-    }
-
-    public String getSocialProvider() {
-        return socialProvider;
-    }
-
-    public void setSocialProvider(String socialProvider) {
-        this.socialProvider = socialProvider;
-    }
-}
+package org.keycloak.models;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SocialLinkModel {
+
+    private String socialUsername;
+    private String socialProvider;
+
+    public SocialLinkModel(String socialProvider, String socialUsername) {
+        this.socialUsername = socialUsername;
+        this.socialProvider = socialProvider;
+    }
+
+    public String getSocialUsername() {
+        return socialUsername;
+    }
+
+    public void setSocialUsername(String socialUsername) {
+        this.socialUsername = socialUsername;
+    }
+
+    public String getSocialProvider() {
+        return socialProvider;
+    }
+
+    public void setSocialProvider(String socialProvider) {
+        this.socialProvider = socialProvider;
+    }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
index 510f852..d096b97 100755
--- a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
@@ -1,69 +1,69 @@
-package org.keycloak.models;
-
-import java.util.UUID;
-
-/**
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-public class UserCredentialModel {
-    public static final String PASSWORD = "password";
-
-    // Secret is same as password but it is not hashed
-    public static final String SECRET = "secret";
-    public static final String TOTP = "totp";
-    public static final String CLIENT_CERT = "cert";
-
-    protected String type;
-    protected String value;
-    protected String device;
-
-    public UserCredentialModel() {
-    }
-
-    public static UserCredentialModel password(String password) {
-        UserCredentialModel model = new UserCredentialModel();
-        model.setType(PASSWORD);
-        model.setValue(password);
-        return model;
-    }
-
-    public static UserCredentialModel secret(String password) {
-        UserCredentialModel model = new UserCredentialModel();
-        model.setType(SECRET);
-        model.setValue(password);
-        return model;
-    }
-
-    public static UserCredentialModel generateSecret() {
-        UserCredentialModel model = new UserCredentialModel();
-        model.setType(SECRET);
-        model.setValue(UUID.randomUUID().toString());
-        return model;
-    }
-
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    public String getDevice() {
-        return device;
-    }
-
-    public void setDevice(String device) {
-        this.device = device;
-    }
-}
+package org.keycloak.models;
+
+import java.util.UUID;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class UserCredentialModel {
+    public static final String PASSWORD = "password";
+
+    // Secret is same as password but it is not hashed
+    public static final String SECRET = "secret";
+    public static final String TOTP = "totp";
+    public static final String CLIENT_CERT = "cert";
+
+    protected String type;
+    protected String value;
+    protected String device;
+
+    public UserCredentialModel() {
+    }
+
+    public static UserCredentialModel password(String password) {
+        UserCredentialModel model = new UserCredentialModel();
+        model.setType(PASSWORD);
+        model.setValue(password);
+        return model;
+    }
+
+    public static UserCredentialModel secret(String password) {
+        UserCredentialModel model = new UserCredentialModel();
+        model.setType(SECRET);
+        model.setValue(password);
+        return model;
+    }
+
+    public static UserCredentialModel generateSecret() {
+        UserCredentialModel model = new UserCredentialModel();
+        model.setType(SECRET);
+        model.setValue(UUID.randomUUID().toString());
+        return model;
+    }
+
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getDevice() {
+        return device;
+    }
+
+    public void setDevice(String device) {
+        this.device = device;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
index 69c30ec..371a43a 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
@@ -24,10 +24,9 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
 
     protected EntityManager em;
     protected ApplicationEntity applicationEntity;
-    protected RealmModel realm;
 
     public ApplicationAdapter(RealmModel realm, EntityManager em, ApplicationEntity applicationEntity) {
-        super(applicationEntity);
+        super(realm, applicationEntity);
         this.realm = realm;
         this.em = em;
         this.applicationEntity = applicationEntity;
@@ -48,7 +47,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
         entity.setName(name);
     }
 
-
     @Override
     public boolean isSurrogateAuthRequired() {
         return applicationEntity.isSurrogateAuthRequired();
@@ -103,11 +101,14 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
     }
 
     @Override
-    public boolean removeRoleById(String id) {
-        RoleAdapter roleAdapter = getRoleById(id);
+    public boolean removeRole(RoleModel roleModel) {
+        RoleAdapter roleAdapter = (RoleAdapter)roleModel;
         if (roleAdapter == null) {
             return false;
         }
+        if (!roleAdapter.getContainer().equals(this)) return false;
+
+        if (!(roleAdapter.getRole() instanceof ApplicationRoleEntity)) return false;
 
         ApplicationRoleEntity role = (ApplicationRoleEntity)roleAdapter.getRole();
 
@@ -135,16 +136,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
     }
 
     @Override
-    public RoleAdapter getRoleById(String id) {
-        RoleEntity entity = em.find(RoleEntity.class, id);
-
-        // Check if it's application role and belongs to this application
-        if (entity == null || !(entity instanceof ApplicationRoleEntity)) return null;
-        ApplicationRoleEntity appRoleEntity = (ApplicationRoleEntity)entity;
-        return (appRoleEntity.getApplication().equals(this.entity)) ? new RoleAdapter(this.realm, em, appRoleEntity) : null;
-    }
-
-    @Override
     public Set<RoleModel> getApplicationRoleMappings(UserModel user) {
         Set<RoleModel> roleMappings = realm.getRoleMappings(user);
 
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 2ec95ec..7dcd3d9 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -1,6 +1,7 @@
 package org.keycloak.models.jpa;
 
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.jpa.entities.ClientEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 
@@ -13,8 +14,10 @@ import java.util.Set;
  */
 public class ClientAdapter implements ClientModel {
     protected ClientEntity entity;
+    protected RealmModel realm;
 
-    public ClientAdapter(ClientEntity entity) {
+    public ClientAdapter(RealmModel realm, ClientEntity entity) {
+        this.realm = realm;
         this.entity = entity;
     }
 
@@ -22,75 +25,111 @@ public class ClientAdapter implements ClientModel {
         return entity;
     }
 
+    @Override
     public String getId() {
         return entity.getId();
     }
 
+    @Override
+    public RealmModel getRealm() {
+        return realm;
+    }
+
+    @Override
     public String getClientId() {
         return entity.getName();
     }
 
+    @Override
     public boolean isEnabled() {
         return entity.isEnabled();
     }
 
+    @Override
     public void setEnabled(boolean enabled) {
         entity.setEnabled(enabled);
     }
 
+    @Override
     public long getAllowedClaimsMask() {
         return entity.getAllowedClaimsMask();
     }
 
+    @Override
     public void setAllowedClaimsMask(long mask) {
         entity.setAllowedClaimsMask(mask);
     }
 
+    @Override
     public Set<String> getWebOrigins() {
         Set<String> result = new HashSet<String>();
         result.addAll(entity.getWebOrigins());
         return result;
     }
 
+    @Override
     public void setWebOrigins(Set<String> webOrigins) {
         entity.setWebOrigins(webOrigins);
     }
 
+    @Override
     public void addWebOrigin(String webOrigin) {
         entity.getWebOrigins().add(webOrigin);
     }
 
+    @Override
     public void removeWebOrigin(String webOrigin) {
         entity.getWebOrigins().remove(webOrigin);
     }
 
+    @Override
     public Set<String> getRedirectUris() {
         Set<String> result = new HashSet<String>();
         result.addAll(entity.getRedirectUris());
         return result;
     }
 
+    @Override
     public void setRedirectUris(Set<String> redirectUris) {
         entity.setRedirectUris(redirectUris);
     }
 
+    @Override
     public void addRedirectUri(String redirectUri) {
         entity.getRedirectUris().add(redirectUri);
     }
 
+    @Override
     public void removeRedirectUri(String redirectUri) {
         entity.getRedirectUris().remove(redirectUri);
     }
 
+    @Override
     public String getSecret() {
         return entity.getSecret();
     }
 
+    @Override
     public void setSecret(String secret) {
         entity.setSecret(secret);
     }
 
+    @Override
     public boolean validateSecret(String secret) {
         return secret.equals(entity.getSecret());
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!this.getClass().equals(o.getClass())) return false;
+
+        ClientAdapter that = (ClientAdapter) o;
+        return that.getId().equals(getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return entity.getId().hashCode();
+    }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
index 692a4e1..29d643d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
@@ -1,6 +1,7 @@
 package org.keycloak.models.jpa;
 
 import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 
@@ -13,7 +14,9 @@ import java.util.Set;
  */
 public class OAuthClientAdapter extends ClientAdapter implements OAuthClientModel {
 
-    public OAuthClientAdapter(OAuthClientEntity entity) {
-        super(entity);
+    public OAuthClientAdapter(RealmModel realm, OAuthClientEntity entity) {
+        super(realm, entity);
     }
+
+
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index d81b2a0..f7e17ce 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
@@ -3,6 +3,7 @@ package org.keycloak.models.jpa;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.ApplicationRoleEntity;
 import org.keycloak.models.jpa.entities.CredentialEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
@@ -496,7 +497,7 @@ public class RealmAdapter implements RealmModel {
         if (application == null) return false;
 
         for (RoleModel role : application.getRoles()) {
-            application.removeRoleById(role.getId());
+            application.removeRole(role);
         }
 
         ApplicationEntity applicationEntity = null;
@@ -673,12 +674,14 @@ public class RealmAdapter implements RealmModel {
         data.setRealm(realm);
         em.persist(data);
         em.flush();
-        return new OAuthClientAdapter(data);
+        return new OAuthClientAdapter(this, data);
     }
 
     @Override
     public boolean removeOAuthClient(String id) {
-        OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
+        OAuthClientModel oauth = getOAuthClientById(id);
+        if (oauth == null) return false;
+        OAuthClientEntity client = (OAuthClientEntity)((OAuthClientAdapter)oauth).getEntity();
         em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where client = :client").setParameter("client", client).executeUpdate();
         em.remove(client);
         return true;
@@ -692,7 +695,7 @@ public class RealmAdapter implements RealmModel {
         query.setParameter("realm", realm);
         List<OAuthClientEntity> entities = query.getResultList();
         if (entities.size() == 0) return null;
-        return new OAuthClientAdapter(entities.get(0));
+        return new OAuthClientAdapter(this, entities.get(0));
     }
 
     @Override
@@ -700,8 +703,8 @@ public class RealmAdapter implements RealmModel {
         OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
 
         // Check if client belongs to this realm
-        if (client == null || !this.realm.equals(client.getRealm())) return null;
-        return new OAuthClientAdapter(client);
+        if (client == null || !this.realm.getId().equals(client.getRealm().getId())) return null;
+        return new OAuthClientAdapter(this, client);
     }
 
 
@@ -711,7 +714,7 @@ public class RealmAdapter implements RealmModel {
         query.setParameter("realm", realm);
         List<OAuthClientEntity> entities = query.getResultList();
         List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
-        for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(entity));
+        for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(this, entity));
         return list;
     }
 
@@ -761,12 +764,12 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public boolean removeRoleById(String id) {
-        RoleModel role = getRoleById(id);
-
+    public boolean removeRole(RoleModel role) {
         if (role == null) {
             return false;
         }
+        if (!role.getContainer().equals(this)) return false;
+
         RoleEntity roleEntity = ((RoleAdapter)role).getRole();
         realm.getRoles().remove(role);
         realm.getDefaultRoles().remove(role);
@@ -793,11 +796,22 @@ public class RealmAdapter implements RealmModel {
     @Override
     public RoleModel getRoleById(String id) {
         RoleEntity entity = em.find(RoleEntity.class, id);
+        if (entity == null) return null;
+        if (entity instanceof RealmRoleEntity) {
+            RealmRoleEntity roleEntity = (RealmRoleEntity)entity;
+            if (!roleEntity.getRealm().getId().equals(getId())) return null;
+        } else {
+            ApplicationRoleEntity roleEntity = (ApplicationRoleEntity)entity;
+            if (!roleEntity.getApplication().getRealm().getId().equals(getId())) return null;
+        }
+        return new RoleAdapter(this, em, entity);
+    }
 
-        // Check if it's realm role and belongs to this realm
-        if (entity == null || !(entity instanceof RealmRoleEntity)) return null;
-        RealmRoleEntity realmRoleEntity = (RealmRoleEntity)entity;
-        return (realmRoleEntity.getRealm().equals(this.realm)) ? new RoleAdapter(this, em, realmRoleEntity) : null;
+    @Override
+    public boolean removeRoleById(String id) {
+        RoleModel role = getRoleById(id);
+        if (role == null) return false;
+        return role.getContainer().removeRole(role);
     }
 
     @Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
index e418441..421cffa 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
@@ -124,13 +124,13 @@ public class RoleAdapter implements RoleModel {
 
         RoleAdapter that = (RoleAdapter) o;
 
-        if (!role.equals(that.role)) return false;
+        if (!role.getId().equals(that.role.getId())) return false;
 
         return true;
     }
 
     @Override
     public int hashCode() {
-        return role.hashCode();
+        return role.getId().hashCode();
     }
 }
diff --git a/model/jpa/src/test/resources/META-INF/persistence.xml b/model/jpa/src/test/resources/META-INF/persistence.xml
index 8fa01f2..b6b99bb 100755
--- a/model/jpa/src/test/resources/META-INF/persistence.xml
+++ b/model/jpa/src/test/resources/META-INF/persistence.xml
@@ -1,66 +1,66 @@
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
-    version="1.0">
-    <persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
-        <provider>org.hibernate.ejb.HibernatePersistence</provider>
-
-        <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
-        <class>org.keycloak.models.jpa.entities.CredentialEntity</class>
-        <class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
-        <class>org.keycloak.models.jpa.entities.RealmEntity</class>
-        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
-        <class>org.keycloak.models.jpa.entities.ApplicationRoleEntity</class>
-        <class>org.keycloak.models.jpa.entities.RealmRoleEntity</class>
-        <class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
-        <class>org.keycloak.models.jpa.entities.UserEntity</class>
-        <class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
-        <class>org.keycloak.models.jpa.entities.ScopeMappingEntity</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-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>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+    version="1.0">
+    <persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+        <provider>org.hibernate.ejb.HibernatePersistence</provider>
+
+        <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
+        <class>org.keycloak.models.jpa.entities.CredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmEntity</class>
+        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationRoleEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmRoleEntity</class>
+        <class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
+        <class>org.keycloak.models.jpa.entities.UserEntity</class>
+        <class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.ScopeMappingEntity</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-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>

model/mongo/pom.xml 274(+137 -137)

diff --git a/model/mongo/pom.xml b/model/mongo/pom.xml
index 417249b..2ed8d45 100755
--- a/model/mongo/pom.xml
+++ b/model/mongo/pom.xml
@@ -1,138 +1,138 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>keycloak-parent</artifactId>
-        <groupId>org.keycloak</groupId>
-        <version>1.0-alpha-3-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>keycloak-model-mongo</artifactId>
-    <name>Keycloak Model Mongo</name>
-    <description/>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcprov-jdk16</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-core</artifactId>
-            <version>${project.version}</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-model-api</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.jboss.logging</groupId>
-            <artifactId>jboss-logging</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-common</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mongodb</groupId>
-            <artifactId>mongo-java-driver</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-model-tests</artifactId>
-            <version>${project.version}</version>
-            <classifier>tests</classifier>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <properties>
-        <keycloak.mongo.host>localhost</keycloak.mongo.host>
-        <keycloak.mongo.port>27018</keycloak.mongo.port>
-        <keycloak.mongo.db>keycloak</keycloak.mongo.db>
-        <keycloak.mongo.clearOnStartup>true</keycloak.mongo.clearOnStartup>
-    </properties>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.6</source>
-                    <target>1.6</target>
-                </configuration>
-            </plugin>
-
-            <!-- Postpone tests to "integration-test" phase, so that we can bootstrap embedded mongo on 27018 before running tests -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>test</id>
-                        <phase>integration-test</phase>
-                        <goals>
-                            <goal>test</goal>
-                        </goals>
-                        <configuration>
-                            <systemPropertyVariables>
-                                <keycloak.mongo.host>${keycloak.mongo.host}</keycloak.mongo.host>
-                                <keycloak.mongo.port>${keycloak.mongo.port}</keycloak.mongo.port>
-                                <keycloak.mongo.db>${keycloak.mongo.db}</keycloak.mongo.db>
-                                <keycloak.mongo.clearOnStartup>${keycloak.mongo.clearOnStartup}</keycloak.mongo.clearOnStartup>
-                            </systemPropertyVariables>
-                            <dependenciesToScan>
-                                <dependency>org.keycloak:keycloak-model-tests</dependency>
-                            </dependenciesToScan>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>default-test</id>
-                        <configuration>
-                            <skip>true</skip>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-
-            <!-- Embedded mongo -->
-            <plugin>
-                <groupId>com.github.joelittlejohn.embedmongo</groupId>
-                <artifactId>embedmongo-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>start-mongodb</id>
-                        <phase>pre-integration-test</phase>
-                        <goals>
-                            <goal>start</goal>
-                        </goals>
-                        <configuration>
-                            <port>${keycloak.mongo.port}</port>
-                            <logging>file</logging>
-                            <logFile>${project.build.directory}/mongodb.log</logFile>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>stop-mongodb</id>
-                        <phase>post-integration-test</phase>
-                        <goals>
-                            <goal>stop</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-
-        </plugins>
-    </build>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>keycloak-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.0-alpha-3-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-model-mongo</artifactId>
+    <name>Keycloak Model Mongo</name>
+    <description/>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk16</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.picketlink</groupId>
+            <artifactId>picketlink-common</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mongodb</groupId>
+            <artifactId>mongo-java-driver</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-tests</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <properties>
+        <keycloak.mongo.host>localhost</keycloak.mongo.host>
+        <keycloak.mongo.port>27018</keycloak.mongo.port>
+        <keycloak.mongo.db>keycloak</keycloak.mongo.db>
+        <keycloak.mongo.clearOnStartup>true</keycloak.mongo.clearOnStartup>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+
+            <!-- Postpone tests to "integration-test" phase, so that we can bootstrap embedded mongo on 27018 before running tests -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>test</id>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <configuration>
+                            <systemPropertyVariables>
+                                <keycloak.mongo.host>${keycloak.mongo.host}</keycloak.mongo.host>
+                                <keycloak.mongo.port>${keycloak.mongo.port}</keycloak.mongo.port>
+                                <keycloak.mongo.db>${keycloak.mongo.db}</keycloak.mongo.db>
+                                <keycloak.mongo.clearOnStartup>${keycloak.mongo.clearOnStartup}</keycloak.mongo.clearOnStartup>
+                            </systemPropertyVariables>
+                            <dependenciesToScan>
+                                <dependency>org.keycloak:keycloak-model-tests</dependency>
+                            </dependenciesToScan>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>default-test</id>
+                        <configuration>
+                            <skip>true</skip>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Embedded mongo -->
+            <plugin>
+                <groupId>com.github.joelittlejohn.embedmongo</groupId>
+                <artifactId>embedmongo-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>start-mongodb</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>start</goal>
+                        </goals>
+                        <configuration>
+                            <port>${keycloak.mongo.port}</port>
+                            <logging>file</logging>
+                            <logFile>${project.build.directory}/mongodb.log</logFile>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>stop-mongodb</id>
+                        <phase>post-integration-test</phase>
+                        <goals>
+                            <goal>stop</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
 </project>
\ No newline at end of file
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java b/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java
index 9da25e5..f16400c 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java
@@ -1,43 +1,43 @@
-package org.keycloak.models.mongo.api;
-
-import com.mongodb.DBObject;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public interface MongoStore {
-
-    /**
-     * Insert new entity
-     *
-     * @param entity to insert
-     */
-    void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
-
-    /**
-     * Update existing entity
-     *
-     * @param entity to update
-     */
-    void updateEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
-
-
-    <T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context);
-
-    <T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context);
-
-    <T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context);
-
-    boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
-
-    boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context);
-
-    boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context);
-
-    <S> boolean pushItemToList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context);
-
-    <S> boolean pullItemFromList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPull, MongoStoreInvocationContext context);
-}
+package org.keycloak.models.mongo.api;
+
+import com.mongodb.DBObject;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface MongoStore {
+
+    /**
+     * Insert new entity
+     *
+     * @param entity to insert
+     */
+    void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
+
+    /**
+     * Update existing entity
+     *
+     * @param entity to update
+     */
+    void updateEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
+
+
+    <T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context);
+
+    <T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context);
+
+    <T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context);
+
+    boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
+
+    boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context);
+
+    boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context);
+
+    <S> boolean pushItemToList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context);
+
+    <S> boolean pullItemFromList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPull, MongoStoreInvocationContext context);
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java b/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java
index 6da24b7..d48fa58 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java
@@ -1,111 +1,111 @@
-package org.keycloak.models.mongo.api.types;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Registry of mappers, which allow to convert application object to database objects. MapperRegistry is main entry point to be used by application.
- * Application can create instance of MapperRegistry and then register required Mapper objects.
- *
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MapperRegistry {
-
-    // TODO: Thread-safety support (maybe...)
-    // Mappers of Application objects to DB objects
-    private Map<Class<?>, Mapper<?, ?>> appObjectMappers = new HashMap<Class<?>, Mapper<?, ?>>();
-
-    // Mappers of DB objects to Application objects
-    private Map<Class<?>, Map<Class<?>, Mapper<?, ?>>> dbObjectMappers = new HashMap<Class<?>, Map<Class<?>, Mapper<?,?>>>();
-
-
-    /**
-     * Add mapper for converting application objects to DB objects
-     *
-     * @param mapper
-     */
-    public void addAppObjectMapper(Mapper<?, ?> mapper) {
-        appObjectMappers.put(mapper.getTypeOfObjectToConvert(), mapper);
-    }
-
-
-    /**
-     * Add mapper for converting DB objects to application objects
-     *
-     * @param mapper
-     */
-    public void addDBObjectMapper(Mapper<?, ?> mapper) {
-        Class<?> dbObjectType = mapper.getTypeOfObjectToConvert();
-        Class<?> appObjectType = mapper.getExpectedReturnType();
-        Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
-        if (appObjects == null) {
-            appObjects = new HashMap<Class<?>, Mapper<?, ?>>();
-            dbObjectMappers.put(dbObjectType, appObjects);
-        }
-        appObjects.put(appObjectType, mapper);
-    }
-
-
-    public <S> S convertDBObjectToApplicationObject(MapperContext<Object, S> context) {
-        Object dbObject = context.getObjectToConvert();
-        Class<?> expectedApplicationObjectType = context.getExpectedReturnType();
-
-        Class<?> dbObjectType = dbObject.getClass();
-        Mapper<Object, S> mapper;
-
-        Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
-        if (appObjects == null) {
-            throw new IllegalArgumentException("Not found any mappers for type " + dbObjectType);
-        } else {
-            if (appObjects.size() == 1) {
-                mapper = (Mapper<Object, S>)appObjects.values().iterator().next();
-            } else {
-                // Try to find converter for requested application type
-                mapper = (Mapper<Object, S>)getAppConverterForType(context.getExpectedReturnType(), appObjects);
-            }
-        }
-
-        if (mapper == null) {
-            throw new IllegalArgumentException("Can't found mapper for type " + dbObjectType + " and expectedApplicationType " + expectedApplicationObjectType);
-        }
-
-        return mapper.convertObject(context);
-    }
-
-
-    public <S> S convertApplicationObjectToDBObject(Object applicationObject, Class<S> expectedDBObjectType) {
-        Class<?> appObjectType = applicationObject.getClass();
-        Mapper<Object, S> mapper = (Mapper<Object, S>)getAppConverterForType(appObjectType, appObjectMappers);
-        if (mapper == null) {
-            throw new IllegalArgumentException("Can't found converter for type " + appObjectType + " in registered appObjectMappers");
-        }
-        if (!expectedDBObjectType.isAssignableFrom(mapper.getExpectedReturnType())) {
-            throw new IllegalArgumentException("Converter " + mapper + " has return type " + mapper.getExpectedReturnType() +
-                    " but we need type " + expectedDBObjectType);
-        }
-        return mapper.convertObject(new MapperContext<Object, S>(applicationObject, expectedDBObjectType, null));
-    }
-
-    // Try to find converter for given type or all it's supertypes
-    private static Mapper<Object, ?> getAppConverterForType(Class<?> appObjectType, Map<Class<?>, Mapper<?, ?>> appObjectConverters) {
-        Mapper<Object, ?> mapper = (Mapper<Object, ?>)appObjectConverters.get(appObjectType);
-        if (mapper != null) {
-            return mapper;
-        } else {
-            Class<?>[] interfaces = appObjectType.getInterfaces();
-            for (Class<?> interface1 : interfaces) {
-                mapper = getAppConverterForType(interface1, appObjectConverters);
-                if (mapper != null) {
-                    return mapper;
-                }
-            }
-
-            Class<?> superType = appObjectType.getSuperclass();
-            if (superType != null) {
-                return getAppConverterForType(superType, appObjectConverters);
-            } else {
-                return null;
-            }
-        }
-    }
-}
+package org.keycloak.models.mongo.api.types;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Registry of mappers, which allow to convert application object to database objects. MapperRegistry is main entry point to be used by application.
+ * Application can create instance of MapperRegistry and then register required Mapper objects.
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MapperRegistry {
+
+    // TODO: Thread-safety support (maybe...)
+    // Mappers of Application objects to DB objects
+    private Map<Class<?>, Mapper<?, ?>> appObjectMappers = new HashMap<Class<?>, Mapper<?, ?>>();
+
+    // Mappers of DB objects to Application objects
+    private Map<Class<?>, Map<Class<?>, Mapper<?, ?>>> dbObjectMappers = new HashMap<Class<?>, Map<Class<?>, Mapper<?,?>>>();
+
+
+    /**
+     * Add mapper for converting application objects to DB objects
+     *
+     * @param mapper
+     */
+    public void addAppObjectMapper(Mapper<?, ?> mapper) {
+        appObjectMappers.put(mapper.getTypeOfObjectToConvert(), mapper);
+    }
+
+
+    /**
+     * Add mapper for converting DB objects to application objects
+     *
+     * @param mapper
+     */
+    public void addDBObjectMapper(Mapper<?, ?> mapper) {
+        Class<?> dbObjectType = mapper.getTypeOfObjectToConvert();
+        Class<?> appObjectType = mapper.getExpectedReturnType();
+        Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
+        if (appObjects == null) {
+            appObjects = new HashMap<Class<?>, Mapper<?, ?>>();
+            dbObjectMappers.put(dbObjectType, appObjects);
+        }
+        appObjects.put(appObjectType, mapper);
+    }
+
+
+    public <S> S convertDBObjectToApplicationObject(MapperContext<Object, S> context) {
+        Object dbObject = context.getObjectToConvert();
+        Class<?> expectedApplicationObjectType = context.getExpectedReturnType();
+
+        Class<?> dbObjectType = dbObject.getClass();
+        Mapper<Object, S> mapper;
+
+        Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
+        if (appObjects == null) {
+            throw new IllegalArgumentException("Not found any mappers for type " + dbObjectType);
+        } else {
+            if (appObjects.size() == 1) {
+                mapper = (Mapper<Object, S>)appObjects.values().iterator().next();
+            } else {
+                // Try to find converter for requested application type
+                mapper = (Mapper<Object, S>)getAppConverterForType(context.getExpectedReturnType(), appObjects);
+            }
+        }
+
+        if (mapper == null) {
+            throw new IllegalArgumentException("Can't found mapper for type " + dbObjectType + " and expectedApplicationType " + expectedApplicationObjectType);
+        }
+
+        return mapper.convertObject(context);
+    }
+
+
+    public <S> S convertApplicationObjectToDBObject(Object applicationObject, Class<S> expectedDBObjectType) {
+        Class<?> appObjectType = applicationObject.getClass();
+        Mapper<Object, S> mapper = (Mapper<Object, S>)getAppConverterForType(appObjectType, appObjectMappers);
+        if (mapper == null) {
+            throw new IllegalArgumentException("Can't found converter for type " + appObjectType + " in registered appObjectMappers");
+        }
+        if (!expectedDBObjectType.isAssignableFrom(mapper.getExpectedReturnType())) {
+            throw new IllegalArgumentException("Converter " + mapper + " has return type " + mapper.getExpectedReturnType() +
+                    " but we need type " + expectedDBObjectType);
+        }
+        return mapper.convertObject(new MapperContext<Object, S>(applicationObject, expectedDBObjectType, null));
+    }
+
+    // Try to find converter for given type or all it's supertypes
+    private static Mapper<Object, ?> getAppConverterForType(Class<?> appObjectType, Map<Class<?>, Mapper<?, ?>> appObjectConverters) {
+        Mapper<Object, ?> mapper = (Mapper<Object, ?>)appObjectConverters.get(appObjectType);
+        if (mapper != null) {
+            return mapper;
+        } else {
+            Class<?>[] interfaces = appObjectType.getInterfaces();
+            for (Class<?> interface1 : interfaces) {
+                mapper = getAppConverterForType(interface1, appObjectConverters);
+                if (mapper != null) {
+                    return mapper;
+                }
+            }
+
+            Class<?> superType = appObjectType.getSuperclass();
+            if (superType != null) {
+                return getAppConverterForType(superType, appObjectConverters);
+            } else {
+                return null;
+            }
+        }
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java
index eedb4a7..b6ff046 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java
@@ -1,49 +1,49 @@
-package org.keycloak.models.mongo.impl;
-
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.picketlink.common.properties.Property;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class EntityInfo {
-
-    private final Class<? extends MongoEntity> entityClass;
-
-    private final String dbCollectionName;
-
-    private final Map<String, Property<Object>> properties;
-
-    public EntityInfo(Class<? extends MongoEntity> entityClass, String dbCollectionName, List<Property<Object>> properties) {
-        this.entityClass = entityClass;
-        this.dbCollectionName = dbCollectionName;
-
-        Map<String, Property<Object>> props= new HashMap<String, Property<Object>>();
-        for (Property<Object> property : properties) {
-            props.put(property.getName(), property);
-        }
-        this.properties = Collections.unmodifiableMap(props);
-    }
-
-    public Class<? extends MongoEntity> getEntityClass() {
-        return entityClass;
-    }
-
-    public String getDbCollectionName() {
-        return dbCollectionName;
-    }
-
-    public Collection<Property<Object>> getProperties() {
-        return properties.values();
-    }
-
-    public Property<Object> getPropertyByName(String propertyName) {
-        return properties.get(propertyName);
-    }
-}
+package org.keycloak.models.mongo.impl;
+
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.picketlink.common.properties.Property;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class EntityInfo {
+
+    private final Class<? extends MongoEntity> entityClass;
+
+    private final String dbCollectionName;
+
+    private final Map<String, Property<Object>> properties;
+
+    public EntityInfo(Class<? extends MongoEntity> entityClass, String dbCollectionName, List<Property<Object>> properties) {
+        this.entityClass = entityClass;
+        this.dbCollectionName = dbCollectionName;
+
+        Map<String, Property<Object>> props= new HashMap<String, Property<Object>>();
+        for (Property<Object> property : properties) {
+            props.put(property.getName(), property);
+        }
+        this.properties = Collections.unmodifiableMap(props);
+    }
+
+    public Class<? extends MongoEntity> getEntityClass() {
+        return entityClass;
+    }
+
+    public String getDbCollectionName() {
+        return dbCollectionName;
+    }
+
+    public Collection<Property<Object>> getProperties() {
+        return properties.values();
+    }
+
+    public Property<Object> getPropertyByName(String propertyName) {
+        return properties.get(propertyName);
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java
index fa41a46..4d59598 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java
@@ -1,416 +1,416 @@
-package org.keycloak.models.mongo.impl;
-
-import com.mongodb.BasicDBList;
-import com.mongodb.BasicDBObject;
-import com.mongodb.DB;
-import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
-import com.mongodb.DBObject;
-import org.jboss.logging.Logger;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-import org.keycloak.models.mongo.api.MongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoStore;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.api.context.MongoTask;
-import org.keycloak.models.mongo.api.types.Mapper;
-import org.keycloak.models.mongo.api.types.MapperContext;
-import org.keycloak.models.mongo.api.types.MapperRegistry;
-import org.keycloak.models.mongo.impl.types.BasicDBListMapper;
-import org.keycloak.models.mongo.impl.types.BasicDBObjectMapper;
-import org.keycloak.models.mongo.impl.types.BasicDBObjectToMapMapper;
-import org.keycloak.models.mongo.impl.types.EnumToStringMapper;
-import org.keycloak.models.mongo.impl.types.ListMapper;
-import org.keycloak.models.mongo.impl.types.MapMapper;
-import org.keycloak.models.mongo.impl.types.MongoEntityMapper;
-import org.keycloak.models.mongo.impl.types.SimpleMapper;
-import org.keycloak.models.mongo.impl.types.StringToEnumMapper;
-import org.keycloak.models.utils.KeycloakModelUtils;
-import org.picketlink.common.properties.Property;
-import org.picketlink.common.properties.query.AnnotatedPropertyCriteria;
-import org.picketlink.common.properties.query.PropertyQueries;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MongoStoreImpl implements MongoStore {
-
-    private static final Class<?>[] SIMPLE_TYPES = { String.class, Integer.class, Boolean.class, Long.class, Double.class, Character.class, Date.class, byte[].class };
-
-    private final DB database;
-    private static final Logger logger = Logger.getLogger(MongoStoreImpl.class);
-
-    private final MapperRegistry mapperRegistry;
-    private ConcurrentMap<Class<? extends MongoEntity>, EntityInfo> entityInfoCache =
-            new ConcurrentHashMap<Class<? extends MongoEntity>, EntityInfo>();
-
-
-    public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class<? extends MongoEntity>[] managedEntityTypes) {
-        this.database = database;
-
-        mapperRegistry = new MapperRegistry();
-
-        for (Class<?> simpleConverterClass : SIMPLE_TYPES) {
-            SimpleMapper converter = new SimpleMapper(simpleConverterClass);
-            mapperRegistry.addAppObjectMapper(converter);
-            mapperRegistry.addDBObjectMapper(converter);
-        }
-
-        // Specific converter for ArrayList is added just for performance purposes to avoid recursive converter lookup (most of list impl will be ArrayList)
-        mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, ArrayList.class));
-        mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, List.class));
-        mapperRegistry.addDBObjectMapper(new BasicDBListMapper(mapperRegistry));
-
-        mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class));
-        mapperRegistry.addAppObjectMapper(new MapMapper(Map.class));
-        mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper());
-
-        // Enum converters
-        mapperRegistry.addAppObjectMapper(new EnumToStringMapper());
-        mapperRegistry.addDBObjectMapper(new StringToEnumMapper());
-
-        for (Class<? extends MongoEntity> type : managedEntityTypes) {
-            getEntityInfo(type);
-            mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type));
-            mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type));
-        }
-
-        if (clearCollectionsOnStartup) {
-            // dropDatabase();
-            clearManagedCollections(managedEntityTypes);
-        }
-    }
-
-    protected void dropDatabase() {
-        this.database.dropDatabase();
-        logger.info("Database " + this.database.getName() + " dropped in MongoDB");
-    }
-
-    // Don't drop database, but just clear all data in managed collections (useful for development)
-    protected void clearManagedCollections(Class<? extends MongoEntity>[] managedEntityTypes) {
-        for (Class<? extends MongoEntity> clazz : managedEntityTypes) {
-            DBCollection dbCollection = getDBCollectionForType(clazz);
-            if (dbCollection != null) {
-                dbCollection.remove(new BasicDBObject());
-                logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName());
-            }
-        }
-    }
-
-    @Override
-    public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
-        Class<? extends MongoEntity> clazz = entity.getClass();
-
-        // Find annotations for ID, for all the properties and for the name of the collection.
-        EntityInfo entityInfo = getEntityInfo(clazz);
-
-        // Create instance of BasicDBObject and add all declared properties to it (properties with null value probably should be skipped)
-        BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
-
-        DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
-
-        String currentId = entity.getId();
-
-        // Generate random ID if not set already
-        if (currentId == null) {
-            currentId = KeycloakModelUtils.generateId();
-            entity.setId(currentId);
-        }
-
-        // Adding "_id"
-        dbObject.put("_id", currentId);
-
-        dbCollection.insert(dbObject);
-
-        // Treat object as created in this transaction (It is already submited to transaction)
-        context.addCreatedEntity(entity);
-    }
-
-    @Override
-    public void updateEntity(final MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
-        MongoTask fullUpdateTask = new MongoTask() {
-
-            @Override
-            public void execute() {
-                Class<? extends MongoEntity> clazz = entity.getClass();
-                EntityInfo entityInfo = getEntityInfo(clazz);
-                BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
-                DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
-
-                String currentId = entity.getId();
-
-                if (currentId == null) {
-                    throw new IllegalStateException("Can't update entity without id: " + entity);
-                } else {
-                    BasicDBObject query = new BasicDBObject("_id", currentId);
-                    dbCollection.update(query, dbObject);
-                }
-            }
-
-            @Override
-            public boolean isFullUpdate() {
-                return true;
-            }
-        };
-
-        // update is just added to context and postponed
-        context.addUpdateTask(entity, fullUpdateTask);
-    }
-
-
-    @Override
-    public <T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context) {
-        // First look if we already read the object with this oid and type during this transaction. If yes, use it instead of DB lookup
-        T cached = context.getLoadedEntity(type, id);
-        if (cached != null) return cached;
-
-        DBCollection dbCollection = getDBCollectionForType(type);
-
-        BasicDBObject idQuery = new BasicDBObject("_id", id);
-        DBObject dbObject = dbCollection.findOne(idQuery);
-
-        if (dbObject == null) return null;
-
-        MapperContext<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
-        T converted = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
-
-        // Now add it to loaded objects
-        context.addLoadedEntity(converted);
-
-        return converted;
-    }
-
-
-    @Override
-    public <T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
-        // First we should execute all pending tasks before searching DB
-        context.beforeDBSearch(type);
-
-        DBCollection dbCollection = getDBCollectionForType(type);
-        DBObject dbObject = dbCollection.findOne(query);
-
-        if (dbObject == null) {
-            return null;
-        } else {
-            return convertDBObjectToEntity(type, dbObject, context);
-        }
-    }
-
-
-    @Override
-    public <T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
-        // First we should execute all pending tasks before searching DB
-        context.beforeDBSearch(type);
-
-        DBCollection dbCollection = getDBCollectionForType(type);
-        DBCursor cursor = dbCollection.find(query);
-
-        return convertCursor(type, cursor, context);
-    }
-
-
-    @Override
-    public boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
-        return removeEntity(entity.getClass(), entity.getId(), context);
-    }
-
-
-    @Override
-    public boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context) {
-        MongoIdentifiableEntity found = loadEntity(type, id, context);
-        if (found == null) {
-            return false;
-        } else {
-            DBCollection dbCollection = getDBCollectionForType(type);
-            BasicDBObject dbQuery = new BasicDBObject("_id", id);
-            dbCollection.remove(dbQuery);
-            logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB.");
-
-            context.addRemovedEntity(found);
-            return true;
-        }
-    }
-
-
-    @Override
-    public boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context) {
-        List<? extends MongoIdentifiableEntity> foundObjects = loadEntities(type, query, context);
-        if (foundObjects.size() == 0) {
-            return false;
-        } else {
-            DBCollection dbCollection = getDBCollectionForType(type);
-            dbCollection.remove(query);
-            logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query);
-
-            for (MongoIdentifiableEntity found : foundObjects) {
-                context.addRemovedEntity(found);;
-            }
-            return true;
-        }
-    }
-
-    @Override
-    public <S> boolean pushItemToList(final MongoIdentifiableEntity entity, final String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context) {
-        final Class<? extends MongoEntity> type = entity.getClass();
-        EntityInfo entityInfo = getEntityInfo(type);
-
-        // Add item to list directly in this object
-        Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
-        if (listProperty == null) {
-            throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
-        }
-
-        List<S> list = (List<S>)listProperty.getValue(entity);
-        if (list == null) {
-            list = new ArrayList<S>();
-            listProperty.setValue(entity, list);
-        }
-
-        // Skip if item is already in list
-        if (skipIfAlreadyPresent && list.contains(itemToPush)) {
-            return false;
-        }
-
-        // Update java object
-        list.add(itemToPush);
-
-        // Add update of list to pending tasks
-        final List<S> listt = list;
-        context.addUpdateTask(entity, new MongoTask() {
-
-            @Override
-            public void execute() {
-                // Now DB update of new list with usage of $set
-                BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class);
-
-                BasicDBObject query = new BasicDBObject("_id", entity.getId());
-                BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList);
-                BasicDBObject setCommand = new BasicDBObject("$set", listObject);
-                getDBCollectionForType(type).update(query, setCommand);
-            }
-
-            @Override
-            public boolean isFullUpdate() {
-                return false;
-            }
-        });
-
-        return true;
-    }
-
-
-    @Override
-    public <S> boolean pullItemFromList(final MongoIdentifiableEntity entity, final String listPropertyName, final S itemToPull, MongoStoreInvocationContext context) {
-        final Class<? extends MongoEntity> type = entity.getClass();
-        EntityInfo entityInfo = getEntityInfo(type);
-
-        // Remove item from list directly in this object
-        Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
-        if (listProperty == null) {
-            throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
-        }
-        List<S> list = (List<S>)listProperty.getValue(entity);
-
-        // If list is null, we skip both object and DB update
-        if (list == null || !list.contains(itemToPull)) {
-            return false;
-        } else {
-
-            // Update java object
-            list.remove(itemToPull);
-
-            // Add update of list to pending tasks
-            context.addUpdateTask(entity, new MongoTask() {
-
-                @Override
-                public void execute() {
-                    // Pull item from DB
-                    Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class);
-                    BasicDBObject query = new BasicDBObject("_id", entity.getId());
-                    BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull);
-                    BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject);
-                    getDBCollectionForType(type).update(query, pullCommand);
-                }
-
-                @Override
-                public boolean isFullUpdate() {
-                    return false;
-                }
-            });
-
-            return true;
-        }
-    }
-
-    // Possibility to add user-defined mappers
-    public void addAppObjectConverter(Mapper<?, ?> mapper) {
-        mapperRegistry.addAppObjectMapper(mapper);
-    }
-
-    public void addDBObjectConverter(Mapper<?, ?> mapper) {
-        mapperRegistry.addDBObjectMapper(mapper);
-    }
-
-    public EntityInfo getEntityInfo(Class<? extends MongoEntity> entityClass) {
-        EntityInfo entityInfo = entityInfoCache.get(entityClass);
-        if (entityInfo == null) {
-            List<Property<Object>> properties = PropertyQueries.createQuery(entityClass).addCriteria(new AnnotatedPropertyCriteria(MongoField.class)).getResultList();
-
-            MongoCollection classAnnotation = entityClass.getAnnotation(MongoCollection.class);
-
-            String dbCollectionName = classAnnotation==null ? null : classAnnotation.collectionName();
-            entityInfo = new EntityInfo(entityClass, dbCollectionName, properties);
-
-            EntityInfo existing = entityInfoCache.putIfAbsent(entityClass, entityInfo);
-            if (existing != null) {
-                entityInfo = existing;
-            }
-        }
-
-        return entityInfo;
-    }
-
-    protected <T extends MongoIdentifiableEntity> List<T> convertCursor(Class<T> type, DBCursor cursor, MongoStoreInvocationContext context) {
-        List<T> result = new ArrayList<T>();
-
-        try {
-            for (DBObject dbObject : cursor) {
-                T entity = convertDBObjectToEntity(type, dbObject, context);
-                result.add(entity);
-            }
-        } finally {
-            cursor.close();
-        }
-
-        return result;
-    }
-
-    protected <T extends MongoIdentifiableEntity> T convertDBObjectToEntity(Class<T> type, DBObject dbObject, MongoStoreInvocationContext context) {
-        // First look if we already have loaded object cached. If yes, we will use cached instance
-        String id = dbObject.get("_id").toString();
-        T object = context.getLoadedEntity(type, id);
-
-        if (object == null) {
-            // So convert and use fresh instance from DB
-            MapperContext<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
-            object = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
-            context.addLoadedEntity(object);
-        }
-        return object;
-    }
-
-    protected DBCollection getDBCollectionForType(Class<? extends MongoEntity> type) {
-        EntityInfo entityInfo = getEntityInfo(type);
-        String dbCollectionName = entityInfo.getDbCollectionName();
-        return dbCollectionName==null ? null : database.getCollection(dbCollectionName);
-    }
-}
+package org.keycloak.models.mongo.impl;
+
+import com.mongodb.BasicDBList;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+import org.jboss.logging.Logger;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+import org.keycloak.models.mongo.api.MongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoStore;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.api.context.MongoTask;
+import org.keycloak.models.mongo.api.types.Mapper;
+import org.keycloak.models.mongo.api.types.MapperContext;
+import org.keycloak.models.mongo.api.types.MapperRegistry;
+import org.keycloak.models.mongo.impl.types.BasicDBListMapper;
+import org.keycloak.models.mongo.impl.types.BasicDBObjectMapper;
+import org.keycloak.models.mongo.impl.types.BasicDBObjectToMapMapper;
+import org.keycloak.models.mongo.impl.types.EnumToStringMapper;
+import org.keycloak.models.mongo.impl.types.ListMapper;
+import org.keycloak.models.mongo.impl.types.MapMapper;
+import org.keycloak.models.mongo.impl.types.MongoEntityMapper;
+import org.keycloak.models.mongo.impl.types.SimpleMapper;
+import org.keycloak.models.mongo.impl.types.StringToEnumMapper;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.picketlink.common.properties.Property;
+import org.picketlink.common.properties.query.AnnotatedPropertyCriteria;
+import org.picketlink.common.properties.query.PropertyQueries;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoStoreImpl implements MongoStore {
+
+    private static final Class<?>[] SIMPLE_TYPES = { String.class, Integer.class, Boolean.class, Long.class, Double.class, Character.class, Date.class, byte[].class };
+
+    private final DB database;
+    private static final Logger logger = Logger.getLogger(MongoStoreImpl.class);
+
+    private final MapperRegistry mapperRegistry;
+    private ConcurrentMap<Class<? extends MongoEntity>, EntityInfo> entityInfoCache =
+            new ConcurrentHashMap<Class<? extends MongoEntity>, EntityInfo>();
+
+
+    public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class<? extends MongoEntity>[] managedEntityTypes) {
+        this.database = database;
+
+        mapperRegistry = new MapperRegistry();
+
+        for (Class<?> simpleConverterClass : SIMPLE_TYPES) {
+            SimpleMapper converter = new SimpleMapper(simpleConverterClass);
+            mapperRegistry.addAppObjectMapper(converter);
+            mapperRegistry.addDBObjectMapper(converter);
+        }
+
+        // Specific converter for ArrayList is added just for performance purposes to avoid recursive converter lookup (most of list impl will be ArrayList)
+        mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, ArrayList.class));
+        mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, List.class));
+        mapperRegistry.addDBObjectMapper(new BasicDBListMapper(mapperRegistry));
+
+        mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class));
+        mapperRegistry.addAppObjectMapper(new MapMapper(Map.class));
+        mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper());
+
+        // Enum converters
+        mapperRegistry.addAppObjectMapper(new EnumToStringMapper());
+        mapperRegistry.addDBObjectMapper(new StringToEnumMapper());
+
+        for (Class<? extends MongoEntity> type : managedEntityTypes) {
+            getEntityInfo(type);
+            mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type));
+            mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type));
+        }
+
+        if (clearCollectionsOnStartup) {
+            // dropDatabase();
+            clearManagedCollections(managedEntityTypes);
+        }
+    }
+
+    protected void dropDatabase() {
+        this.database.dropDatabase();
+        logger.info("Database " + this.database.getName() + " dropped in MongoDB");
+    }
+
+    // Don't drop database, but just clear all data in managed collections (useful for development)
+    protected void clearManagedCollections(Class<? extends MongoEntity>[] managedEntityTypes) {
+        for (Class<? extends MongoEntity> clazz : managedEntityTypes) {
+            DBCollection dbCollection = getDBCollectionForType(clazz);
+            if (dbCollection != null) {
+                dbCollection.remove(new BasicDBObject());
+                logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName());
+            }
+        }
+    }
+
+    @Override
+    public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
+        Class<? extends MongoEntity> clazz = entity.getClass();
+
+        // Find annotations for ID, for all the properties and for the name of the collection.
+        EntityInfo entityInfo = getEntityInfo(clazz);
+
+        // Create instance of BasicDBObject and add all declared properties to it (properties with null value probably should be skipped)
+        BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
+
+        DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
+
+        String currentId = entity.getId();
+
+        // Generate random ID if not set already
+        if (currentId == null) {
+            currentId = KeycloakModelUtils.generateId();
+            entity.setId(currentId);
+        }
+
+        // Adding "_id"
+        dbObject.put("_id", currentId);
+
+        dbCollection.insert(dbObject);
+
+        // Treat object as created in this transaction (It is already submited to transaction)
+        context.addCreatedEntity(entity);
+    }
+
+    @Override
+    public void updateEntity(final MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
+        MongoTask fullUpdateTask = new MongoTask() {
+
+            @Override
+            public void execute() {
+                Class<? extends MongoEntity> clazz = entity.getClass();
+                EntityInfo entityInfo = getEntityInfo(clazz);
+                BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
+                DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
+
+                String currentId = entity.getId();
+
+                if (currentId == null) {
+                    throw new IllegalStateException("Can't update entity without id: " + entity);
+                } else {
+                    BasicDBObject query = new BasicDBObject("_id", currentId);
+                    dbCollection.update(query, dbObject);
+                }
+            }
+
+            @Override
+            public boolean isFullUpdate() {
+                return true;
+            }
+        };
+
+        // update is just added to context and postponed
+        context.addUpdateTask(entity, fullUpdateTask);
+    }
+
+
+    @Override
+    public <T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context) {
+        // First look if we already read the object with this oid and type during this transaction. If yes, use it instead of DB lookup
+        T cached = context.getLoadedEntity(type, id);
+        if (cached != null) return cached;
+
+        DBCollection dbCollection = getDBCollectionForType(type);
+
+        BasicDBObject idQuery = new BasicDBObject("_id", id);
+        DBObject dbObject = dbCollection.findOne(idQuery);
+
+        if (dbObject == null) return null;
+
+        MapperContext<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
+        T converted = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
+
+        // Now add it to loaded objects
+        context.addLoadedEntity(converted);
+
+        return converted;
+    }
+
+
+    @Override
+    public <T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
+        // First we should execute all pending tasks before searching DB
+        context.beforeDBSearch(type);
+
+        DBCollection dbCollection = getDBCollectionForType(type);
+        DBObject dbObject = dbCollection.findOne(query);
+
+        if (dbObject == null) {
+            return null;
+        } else {
+            return convertDBObjectToEntity(type, dbObject, context);
+        }
+    }
+
+
+    @Override
+    public <T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
+        // First we should execute all pending tasks before searching DB
+        context.beforeDBSearch(type);
+
+        DBCollection dbCollection = getDBCollectionForType(type);
+        DBCursor cursor = dbCollection.find(query);
+
+        return convertCursor(type, cursor, context);
+    }
+
+
+    @Override
+    public boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
+        return removeEntity(entity.getClass(), entity.getId(), context);
+    }
+
+
+    @Override
+    public boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context) {
+        MongoIdentifiableEntity found = loadEntity(type, id, context);
+        if (found == null) {
+            return false;
+        } else {
+            DBCollection dbCollection = getDBCollectionForType(type);
+            BasicDBObject dbQuery = new BasicDBObject("_id", id);
+            dbCollection.remove(dbQuery);
+            logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB.");
+
+            context.addRemovedEntity(found);
+            return true;
+        }
+    }
+
+
+    @Override
+    public boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context) {
+        List<? extends MongoIdentifiableEntity> foundObjects = loadEntities(type, query, context);
+        if (foundObjects.size() == 0) {
+            return false;
+        } else {
+            DBCollection dbCollection = getDBCollectionForType(type);
+            dbCollection.remove(query);
+            logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query);
+
+            for (MongoIdentifiableEntity found : foundObjects) {
+                context.addRemovedEntity(found);;
+            }
+            return true;
+        }
+    }
+
+    @Override
+    public <S> boolean pushItemToList(final MongoIdentifiableEntity entity, final String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context) {
+        final Class<? extends MongoEntity> type = entity.getClass();
+        EntityInfo entityInfo = getEntityInfo(type);
+
+        // Add item to list directly in this object
+        Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
+        if (listProperty == null) {
+            throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
+        }
+
+        List<S> list = (List<S>)listProperty.getValue(entity);
+        if (list == null) {
+            list = new ArrayList<S>();
+            listProperty.setValue(entity, list);
+        }
+
+        // Skip if item is already in list
+        if (skipIfAlreadyPresent && list.contains(itemToPush)) {
+            return false;
+        }
+
+        // Update java object
+        list.add(itemToPush);
+
+        // Add update of list to pending tasks
+        final List<S> listt = list;
+        context.addUpdateTask(entity, new MongoTask() {
+
+            @Override
+            public void execute() {
+                // Now DB update of new list with usage of $set
+                BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class);
+
+                BasicDBObject query = new BasicDBObject("_id", entity.getId());
+                BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList);
+                BasicDBObject setCommand = new BasicDBObject("$set", listObject);
+                getDBCollectionForType(type).update(query, setCommand);
+            }
+
+            @Override
+            public boolean isFullUpdate() {
+                return false;
+            }
+        });
+
+        return true;
+    }
+
+
+    @Override
+    public <S> boolean pullItemFromList(final MongoIdentifiableEntity entity, final String listPropertyName, final S itemToPull, MongoStoreInvocationContext context) {
+        final Class<? extends MongoEntity> type = entity.getClass();
+        EntityInfo entityInfo = getEntityInfo(type);
+
+        // Remove item from list directly in this object
+        Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
+        if (listProperty == null) {
+            throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
+        }
+        List<S> list = (List<S>)listProperty.getValue(entity);
+
+        // If list is null, we skip both object and DB update
+        if (list == null || !list.contains(itemToPull)) {
+            return false;
+        } else {
+
+            // Update java object
+            list.remove(itemToPull);
+
+            // Add update of list to pending tasks
+            context.addUpdateTask(entity, new MongoTask() {
+
+                @Override
+                public void execute() {
+                    // Pull item from DB
+                    Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class);
+                    BasicDBObject query = new BasicDBObject("_id", entity.getId());
+                    BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull);
+                    BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject);
+                    getDBCollectionForType(type).update(query, pullCommand);
+                }
+
+                @Override
+                public boolean isFullUpdate() {
+                    return false;
+                }
+            });
+
+            return true;
+        }
+    }
+
+    // Possibility to add user-defined mappers
+    public void addAppObjectConverter(Mapper<?, ?> mapper) {
+        mapperRegistry.addAppObjectMapper(mapper);
+    }
+
+    public void addDBObjectConverter(Mapper<?, ?> mapper) {
+        mapperRegistry.addDBObjectMapper(mapper);
+    }
+
+    public EntityInfo getEntityInfo(Class<? extends MongoEntity> entityClass) {
+        EntityInfo entityInfo = entityInfoCache.get(entityClass);
+        if (entityInfo == null) {
+            List<Property<Object>> properties = PropertyQueries.createQuery(entityClass).addCriteria(new AnnotatedPropertyCriteria(MongoField.class)).getResultList();
+
+            MongoCollection classAnnotation = entityClass.getAnnotation(MongoCollection.class);
+
+            String dbCollectionName = classAnnotation==null ? null : classAnnotation.collectionName();
+            entityInfo = new EntityInfo(entityClass, dbCollectionName, properties);
+
+            EntityInfo existing = entityInfoCache.putIfAbsent(entityClass, entityInfo);
+            if (existing != null) {
+                entityInfo = existing;
+            }
+        }
+
+        return entityInfo;
+    }
+
+    protected <T extends MongoIdentifiableEntity> List<T> convertCursor(Class<T> type, DBCursor cursor, MongoStoreInvocationContext context) {
+        List<T> result = new ArrayList<T>();
+
+        try {
+            for (DBObject dbObject : cursor) {
+                T entity = convertDBObjectToEntity(type, dbObject, context);
+                result.add(entity);
+            }
+        } finally {
+            cursor.close();
+        }
+
+        return result;
+    }
+
+    protected <T extends MongoIdentifiableEntity> T convertDBObjectToEntity(Class<T> type, DBObject dbObject, MongoStoreInvocationContext context) {
+        // First look if we already have loaded object cached. If yes, we will use cached instance
+        String id = dbObject.get("_id").toString();
+        T object = context.getLoadedEntity(type, id);
+
+        if (object == null) {
+            // So convert and use fresh instance from DB
+            MapperContext<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
+            object = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
+            context.addLoadedEntity(object);
+        }
+        return object;
+    }
+
+    protected DBCollection getDBCollectionForType(Class<? extends MongoEntity> type) {
+        EntityInfo entityInfo = getEntityInfo(type);
+        String dbCollectionName = entityInfo.getDbCollectionName();
+        return dbCollectionName==null ? null : database.getCollection(dbCollectionName);
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java
index ff81604..58d8b9d 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java
@@ -1,44 +1,44 @@
-package org.keycloak.models.mongo.impl.types;
-
-import com.mongodb.BasicDBList;
-import org.keycloak.models.mongo.api.types.Mapper;
-import org.keycloak.models.mongo.api.types.MapperContext;
-import org.keycloak.models.mongo.api.types.MapperRegistry;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class BasicDBListMapper implements Mapper<BasicDBList, List> {
-
-    private final MapperRegistry mapperRegistry;
-
-    public BasicDBListMapper(MapperRegistry mapperRegistry) {
-        this.mapperRegistry = mapperRegistry;
-    }
-
-    @Override
-    public List convertObject(MapperContext<BasicDBList, List> context) {
-        BasicDBList dbList = context.getObjectToConvert();
-        ArrayList<Object> appObjects = new ArrayList<Object>();
-        Class<?> expectedListElementType = context.getGenericTypes().get(0);
-
-        for (Object dbObject : dbList) {
-            MapperContext<Object, Object> newContext = new MapperContext<Object, Object>(dbObject, expectedListElementType, null);
-            appObjects.add(mapperRegistry.convertDBObjectToApplicationObject(newContext));
-        }
-        return appObjects;
-    }
-
-    @Override
-    public Class<? extends BasicDBList> getTypeOfObjectToConvert() {
-        return BasicDBList.class;
-    }
-
-    @Override
-    public Class<List> getExpectedReturnType() {
-        return List.class;
-    }
-}
+package org.keycloak.models.mongo.impl.types;
+
+import com.mongodb.BasicDBList;
+import org.keycloak.models.mongo.api.types.Mapper;
+import org.keycloak.models.mongo.api.types.MapperContext;
+import org.keycloak.models.mongo.api.types.MapperRegistry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class BasicDBListMapper implements Mapper<BasicDBList, List> {
+
+    private final MapperRegistry mapperRegistry;
+
+    public BasicDBListMapper(MapperRegistry mapperRegistry) {
+        this.mapperRegistry = mapperRegistry;
+    }
+
+    @Override
+    public List convertObject(MapperContext<BasicDBList, List> context) {
+        BasicDBList dbList = context.getObjectToConvert();
+        ArrayList<Object> appObjects = new ArrayList<Object>();
+        Class<?> expectedListElementType = context.getGenericTypes().get(0);
+
+        for (Object dbObject : dbList) {
+            MapperContext<Object, Object> newContext = new MapperContext<Object, Object>(dbObject, expectedListElementType, null);
+            appObjects.add(mapperRegistry.convertDBObjectToApplicationObject(newContext));
+        }
+        return appObjects;
+    }
+
+    @Override
+    public Class<? extends BasicDBList> getTypeOfObjectToConvert() {
+        return BasicDBList.class;
+    }
+
+    @Override
+    public Class<List> getExpectedReturnType() {
+        return List.class;
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java
index 7ac9a59..7857e36 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java
@@ -1,45 +1,45 @@
-package org.keycloak.models.mongo.impl.types;
-
-import com.mongodb.BasicDBList;
-import org.keycloak.models.mongo.api.types.Mapper;
-import org.keycloak.models.mongo.api.types.MapperContext;
-import org.keycloak.models.mongo.api.types.MapperRegistry;
-
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class ListMapper<T extends List> implements Mapper<T, BasicDBList> {
-
-    private final MapperRegistry mapperRegistry;
-    private final Class<T> listType;
-
-    public ListMapper(MapperRegistry mapperRegistry, Class<T> listType) {
-        this.mapperRegistry = mapperRegistry;
-        this.listType = listType;
-    }
-
-    @Override
-    public BasicDBList convertObject(MapperContext<T, BasicDBList> context) {
-        T appObjectsList = context.getObjectToConvert();
-
-        BasicDBList dbObjects = new BasicDBList();
-        for (Object appObject : appObjectsList) {
-            Object dbObject = mapperRegistry.convertApplicationObjectToDBObject(appObject, Object.class);
-
-            dbObjects.add(dbObject);
-        }
-        return dbObjects;
-    }
-
-    @Override
-    public Class<? extends T> getTypeOfObjectToConvert() {
-        return listType;
-    }
-
-    @Override
-    public Class<BasicDBList> getExpectedReturnType() {
-        return BasicDBList.class;
-    }
-}
+package org.keycloak.models.mongo.impl.types;
+
+import com.mongodb.BasicDBList;
+import org.keycloak.models.mongo.api.types.Mapper;
+import org.keycloak.models.mongo.api.types.MapperContext;
+import org.keycloak.models.mongo.api.types.MapperRegistry;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ListMapper<T extends List> implements Mapper<T, BasicDBList> {
+
+    private final MapperRegistry mapperRegistry;
+    private final Class<T> listType;
+
+    public ListMapper(MapperRegistry mapperRegistry, Class<T> listType) {
+        this.mapperRegistry = mapperRegistry;
+        this.listType = listType;
+    }
+
+    @Override
+    public BasicDBList convertObject(MapperContext<T, BasicDBList> context) {
+        T appObjectsList = context.getObjectToConvert();
+
+        BasicDBList dbObjects = new BasicDBList();
+        for (Object appObject : appObjectsList) {
+            Object dbObject = mapperRegistry.convertApplicationObjectToDBObject(appObject, Object.class);
+
+            dbObjects.add(dbObject);
+        }
+        return dbObjects;
+    }
+
+    @Override
+    public Class<? extends T> getTypeOfObjectToConvert() {
+        return listType;
+    }
+
+    @Override
+    public Class<BasicDBList> getExpectedReturnType() {
+        return BasicDBList.class;
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java
index 8fb29eb..d62deac 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java
@@ -1,58 +1,58 @@
-package org.keycloak.models.mongo.impl.types;
-
-import com.mongodb.BasicDBObject;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.types.Mapper;
-import org.keycloak.models.mongo.api.types.MapperContext;
-import org.keycloak.models.mongo.api.types.MapperRegistry;
-import org.keycloak.models.mongo.impl.MongoStoreImpl;
-import org.keycloak.models.mongo.impl.EntityInfo;
-import org.picketlink.common.properties.Property;
-
-import java.util.Collection;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MongoEntityMapper<T extends MongoEntity> implements Mapper<T, BasicDBObject> {
-
-    private final MongoStoreImpl mongoStoreImpl;
-    private final MapperRegistry mapperRegistry;
-    private final Class<T> expectedMongoEntityType;
-
-    public MongoEntityMapper(MongoStoreImpl mongoStoreImpl, MapperRegistry mapperRegistry, Class<T> expectedMongoEntityType) {
-        this.mongoStoreImpl = mongoStoreImpl;
-        this.mapperRegistry = mapperRegistry;
-        this.expectedMongoEntityType = expectedMongoEntityType;
-    }
-
-    @Override
-    public BasicDBObject convertObject(MapperContext<T, BasicDBObject> context) {
-        T applicationObject = context.getObjectToConvert();
-
-        EntityInfo entityInfo = mongoStoreImpl.getEntityInfo(applicationObject.getClass());
-
-        // Create instance of BasicDBObject and add all declared properties to it
-        BasicDBObject dbObject = new BasicDBObject();
-        Collection<Property<Object>> props = entityInfo.getProperties();
-        for (Property<Object> property : props) {
-            String propName = property.getName();
-            Object propValue = property.getValue(applicationObject);
-
-            Object dbValue = propValue == null ? null : mapperRegistry.convertApplicationObjectToDBObject(propValue, Object.class);
-            dbObject.put(propName, dbValue);
-        }
-
-        return dbObject;
-    }
-
-    @Override
-    public Class<? extends T> getTypeOfObjectToConvert() {
-        return expectedMongoEntityType;
-    }
-
-    @Override
-    public Class<BasicDBObject> getExpectedReturnType() {
-        return BasicDBObject.class;
-    }
-}
+package org.keycloak.models.mongo.impl.types;
+
+import com.mongodb.BasicDBObject;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.types.Mapper;
+import org.keycloak.models.mongo.api.types.MapperContext;
+import org.keycloak.models.mongo.api.types.MapperRegistry;
+import org.keycloak.models.mongo.impl.MongoStoreImpl;
+import org.keycloak.models.mongo.impl.EntityInfo;
+import org.picketlink.common.properties.Property;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoEntityMapper<T extends MongoEntity> implements Mapper<T, BasicDBObject> {
+
+    private final MongoStoreImpl mongoStoreImpl;
+    private final MapperRegistry mapperRegistry;
+    private final Class<T> expectedMongoEntityType;
+
+    public MongoEntityMapper(MongoStoreImpl mongoStoreImpl, MapperRegistry mapperRegistry, Class<T> expectedMongoEntityType) {
+        this.mongoStoreImpl = mongoStoreImpl;
+        this.mapperRegistry = mapperRegistry;
+        this.expectedMongoEntityType = expectedMongoEntityType;
+    }
+
+    @Override
+    public BasicDBObject convertObject(MapperContext<T, BasicDBObject> context) {
+        T applicationObject = context.getObjectToConvert();
+
+        EntityInfo entityInfo = mongoStoreImpl.getEntityInfo(applicationObject.getClass());
+
+        // Create instance of BasicDBObject and add all declared properties to it
+        BasicDBObject dbObject = new BasicDBObject();
+        Collection<Property<Object>> props = entityInfo.getProperties();
+        for (Property<Object> property : props) {
+            String propName = property.getName();
+            Object propValue = property.getValue(applicationObject);
+
+            Object dbValue = propValue == null ? null : mapperRegistry.convertApplicationObjectToDBObject(propValue, Object.class);
+            dbObject.put(propName, dbValue);
+        }
+
+        return dbObject;
+    }
+
+    @Override
+    public Class<? extends T> getTypeOfObjectToConvert() {
+        return expectedMongoEntityType;
+    }
+
+    @Override
+    public Class<BasicDBObject> getExpectedReturnType() {
+        return BasicDBObject.class;
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
index 07d8764..07c535f 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
@@ -1,305 +1,317 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
-import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
-import org.keycloak.models.mongo.keycloak.entities.UserEntity;
-import org.keycloak.models.mongo.utils.MongoModelUtils;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class ApplicationAdapter extends AbstractAdapter implements ApplicationModel {
-
-    private final ApplicationEntity application;
-
-    public ApplicationAdapter(ApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) {
-        super(invContext);
-        this.application = applicationEntity;
-    }
-
-    @Override
-    public void updateApplication() {
-        getMongoStore().updateEntity(application, invocationContext);
-    }
-
-    @Override
-    public String getId() {
-        return application.getId();
-    }
-
-    @Override
-    public String getClientId() {
-        return getName();
-    }
-
-    @Override
-    public String getName() {
-        return application.getName();
-    }
-
-    @Override
-    public void setName(String name) {
-        application.setName(name);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return application.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        application.setEnabled(enabled);
-    }
-
-    @Override
-    public boolean isSurrogateAuthRequired() {
-        return application.isSurrogateAuthRequired();
-    }
-
-    @Override
-    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
-        application.setSurrogateAuthRequired(surrogateAuthRequired);
-    }
-
-    @Override
-    public String getManagementUrl() {
-        return application.getManagementUrl();
-    }
-
-    @Override
-    public void setManagementUrl(String url) {
-        application.setManagementUrl(url);
-    }
-
-    @Override
-    public void setBaseUrl(String url) {
-        application.setBaseUrl(url);
-    }
-
-    @Override
-    public String getBaseUrl() {
-        return application.getBaseUrl();
-    }
-
-    @Override
-    public long getAllowedClaimsMask() {
-        return application.getAllowedClaimsMask();
-    }
-
-    @Override
-    public void setAllowedClaimsMask(long mask) {
-        application.setAllowedClaimsMask(mask);
-    }
-
-
-    @Override
-    public RoleAdapter getRole(String name) {
-        DBObject query = new QueryBuilder()
-                .and("name").is(name)
-                .and("applicationId").is(getId())
-                .get();
-        RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext);
-        if (role == null) {
-            return null;
-        } else {
-            return new RoleAdapter(role, invocationContext);
-        }
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext);
-
-        // Check that role belongs to this application
-        if (role == null || !getId().equals(role.getApplicationId())) {
-            return null;
-        } else {
-            return new RoleAdapter(role, this, invocationContext);
-        }
-    }
-
-    @Override
-    public RoleAdapter addRole(String name) {
-        RoleAdapter existing = getRole(name);
-        if (existing != null) {
-            return existing;
-        }
-
-        RoleEntity roleEntity = new RoleEntity();
-        roleEntity.setName(name);
-        roleEntity.setApplicationId(getId());
-
-        getMongoStore().insertEntity(roleEntity, invocationContext);
-        return new RoleAdapter(roleEntity, this, invocationContext);
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public Set<RoleModel> getRoles() {
-        DBObject query = new QueryBuilder()
-                .and("applicationId").is(getId())
-                .get();
-        List<RoleEntity> roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext);
-
-        Set<RoleModel> result = new HashSet<RoleModel>();
-        for (RoleEntity role : roles) {
-            result.add(new RoleAdapter(role, this, invocationContext));
-        }
-
-        return result;
-    }
-
-    @Override
-    public Set<RoleModel> getApplicationRoleMappings(UserModel user) {
-        Set<RoleModel> result = new HashSet<RoleModel>();
-        List<RoleEntity> roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext);
-
-        for (RoleEntity role : roles) {
-            if (getId().equals(role.getApplicationId())) {
-                result.add(new RoleAdapter(role, this, invocationContext));
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public void addScope(RoleModel role) {
-        getMongoStore().pushItemToList(application, "scopeIds", role.getId(), true, invocationContext);
-    }
-
-    @Override
-    public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
-        Set<RoleModel> result = new HashSet<RoleModel>();
-        List<RoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
-
-        for (RoleEntity role : roles) {
-            if (getId().equals(role.getApplicationId())) {
-                result.add(new RoleAdapter(role, this, invocationContext));
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public List<String> getDefaultRoles() {
-        return application.getDefaultRoles();
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        RoleModel role = getRole(name);
-        if (role == null) {
-            addRole(name);
-        }
-
-        getMongoStore().pushItemToList(application, "defaultRoles", name, true, invocationContext);
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        List<String> roleNames = new ArrayList<String>();
-        for (String roleName : defaultRoles) {
-            RoleModel role = getRole(roleName);
-            if (role == null) {
-                addRole(roleName);
-            }
-
-            roleNames.add(roleName);
-        }
-
-        application.setDefaultRoles(roleNames);
-    }
-
-    @Override
-    public AbstractMongoIdentifiableEntity getMongoEntity() {
-        return application;
-    }
-
-    @Override
-    public Set<String> getWebOrigins() {
-        Set<String> result = new HashSet<String>();
-        if (application.getWebOrigins() != null) {
-            result.addAll(application.getWebOrigins());
-        }
-        return result;
-    }
-
-    @Override
-    public void setWebOrigins(Set<String> webOrigins) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(webOrigins);
-        application.setWebOrigins(result);
-    }
-
-    @Override
-    public void addWebOrigin(String webOrigin) {
-        getMongoStore().pushItemToList(application, "webOrigins", webOrigin, true, invocationContext);
-    }
-
-    @Override
-    public void removeWebOrigin(String webOrigin) {
-        getMongoStore().pullItemFromList(application, "webOrigins", webOrigin, invocationContext);
-    }
-
-    @Override
-    public Set<String> getRedirectUris() {
-        Set<String> result = new HashSet<String>();
-        if (application.getRedirectUris() != null) {
-            result.addAll(application.getRedirectUris());
-        }
-        return result;
-    }
-
-    @Override
-    public void setRedirectUris(Set<String> redirectUris) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(redirectUris);
-        application.setRedirectUris(result);
-    }
-
-    @Override
-    public void addRedirectUri(String redirectUri) {
-        getMongoStore().pushItemToList(application, "redirectUris", redirectUri, true, invocationContext);
-    }
-
-    @Override
-    public void removeRedirectUri(String redirectUri) {
-        getMongoStore().pullItemFromList(application, "redirectUris", redirectUri, invocationContext);
-    }
-
-    @Override
-    public String getSecret() {
-        return application.getSecret();
-    }
-
-    @Override
-    public void setSecret(String secret) {
-        application.setSecret(secret);
-    }
-
-
-    @Override
-    public boolean validateSecret(String secret) {
-        return secret.equals(application.getSecret());
-    }
-
-
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
+import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
+import org.keycloak.models.mongo.keycloak.entities.UserEntity;
+import org.keycloak.models.mongo.utils.MongoModelUtils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ApplicationAdapter extends AbstractAdapter implements ApplicationModel {
+
+    private final ApplicationEntity application;
+    private final RealmModel realm;
+
+    public ApplicationAdapter(RealmModel realm, ApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) {
+        super(invContext);
+        this.application = applicationEntity;
+        this.realm = realm;
+    }
+
+    @Override
+    public void updateApplication() {
+        getMongoStore().updateEntity(application, invocationContext);
+    }
+
+    @Override
+    public String getId() {
+        return application.getId();
+    }
+
+    @Override
+    public String getClientId() {
+        return getName();
+    }
+
+    @Override
+    public String getName() {
+        return application.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        application.setName(name);
+    }
+
+    @Override
+    public RealmModel getRealm() {
+        return realm;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return application.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        application.setEnabled(enabled);
+    }
+
+    @Override
+    public boolean isSurrogateAuthRequired() {
+        return application.isSurrogateAuthRequired();
+    }
+
+    @Override
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        application.setSurrogateAuthRequired(surrogateAuthRequired);
+    }
+
+    @Override
+    public String getManagementUrl() {
+        return application.getManagementUrl();
+    }
+
+    @Override
+    public void setManagementUrl(String url) {
+        application.setManagementUrl(url);
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        application.setBaseUrl(url);
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return application.getBaseUrl();
+    }
+
+    @Override
+    public long getAllowedClaimsMask() {
+        return application.getAllowedClaimsMask();
+    }
+
+    @Override
+    public void setAllowedClaimsMask(long mask) {
+        application.setAllowedClaimsMask(mask);
+    }
+
+
+    @Override
+    public RoleAdapter getRole(String name) {
+        DBObject query = new QueryBuilder()
+                .and("name").is(name)
+                .and("applicationId").is(getId())
+                .get();
+        RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext);
+        if (role == null) {
+            return null;
+        } else {
+            return new RoleAdapter(getRealm(), role, invocationContext);
+        }
+    }
+
+    @Override
+    public RoleAdapter addRole(String name) {
+        RoleAdapter existing = getRole(name);
+        if (existing != null) {
+            return existing;
+        }
+
+        RoleEntity roleEntity = new RoleEntity();
+        roleEntity.setName(name);
+        roleEntity.setApplicationId(getId());
+
+        getMongoStore().insertEntity(roleEntity, invocationContext);
+        return new RoleAdapter(getRealm(), roleEntity, this, invocationContext);
+    }
+
+    @Override
+    public boolean removeRole(RoleModel role) {
+        return getMongoStore().removeEntity(RoleEntity.class, role.getId(), invocationContext);
+    }
+
+    @Override
+    public Set<RoleModel> getRoles() {
+        DBObject query = new QueryBuilder()
+                .and("applicationId").is(getId())
+                .get();
+        List<RoleEntity> roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext);
+
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        for (RoleEntity role : roles) {
+            result.add(new RoleAdapter(getRealm(), role, this, invocationContext));
+        }
+
+        return result;
+    }
+
+    @Override
+    public Set<RoleModel> getApplicationRoleMappings(UserModel user) {
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        List<RoleEntity> roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext);
+
+        for (RoleEntity role : roles) {
+            if (getId().equals(role.getApplicationId())) {
+                result.add(new RoleAdapter(getRealm(), role, this, invocationContext));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void addScope(RoleModel role) {
+        getMongoStore().pushItemToList(application, "scopeIds", role.getId(), true, invocationContext);
+    }
+
+    @Override
+    public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        List<RoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
+
+        for (RoleEntity role : roles) {
+            if (getId().equals(role.getApplicationId())) {
+                result.add(new RoleAdapter(getRealm(), role, this, invocationContext));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        return application.getDefaultRoles();
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        RoleModel role = getRole(name);
+        if (role == null) {
+            addRole(name);
+        }
+
+        getMongoStore().pushItemToList(application, "defaultRoles", name, true, invocationContext);
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        List<String> roleNames = new ArrayList<String>();
+        for (String roleName : defaultRoles) {
+            RoleModel role = getRole(roleName);
+            if (role == null) {
+                addRole(roleName);
+            }
+
+            roleNames.add(roleName);
+        }
+
+        application.setDefaultRoles(roleNames);
+    }
+
+    @Override
+    public AbstractMongoIdentifiableEntity getMongoEntity() {
+        return application;
+    }
+
+    @Override
+    public Set<String> getWebOrigins() {
+        Set<String> result = new HashSet<String>();
+        if (application.getWebOrigins() != null) {
+            result.addAll(application.getWebOrigins());
+        }
+        return result;
+    }
+
+    @Override
+    public void setWebOrigins(Set<String> webOrigins) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(webOrigins);
+        application.setWebOrigins(result);
+    }
+
+    @Override
+    public void addWebOrigin(String webOrigin) {
+        getMongoStore().pushItemToList(application, "webOrigins", webOrigin, true, invocationContext);
+    }
+
+    @Override
+    public void removeWebOrigin(String webOrigin) {
+        getMongoStore().pullItemFromList(application, "webOrigins", webOrigin, invocationContext);
+    }
+
+    @Override
+    public Set<String> getRedirectUris() {
+        Set<String> result = new HashSet<String>();
+        if (application.getRedirectUris() != null) {
+            result.addAll(application.getRedirectUris());
+        }
+        return result;
+    }
+
+    @Override
+    public void setRedirectUris(Set<String> redirectUris) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(redirectUris);
+        application.setRedirectUris(result);
+    }
+
+    @Override
+    public void addRedirectUri(String redirectUri) {
+        getMongoStore().pushItemToList(application, "redirectUris", redirectUri, true, invocationContext);
+    }
+
+    @Override
+    public void removeRedirectUri(String redirectUri) {
+        getMongoStore().pullItemFromList(application, "redirectUris", redirectUri, invocationContext);
+    }
+
+    @Override
+    public String getSecret() {
+        return application.getSecret();
+    }
+
+    @Override
+    public void setSecret(String secret) {
+        application.setSecret(secret);
+    }
+
+
+    @Override
+    public boolean validateSecret(String secret) {
+        return secret.equals(application.getSecret());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ApplicationAdapter)) return false;
+        if (!super.equals(o)) return false;
+
+        ApplicationAdapter that = (ApplicationAdapter) o;
+
+        if (!application.getId().equals(that.application.getId())) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return application.getId().hashCode();
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
index 1420a09..c90fe01 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
@@ -1,100 +1,100 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import com.mongodb.BasicDBObject;
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.MongoStore;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
-import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
-import org.keycloak.models.utils.KeycloakModelUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MongoKeycloakSession implements KeycloakSession {
-
-    private final MongoStoreInvocationContext invocationContext;
-    private final MongoKeycloakTransaction transaction;
-
-    public MongoKeycloakSession(MongoStore mongoStore) {
-        // this.invocationContext = new SimpleMongoStoreInvocationContext(mongoStore);
-        this.invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
-        this.transaction = new MongoKeycloakTransaction(invocationContext);
-    }
-
-    @Override
-    public KeycloakTransaction getTransaction() {
-        return transaction;
-    }
-
-    @Override
-    public void close() {
-        // TODO
-    }
-
-    @Override
-    public RealmModel createRealm(String name) {
-        return createRealm(KeycloakModelUtils.generateId(), name);
-    }
-
-    @Override
-    public RealmModel createRealm(String id, String name) {
-        if (getRealm(id) != null) {
-            throw new IllegalStateException("Realm with id '" + id + "' already exists");
-        }
-
-        RealmEntity newRealm = new RealmEntity();
-        newRealm.setId(id);
-        newRealm.setName(name);
-
-        getMongoStore().insertEntity(newRealm, invocationContext);
-
-        return new RealmAdapter(newRealm, invocationContext);
-    }
-
-    @Override
-    public RealmModel getRealm(String id) {
-        RealmEntity realmEntity = getMongoStore().loadEntity(RealmEntity.class, id, invocationContext);
-        return realmEntity != null ? new RealmAdapter(realmEntity, invocationContext) : null;
-    }
-
-    @Override
-    public List<RealmModel> getRealms() {
-        DBObject query = new BasicDBObject();
-        List<RealmEntity> realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext);
-
-        List<RealmModel> results = new ArrayList<RealmModel>();
-        for (RealmEntity realmEntity : realms) {
-            results.add(new RealmAdapter(realmEntity, invocationContext));
-        }
-        return results;
-    }
-
-    @Override
-    public RealmModel getRealmByName(String name) {
-        DBObject query = new QueryBuilder()
-                .and("name").is(name)
-                .get();
-        RealmEntity realm = getMongoStore().loadSingleEntity(RealmEntity.class, query, invocationContext);
-
-        if (realm == null) return null;
-        return new RealmAdapter(realm, invocationContext);
-    }
-
-    @Override
-    public boolean removeRealm(String id) {
-        return getMongoStore().removeEntity(RealmEntity.class, id, invocationContext);
-    }
-
-    protected MongoStore getMongoStore() {
-        return invocationContext.getMongoStore();
-    }
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.MongoStore;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
+import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
+import org.keycloak.models.utils.KeycloakModelUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoKeycloakSession implements KeycloakSession {
+
+    private final MongoStoreInvocationContext invocationContext;
+    private final MongoKeycloakTransaction transaction;
+
+    public MongoKeycloakSession(MongoStore mongoStore) {
+        // this.invocationContext = new SimpleMongoStoreInvocationContext(mongoStore);
+        this.invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
+        this.transaction = new MongoKeycloakTransaction(invocationContext);
+    }
+
+    @Override
+    public KeycloakTransaction getTransaction() {
+        return transaction;
+    }
+
+    @Override
+    public void close() {
+        // TODO
+    }
+
+    @Override
+    public RealmModel createRealm(String name) {
+        return createRealm(KeycloakModelUtils.generateId(), name);
+    }
+
+    @Override
+    public RealmModel createRealm(String id, String name) {
+        if (getRealm(id) != null) {
+            throw new IllegalStateException("Realm with id '" + id + "' already exists");
+        }
+
+        RealmEntity newRealm = new RealmEntity();
+        newRealm.setId(id);
+        newRealm.setName(name);
+
+        getMongoStore().insertEntity(newRealm, invocationContext);
+
+        return new RealmAdapter(newRealm, invocationContext);
+    }
+
+    @Override
+    public RealmModel getRealm(String id) {
+        RealmEntity realmEntity = getMongoStore().loadEntity(RealmEntity.class, id, invocationContext);
+        return realmEntity != null ? new RealmAdapter(realmEntity, invocationContext) : null;
+    }
+
+    @Override
+    public List<RealmModel> getRealms() {
+        DBObject query = new BasicDBObject();
+        List<RealmEntity> realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext);
+
+        List<RealmModel> results = new ArrayList<RealmModel>();
+        for (RealmEntity realmEntity : realms) {
+            results.add(new RealmAdapter(realmEntity, invocationContext));
+        }
+        return results;
+    }
+
+    @Override
+    public RealmModel getRealmByName(String name) {
+        DBObject query = new QueryBuilder()
+                .and("name").is(name)
+                .get();
+        RealmEntity realm = getMongoStore().loadSingleEntity(RealmEntity.class, query, invocationContext);
+
+        if (realm == null) return null;
+        return new RealmAdapter(realm, invocationContext);
+    }
+
+    @Override
+    public boolean removeRealm(String id) {
+        return getMongoStore().removeEntity(RealmEntity.class, id, invocationContext);
+    }
+
+    protected MongoStore getMongoStore() {
+        return invocationContext.getMongoStore();
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java
index 7ff4ead..563dba4 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java
@@ -1,70 +1,70 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import com.mongodb.DB;
-import com.mongodb.MongoClient;
-import org.jboss.logging.Logger;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoStore;
-import org.keycloak.models.mongo.impl.MongoStoreImpl;
-import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
-import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
-import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
-import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
-import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
-import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
-import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
-import org.keycloak.models.mongo.keycloak.entities.UserEntity;
-import org.keycloak.models.mongo.utils.MongoConfiguration;
-
-import java.net.UnknownHostException;
-
-/**
- * KeycloakSessionFactory implementation based on MongoDB
- *
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MongoKeycloakSessionFactory implements KeycloakSessionFactory {
-    protected static final Logger logger = Logger.getLogger(MongoKeycloakSessionFactory.class);
-
-    private static final Class<? extends MongoEntity>[] MANAGED_ENTITY_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
-            RealmEntity.class,
-            UserEntity.class,
-            RoleEntity.class,
-            RequiredCredentialEntity.class,
-            CredentialEntity.class,
-            SocialLinkEntity.class,
-            ApplicationEntity.class,
-            OAuthClientEntity.class
-    };
-
-    private final MongoClient mongoClient;
-    private final MongoStore mongoStore;
-
-    public MongoKeycloakSessionFactory(MongoConfiguration config) {
-        logger.info(String.format("Configuring MongoStore with: " + config));
-
-        try {
-            // TODO: authentication support
-            mongoClient = new MongoClient(config.getHost(), config.getPort());
-
-            DB db = mongoClient.getDB(config.getDbName());
-            mongoStore = new MongoStoreImpl(db, config.isClearCollectionsOnStartup(), MANAGED_ENTITY_TYPES);
-
-        } catch (UnknownHostException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Override
-    public KeycloakSession createSession() {
-        return new MongoKeycloakSession(mongoStore);
-    }
-
-    @Override
-    public void close() {
-        logger.info("Closing MongoDB client");
-        mongoClient.close();
-    }
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import com.mongodb.DB;
+import com.mongodb.MongoClient;
+import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoStore;
+import org.keycloak.models.mongo.impl.MongoStoreImpl;
+import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
+import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
+import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
+import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
+import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
+import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
+import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
+import org.keycloak.models.mongo.keycloak.entities.UserEntity;
+import org.keycloak.models.mongo.utils.MongoConfiguration;
+
+import java.net.UnknownHostException;
+
+/**
+ * KeycloakSessionFactory implementation based on MongoDB
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoKeycloakSessionFactory implements KeycloakSessionFactory {
+    protected static final Logger logger = Logger.getLogger(MongoKeycloakSessionFactory.class);
+
+    private static final Class<? extends MongoEntity>[] MANAGED_ENTITY_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
+            RealmEntity.class,
+            UserEntity.class,
+            RoleEntity.class,
+            RequiredCredentialEntity.class,
+            CredentialEntity.class,
+            SocialLinkEntity.class,
+            ApplicationEntity.class,
+            OAuthClientEntity.class
+    };
+
+    private final MongoClient mongoClient;
+    private final MongoStore mongoStore;
+
+    public MongoKeycloakSessionFactory(MongoConfiguration config) {
+        logger.info(String.format("Configuring MongoStore with: " + config));
+
+        try {
+            // TODO: authentication support
+            mongoClient = new MongoClient(config.getHost(), config.getPort());
+
+            DB db = mongoClient.getDB(config.getDbName());
+            mongoStore = new MongoStoreImpl(db, config.isClearCollectionsOnStartup(), MANAGED_ENTITY_TYPES);
+
+        } catch (UnknownHostException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public KeycloakSession createSession() {
+        return new MongoKeycloakSession(mongoStore);
+    }
+
+    @Override
+    public void close() {
+        logger.info("Closing MongoDB client");
+        mongoClient.close();
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
index cbdbec6..32a877d 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
@@ -1,131 +1,139 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import org.keycloak.models.OAuthClientModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
-import org.keycloak.models.mongo.keycloak.entities.UserEntity;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientModel {
-
-    private final OAuthClientEntity delegate;
-
-    public OAuthClientAdapter(OAuthClientEntity oauthClientEntity, MongoStoreInvocationContext invContext) {
-        super(invContext);
-        this.delegate = oauthClientEntity;
-    }
-
-    @Override
-    public String getId() {
-        return delegate.getId();
-    }
-
-    @Override
-    public String getClientId() {
-        return delegate.getName();
-    }
-
-    @Override
-    public long getAllowedClaimsMask() {
-        return delegate.getAllowedClaimsMask();
-    }
-
-    @Override
-    public void setAllowedClaimsMask(long mask) {
-        delegate.setAllowedClaimsMask(mask);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return delegate.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        delegate.setEnabled(enabled);
-    }
-
-    @Override
-    public AbstractMongoIdentifiableEntity getMongoEntity() {
-        return delegate;
-    }
-
-    @Override
-    public Set<String> getWebOrigins() {
-        Set<String> result = new HashSet<String>();
-        if (delegate.getWebOrigins() != null) {
-            result.addAll(delegate.getWebOrigins());
-        }
-        return result;
-    }
-
-    @Override
-    public void setWebOrigins(Set<String> webOrigins) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(webOrigins);
-        delegate.setWebOrigins(result);
-    }
-
-    @Override
-    public void addWebOrigin(String webOrigin) {
-        getMongoStore().pushItemToList(delegate, "webOrigins", webOrigin, true, invocationContext);
-    }
-
-    @Override
-    public void removeWebOrigin(String webOrigin) {
-        getMongoStore().pullItemFromList(delegate, "webOrigins", webOrigin, invocationContext);
-    }
-
-    @Override
-    public Set<String> getRedirectUris() {
-        Set<String> result = new HashSet<String>();
-        if (delegate.getRedirectUris() != null) {
-            result.addAll(delegate.getRedirectUris());
-        }
-        return result;
-    }
-
-    @Override
-    public void setRedirectUris(Set<String> redirectUris) {
-        List<String> result = new ArrayList<String>();
-        result.addAll(redirectUris);
-        delegate.setRedirectUris(result);
-    }
-
-    @Override
-    public void addRedirectUri(String redirectUri) {
-        getMongoStore().pushItemToList(delegate, "redirectUris", redirectUri, true, invocationContext);
-    }
-
-    @Override
-    public void removeRedirectUri(String redirectUri) {
-        getMongoStore().pullItemFromList(delegate, "redirectUris", redirectUri, invocationContext);
-    }
-
-    @Override
-    public String getSecret() {
-        return delegate.getSecret();
-    }
-
-    @Override
-    public void setSecret(String secret) {
-        delegate.setSecret(secret);
-    }
-
-
-    @Override
-    public boolean validateSecret(String secret) {
-        return secret.equals(delegate.getSecret());
-    }
-
-
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
+import org.keycloak.models.mongo.keycloak.entities.UserEntity;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientModel {
+
+    private final OAuthClientEntity delegate;
+    private final RealmModel realm;
+
+    public OAuthClientAdapter(RealmModel realm, OAuthClientEntity oauthClientEntity, MongoStoreInvocationContext invContext) {
+        super(invContext);
+        this.delegate = oauthClientEntity;
+        this.realm = realm;
+    }
+
+    @Override
+    public String getId() {
+        return delegate.getId();
+    }
+
+    @Override
+    public String getClientId() {
+        return delegate.getName();
+    }
+
+    @Override
+    public RealmModel getRealm() {
+        return realm;
+    }
+
+    @Override
+    public long getAllowedClaimsMask() {
+        return delegate.getAllowedClaimsMask();
+    }
+
+    @Override
+    public void setAllowedClaimsMask(long mask) {
+        delegate.setAllowedClaimsMask(mask);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return delegate.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        delegate.setEnabled(enabled);
+    }
+
+    @Override
+    public AbstractMongoIdentifiableEntity getMongoEntity() {
+        return delegate;
+    }
+
+    @Override
+    public Set<String> getWebOrigins() {
+        Set<String> result = new HashSet<String>();
+        if (delegate.getWebOrigins() != null) {
+            result.addAll(delegate.getWebOrigins());
+        }
+        return result;
+    }
+
+    @Override
+    public void setWebOrigins(Set<String> webOrigins) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(webOrigins);
+        delegate.setWebOrigins(result);
+    }
+
+    @Override
+    public void addWebOrigin(String webOrigin) {
+        getMongoStore().pushItemToList(delegate, "webOrigins", webOrigin, true, invocationContext);
+    }
+
+    @Override
+    public void removeWebOrigin(String webOrigin) {
+        getMongoStore().pullItemFromList(delegate, "webOrigins", webOrigin, invocationContext);
+    }
+
+    @Override
+    public Set<String> getRedirectUris() {
+        Set<String> result = new HashSet<String>();
+        if (delegate.getRedirectUris() != null) {
+            result.addAll(delegate.getRedirectUris());
+        }
+        return result;
+    }
+
+    @Override
+    public void setRedirectUris(Set<String> redirectUris) {
+        List<String> result = new ArrayList<String>();
+        result.addAll(redirectUris);
+        delegate.setRedirectUris(result);
+    }
+
+    @Override
+    public void addRedirectUri(String redirectUri) {
+        getMongoStore().pushItemToList(delegate, "redirectUris", redirectUri, true, invocationContext);
+    }
+
+    @Override
+    public void removeRedirectUri(String redirectUri) {
+        getMongoStore().pullItemFromList(delegate, "redirectUris", redirectUri, invocationContext);
+    }
+
+    @Override
+    public String getSecret() {
+        return delegate.getSecret();
+    }
+
+    @Override
+    public void setSecret(String secret) {
+        delegate.setSecret(secret);
+    }
+
+
+    @Override
+    public boolean validateSecret(String secret) {
+        return secret.equals(delegate.getSecret());
+    }
+
+
+}
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 ff941b9..22acd3f 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -1,1008 +1,1016 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.jboss.logging.Logger;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-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.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
-import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
-import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
-import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
-import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
-import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
-import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
-import org.keycloak.models.mongo.keycloak.entities.UserEntity;
-import org.keycloak.models.mongo.utils.MongoModelUtils;
-import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
-import org.keycloak.models.utils.TimeBasedOTP;
-
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class RealmAdapter extends AbstractAdapter implements RealmModel {
-
-    private static final Logger logger = Logger.getLogger(RealmAdapter.class);
-
-    private final RealmEntity realm;
-
-    protected volatile transient PublicKey publicKey;
-    protected volatile transient PrivateKey privateKey;
-
-    private volatile transient PasswordPolicy passwordPolicy;
-
-    public RealmAdapter(RealmEntity realmEntity, MongoStoreInvocationContext invocationContext) {
-        super(invocationContext);
-        this.realm = realmEntity;
-    }
-
-    @Override
-    public String getId() {
-        return realm.getId();
-    }
-
-    @Override
-    public String getName() {
-        return realm.getName();
-    }
-
-    @Override
-    public void setName(String name) {
-        realm.setName(name);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return realm.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        realm.setEnabled(enabled);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isSslNotRequired() {
-        return realm.isSslNotRequired();
-    }
-
-    @Override
-    public void setSslNotRequired(boolean sslNotRequired) {
-        realm.setSslNotRequired(sslNotRequired);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isRegistrationAllowed() {
-        return realm.isRegistrationAllowed();
-    }
-
-    @Override
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        realm.setRegistrationAllowed(registrationAllowed);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isRememberMe() {
-        return realm.isRememberMe();
-    }
-
-    @Override
-    public void setRememberMe(boolean rememberMe) {
-        realm.setRememberMe(rememberMe);
-        updateRealm();
-    }
-
-
-    @Override
-    public boolean isVerifyEmail() {
-        return realm.isVerifyEmail();
-    }
-
-    @Override
-    public void setVerifyEmail(boolean verifyEmail) {
-        realm.setVerifyEmail(verifyEmail);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isResetPasswordAllowed() {
-        return realm.isResetPasswordAllowed();
-    }
-
-    @Override
-    public void setResetPasswordAllowed(boolean resetPassword) {
-        realm.setResetPasswordAllowed(resetPassword);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isSocial() {
-        return realm.isSocial();
-    }
-
-    @Override
-    public void setSocial(boolean social) {
-        realm.setSocial(social);
-        updateRealm();
-    }
-
-    @Override
-    public boolean isUpdateProfileOnInitialSocialLogin() {
-        return realm.isUpdateProfileOnInitialSocialLogin();
-    }
-
-    @Override
-    public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
-        realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin);
-        updateRealm();
-    }
-
-    @Override
-    public PasswordPolicy getPasswordPolicy() {
-        if (passwordPolicy == null) {
-            passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
-        }
-        return passwordPolicy;
-    }
-
-    @Override
-    public void setPasswordPolicy(PasswordPolicy policy) {
-        this.passwordPolicy = policy;
-        realm.setPasswordPolicy(policy.toString());
-        updateRealm();
-    }
-
-    @Override
-    public int getNotBefore() {
-        return realm.getNotBefore();
-    }
-
-    @Override
-    public void setNotBefore(int notBefore) {
-        realm.setNotBefore(notBefore);
-    }
-
-
-    @Override
-    public int getAccessTokenLifespan() {
-        return realm.getAccessTokenLifespan();
-    }
-
-    @Override
-    public void setAccessTokenLifespan(int tokenLifespan) {
-        realm.setAccessTokenLifespan(tokenLifespan);
-        updateRealm();
-    }
-
-    @Override
-    public int getCentralLoginLifespan() {
-        return realm.getCentralLoginLifespan();
-    }
-
-    @Override
-    public void setCentralLoginLifespan(int lifespan) {
-        realm.setCentralLoginLifespan(lifespan);
-        updateRealm();
-    }
-
-
-    @Override
-    public int getRefreshTokenLifespan() {
-        return realm.getRefreshTokenLifespan();
-    }
-
-    @Override
-    public void setRefreshTokenLifespan(int tokenLifespan) {
-        realm.setRefreshTokenLifespan(tokenLifespan);
-        updateRealm();
-    }
-
-    @Override
-    public int getAccessCodeLifespan() {
-        return realm.getAccessCodeLifespan();
-    }
-
-    @Override
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        realm.setAccessCodeLifespan(accessCodeLifespan);
-        updateRealm();
-    }
-
-    @Override
-    public int getAccessCodeLifespanUserAction() {
-        return realm.getAccessCodeLifespanUserAction();
-    }
-
-    @Override
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
-        updateRealm();
-    }
-
-    @Override
-    public String getPublicKeyPem() {
-        return realm.getPublicKeyPem();
-    }
-
-    @Override
-    public void setPublicKeyPem(String publicKeyPem) {
-        realm.setPublicKeyPem(publicKeyPem);
-        this.publicKey = null;
-        updateRealm();
-    }
-
-    @Override
-    public String getPrivateKeyPem() {
-        return realm.getPrivateKeyPem();
-    }
-
-    @Override
-    public void setPrivateKeyPem(String privateKeyPem) {
-        realm.setPrivateKeyPem(privateKeyPem);
-        this.privateKey = null;
-        updateRealm();
-    }
-
-    @Override
-    public PublicKey getPublicKey() {
-        if (publicKey != null) return publicKey;
-        publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
-        return publicKey;
-    }
-
-    @Override
-    public void setPublicKey(PublicKey publicKey) {
-        this.publicKey = publicKey;
-        String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
-        setPublicKeyPem(publicKeyPem);
-    }
-
-    @Override
-    public PrivateKey getPrivateKey() {
-        if (privateKey != null) return privateKey;
-        privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
-        return privateKey;
-    }
-
-    @Override
-    public void setPrivateKey(PrivateKey privateKey) {
-        this.privateKey = privateKey;
-        String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
-        setPrivateKeyPem(privateKeyPem);
-    }
-
-    @Override
-    public String getLoginTheme() {
-        return realm.getLoginTheme();
-    }
-
-    @Override
-    public void setLoginTheme(String name) {
-        realm.setLoginTheme(name);
-        updateRealm();
-    }
-
-    @Override
-    public String getAccountTheme() {
-        return realm.getAccountTheme();
-    }
-
-    @Override
-    public void setAccountTheme(String name) {
-        realm.setAccountTheme(name);
-        updateRealm();
-    }
-
-    @Override
-    public UserAdapter getUser(String name) {
-        DBObject query = new QueryBuilder()
-                .and("loginName").is(name)
-                .and("realmId").is(getId())
-                .get();
-        UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
-
-        if (user == null) {
-            return null;
-        } else {
-            return new UserAdapter(user, invocationContext);
-        }
-    }
-
-    @Override
-    public UserModel getUserByEmail(String email) {
-        DBObject query = new QueryBuilder()
-                .and("email").is(email)
-                .and("realmId").is(getId())
-                .get();
-        UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
-
-        if (user == null) {
-            return null;
-        } else {
-            return new UserAdapter(user, invocationContext);
-        }
-    }
-
-    @Override
-    public UserModel getUserById(String id) {
-        UserEntity user = getMongoStore().loadEntity(UserEntity.class, id, invocationContext);
-
-        // Check that it's user from this realm
-        if (user == null || !getId().equals(user.getRealmId())) {
-            return null;
-        } else {
-            return new UserAdapter(user, invocationContext);
-        }
-    }
-
-    @Override
-    public UserAdapter addUser(String username) {
-        UserAdapter userModel = addUserEntity(username);
-
-        for (String r : getDefaultRoles()) {
-            grantRole(userModel, getRole(r));
-        }
-
-        for (ApplicationModel application : getApplications()) {
-            for (String r : application.getDefaultRoles()) {
-                grantRole(userModel, application.getRole(r));
-            }
-        }
-
-        return userModel;
-    }
-
-    // Add just user entity without defaultRoles
-    protected UserAdapter addUserEntity(String username) {
-        if (getUser(username) != null) {
-            throw new IllegalArgumentException("User " + username + " already exists");
-        }
-
-        UserEntity userEntity = new UserEntity();
-        userEntity.setLoginName(username);
-        userEntity.setEnabled(true);
-        userEntity.setRealmId(getId());
-
-        getMongoStore().insertEntity(userEntity, invocationContext);
-        return new UserAdapter(userEntity, invocationContext);
-    }
-
-    @Override
-    public boolean removeUser(String name) {
-        DBObject query = new QueryBuilder()
-                .and("loginName").is(name)
-                .and("realmId").is(getId())
-                .get();
-        return getMongoStore().removeEntities(UserEntity.class, query, invocationContext);
-    }
-
-    @Override
-    public RoleAdapter getRole(String name) {
-        DBObject query = new QueryBuilder()
-                .and("name").is(name)
-                .and("realmId").is(getId())
-                .get();
-        RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext);
-        if (role == null) {
-            return null;
-        } else {
-            return new RoleAdapter(role, this, invocationContext);
-        }
-    }
-
-    @Override
-    public RoleModel addRole(String name) {
-        RoleAdapter role = getRole(name);
-        if (role != null) {
-            // Compatibility with JPA model
-            return role;
-            // throw new IllegalArgumentException("Role " + name + " already exists");
-        }
-
-        RoleEntity roleEntity = new RoleEntity();
-        roleEntity.setName(name);
-        roleEntity.setRealmId(getId());
-
-        getMongoStore().insertEntity(roleEntity, invocationContext);
-        return new RoleAdapter(roleEntity, this, invocationContext);
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public Set<RoleModel> getRoles() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<RoleEntity> roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext);
-
-        Set<RoleModel> result = new HashSet<RoleModel>();
-
-        if (roles == null) return result;
-        for (RoleEntity role : roles) {
-            result.add(new RoleAdapter(role, this, invocationContext));
-        }
-
-        return result;
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext);
-        if (role == null || !getId().equals(role.getRealmId())) {
-            return null;
-        } else {
-            return new RoleAdapter(role, this, invocationContext);
-        }
-    }
-
-    @Override
-    public List<String> getDefaultRoles() {
-        return realm.getDefaultRoles();
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        RoleModel role = getRole(name);
-        if (role == null) {
-            addRole(name);
-        }
-
-        getMongoStore().pushItemToList(realm, "defaultRoles", name, true, invocationContext);
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        List<String> roleNames = new ArrayList<String>();
-        for (String roleName : defaultRoles) {
-            RoleModel role = getRole(roleName);
-            if (role == null) {
-                addRole(roleName);
-            }
-
-            roleNames.add(roleName);
-        }
-
-        realm.setDefaultRoles(roleNames);
-        updateRealm();
-    }
-
-    @Override
-    public ClientModel findClient(String clientId) {
-        ClientModel model = getApplicationByName(clientId);
-        if (model != null) return model;
-        return getOAuthClient(clientId);
-    }
-
-
-    @Override
-    public ApplicationModel getApplicationById(String id) {
-        ApplicationEntity appData = getMongoStore().loadEntity(ApplicationEntity.class, id, invocationContext);
-
-        // Check if application belongs to this realm
-        if (appData == null || !getId().equals(appData.getRealmId())) {
-            return null;
-        }
-
-        return new ApplicationAdapter(appData, invocationContext);
-    }
-
-    @Override
-    public ApplicationModel getApplicationByName(String name) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .and("name").is(name)
-                .get();
-        ApplicationEntity appEntity = getMongoStore().loadSingleEntity(ApplicationEntity.class, query, invocationContext);
-        return appEntity==null ? null : new ApplicationAdapter(appEntity, invocationContext);
-    }
-
-    @Override
-    public Map<String, ApplicationModel> getApplicationNameMap() {
-        Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
-        for (ApplicationModel resource : getApplications()) {
-            resourceMap.put(resource.getName(), resource);
-        }
-        return resourceMap;
-    }
-
-    @Override
-    public List<ApplicationModel> getApplications() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<ApplicationEntity> appDatas = getMongoStore().loadEntities(ApplicationEntity.class, query, invocationContext);
-
-        List<ApplicationModel> result = new ArrayList<ApplicationModel>();
-        for (ApplicationEntity appData : appDatas) {
-            result.add(new ApplicationAdapter(appData, invocationContext));
-        }
-        return result;
-    }
-
-    @Override
-    public ApplicationModel addApplication(String name) {
-        ApplicationEntity appData = new ApplicationEntity();
-        appData.setName(name);
-        appData.setRealmId(getId());
-        appData.setEnabled(true);
-        getMongoStore().insertEntity(appData, invocationContext);
-
-        return new ApplicationAdapter(appData, invocationContext);
-    }
-
-    @Override
-    public boolean removeApplication(String id) {
-        return getMongoStore().removeEntity(ApplicationEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public boolean hasRole(UserModel user, RoleModel role) {
-        Set<RoleModel> roles = getRoleMappings(user);
-        if (roles.contains(role)) return true;
-
-        for (RoleModel mapping : roles) {
-            if (mapping.hasRole(role)) return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void grantRole(UserModel user, RoleModel role) {
-        UserEntity userEntity = ((UserAdapter)user).getUser();
-        getMongoStore().pushItemToList(userEntity, "roleIds", role.getId(), true, invocationContext);
-    }
-
-    @Override
-    public Set<RoleModel> getRoleMappings(UserModel user) {
-        Set<RoleModel> result = new HashSet<RoleModel>();
-        List<RoleEntity> roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext);
-
-        for (RoleEntity role : roles) {
-            if (getId().equals(role.getRealmId())) {
-                result.add(new RoleAdapter(role, this, invocationContext));
-            } else {
-                // Likely applicationRole, but we don't have this application yet
-                result.add(new RoleAdapter(role, invocationContext));
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public Set<RoleModel> getRealmRoleMappings(UserModel user) {
-        Set<RoleModel> allRoles = getRoleMappings(user);
-
-        // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user?
-        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
-        for (RoleModel role : allRoles) {
-            RoleEntity roleEntity = ((RoleAdapter)role).getRole();
-
-            if (getId().equals(roleEntity.getRealmId())) {
-                realmRoles.add(role);
-            }
-        }
-        return realmRoles;
-    }
-
-    @Override
-    public void deleteRoleMapping(UserModel user, RoleModel role) {
-        if (user == null || role == null) return;
-
-        UserEntity userEntity = ((UserAdapter)user).getUser();
-        getMongoStore().pullItemFromList(userEntity, "roleIds", role.getId(), invocationContext);
-    }
-
-    @Override
-    public Set<RoleModel> getScopeMappings(ClientModel client) {
-        Set<RoleModel> result = new HashSet<RoleModel>();
-        List<RoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
-
-        for (RoleEntity role : roles) {
-            if (getId().equals(role.getRealmId())) {
-                result.add(new RoleAdapter(role, this, invocationContext));
-            } else {
-                // Likely applicationRole, but we don't have this application yet
-                result.add(new RoleAdapter(role, invocationContext));
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public Set<RoleModel> getRealmScopeMappings(ClientModel client) {
-        Set<RoleModel> allScopes = getScopeMappings(client);
-
-        // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user?
-        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
-        for (RoleModel role : allScopes) {
-            RoleEntity roleEntity = ((RoleAdapter)role).getRole();
-
-            if (getId().equals(roleEntity.getRealmId())) {
-                realmRoles.add(role);
-            }
-        }
-        return realmRoles;
-    }
-
-    @Override
-    public boolean hasScope(ClientModel client, RoleModel role) {
-        Set<RoleModel> roles = getScopeMappings(client);
-        if (roles.contains(role)) return true;
-
-        for (RoleModel mapping : roles) {
-            if (mapping.hasRole(role)) return true;
-        }
-        return false;
-    }
-
-
-    @Override
-    public void addScopeMapping(ClientModel client, RoleModel role) {
-        getMongoStore().pushItemToList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), true, invocationContext);
-    }
-
-    @Override
-    public void deleteScopeMapping(ClientModel client, RoleModel role) {
-        getMongoStore().pullItemFromList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel addOAuthClient(String name) {
-        OAuthClientEntity oauthClient = new OAuthClientEntity();
-        oauthClient.setRealmId(getId());
-        oauthClient.setName(name);
-        getMongoStore().insertEntity(oauthClient, invocationContext);
-
-        return new OAuthClientAdapter(oauthClient, invocationContext);
-    }
-
-    @Override
-    public boolean removeOAuthClient(String id) {
-        return getMongoStore().removeEntity(OAuthClientEntity.class, id, invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClient(String name) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .and("name").is(name)
-                .get();
-        OAuthClientEntity oauthClient = getMongoStore().loadSingleEntity(OAuthClientEntity.class, query, invocationContext);
-        return oauthClient == null ? null : new OAuthClientAdapter(oauthClient, invocationContext);
-    }
-
-    @Override
-    public OAuthClientModel getOAuthClientById(String id) {
-        OAuthClientEntity clientEntity = getMongoStore().loadEntity(OAuthClientEntity.class, id, invocationContext);
-
-        // Check if client belongs to this realm
-        if (clientEntity == null || !getId().equals(clientEntity.getRealmId())) return null;
-
-        return new OAuthClientAdapter(clientEntity, invocationContext);
-    }
-
-    @Override
-    public List<OAuthClientModel> getOAuthClients() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<OAuthClientEntity> results = getMongoStore().loadEntities(OAuthClientEntity.class, query, invocationContext);
-        List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
-        for (OAuthClientEntity data : results) {
-            list.add(new OAuthClientAdapter(data, invocationContext));
-        }
-        return list;
-    }
-
-    @Override
-    public void addRequiredCredential(String type) {
-        RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
-        addRequiredCredential(credentialModel, realm.getRequiredCredentials());
-    }
-
-    protected void addRequiredCredential(RequiredCredentialModel credentialModel, List<RequiredCredentialEntity> persistentCollection) {
-        RequiredCredentialEntity credEntity = new RequiredCredentialEntity();
-        credEntity.setType(credentialModel.getType());
-        credEntity.setFormLabel(credentialModel.getFormLabel());
-        credEntity.setInput(credentialModel.isInput());
-        credEntity.setSecret(credentialModel.isSecret());
-
-        persistentCollection.add(credEntity);
-
-        updateRealm();
-    }
-
-    @Override
-    public void updateRequiredCredentials(Set<String> creds) {
-        updateRequiredCredentials(creds, realm.getRequiredCredentials());
-    }
-
-    protected void updateRequiredCredentials(Set<String> creds, List<RequiredCredentialEntity> credsEntities) {
-        Set<String> already = new HashSet<String>();
-        Set<RequiredCredentialEntity> toRemove = new HashSet<RequiredCredentialEntity>();
-        for (RequiredCredentialEntity entity : credsEntities) {
-            if (!creds.contains(entity.getType())) {
-                toRemove.add(entity);
-            } else {
-                already.add(entity.getType());
-            }
-        }
-        for (RequiredCredentialEntity entity : toRemove) {
-            credsEntities.remove(entity);
-        }
-        for (String cred : creds) {
-            logger.info("updating cred: " + cred);
-            if (!already.contains(cred)) {
-                RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred);
-                addRequiredCredential(credentialModel, credsEntities);
-            }
-        }
-    }
-
-    @Override
-    public List<RequiredCredentialModel> getRequiredCredentials() {
-        return convertRequiredCredentialEntities(realm.getRequiredCredentials());
-    }
-
-    protected List<RequiredCredentialModel> convertRequiredCredentialEntities(Collection<RequiredCredentialEntity> credEntities) {
-
-        List<RequiredCredentialModel> result = new ArrayList<RequiredCredentialModel>();
-        for (RequiredCredentialEntity entity : credEntities) {
-            RequiredCredentialModel model = new RequiredCredentialModel();
-            model.setFormLabel(entity.getFormLabel());
-            model.setInput(entity.isInput());
-            model.setSecret(entity.isSecret());
-            model.setType(entity.getType());
-
-            result.add(model);
-        }
-        return result;
-    }
-
-    @Override
-    public boolean validatePassword(UserModel user, String password) {
-        for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
-            if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
-                return new Pbkdf2PasswordEncoder(cred.getSalt()).verify(password, cred.getValue());
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean validateTOTP(UserModel user, String password, String token) {
-        if (!validatePassword(user, password)) return false;
-        for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
-            if (cred.getType().equals(UserCredentialModel.TOTP)) {
-                return new TimeBasedOTP().validate(token, cred.getValue().getBytes());
-            }
-        }
-        return false;
-    }
-
-
-    @Override
-    public void updateCredential(UserModel user, UserCredentialModel cred) {
-        CredentialEntity credentialEntity = null;
-        UserEntity userEntity = ((UserAdapter) user).getUser();
-        for (CredentialEntity entity : userEntity.getCredentials()) {
-            if (entity.getType().equals(cred.getType())) {
-                credentialEntity = entity;
-            }
-        }
-
-        if (credentialEntity == null) {
-            credentialEntity = new CredentialEntity();
-            credentialEntity.setType(cred.getType());
-            credentialEntity.setDevice(cred.getDevice());
-            userEntity.getCredentials().add(credentialEntity);
-        }
-        if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
-            byte[] salt = Pbkdf2PasswordEncoder.getSalt();
-            credentialEntity.setValue(new Pbkdf2PasswordEncoder(salt).encode(cred.getValue()));
-            credentialEntity.setSalt(salt);
-        } else {
-            credentialEntity.setValue(cred.getValue());
-        }
-        credentialEntity.setDevice(cred.getDevice());
-
-        getMongoStore().updateEntity(userEntity, invocationContext);
-    }
-
-    @Override
-    public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
-        DBObject query = new QueryBuilder()
-                .and("socialLinks.socialProvider").is(socialLink.getSocialProvider())
-                .and("socialLinks.socialUsername").is(socialLink.getSocialUsername())
-                .and("realmId").is(getId())
-                .get();
-        UserEntity userEntity = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
-        return userEntity==null ? null : new UserAdapter(userEntity, invocationContext);
-    }
-
-    @Override
-    public Set<SocialLinkModel> getSocialLinks(UserModel user) {
-        UserEntity userEntity = ((UserAdapter)user).getUser();
-        List<SocialLinkEntity> linkEntities = userEntity.getSocialLinks();
-
-        if (linkEntities == null) {
-            return Collections.EMPTY_SET;
-        }
-
-        Set<SocialLinkModel> result = new HashSet<SocialLinkModel>();
-        for (SocialLinkEntity socialLinkEntity : linkEntities) {
-            SocialLinkModel model = new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUsername());
-            result.add(model);
-        }
-        return result;
-    }
-
-    @Override
-    public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
-        UserEntity userEntity = ((UserAdapter)user).getUser();
-        SocialLinkEntity socialLinkEntity = new SocialLinkEntity();
-        socialLinkEntity.setSocialProvider(socialLink.getSocialProvider());
-        socialLinkEntity.setSocialUsername(socialLink.getSocialUsername());
-
-        getMongoStore().pushItemToList(userEntity, "socialLinks", socialLinkEntity, true, invocationContext);
-    }
-
-    @Override
-    public void removeSocialLink(UserModel user, SocialLinkModel socialLink) {
-        SocialLinkEntity socialLinkEntity = new SocialLinkEntity();
-        socialLinkEntity.setSocialProvider(socialLink.getSocialProvider());
-        socialLinkEntity.setSocialUsername(socialLink.getSocialUsername());
-
-        UserEntity userEntity = ((UserAdapter)user).getUser();
-        getMongoStore().pullItemFromList(userEntity, "socialLinks", socialLinkEntity, invocationContext);
-    }
-
-    protected void updateRealm() {
-        getMongoStore().updateEntity(realm, invocationContext);
-    }
-
-    protected RequiredCredentialModel initRequiredCredentialModel(String type) {
-        RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
-        if (model == null) {
-            throw new RuntimeException("Unknown credential type " + type);
-        }
-        return model;
-    }
-
-    @Override
-    public List<UserModel> getUsers() {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-        List<UserEntity> users = getMongoStore().loadEntities(UserEntity.class, query, invocationContext);
-        return convertUserEntities(users);
-    }
-
-    @Override
-    public List<UserModel> searchForUser(String search) {
-        search = search.trim();
-        Pattern caseInsensitivePattern = Pattern.compile("(?i:" + search + ")");
-
-        QueryBuilder nameBuilder;
-        int spaceInd = search.lastIndexOf(" ");
-
-        // Case when we have search string like "ohn Bow". Then firstName must end with "ohn" AND lastName must start with "bow" (everything case-insensitive)
-        if (spaceInd != -1) {
-            String firstName = search.substring(0, spaceInd);
-            String lastName = search.substring(spaceInd + 1);
-            Pattern firstNamePattern =  Pattern.compile("(?i:" + firstName + "$)");
-            Pattern lastNamePattern =  Pattern.compile("(?i:^" + lastName + ")");
-            nameBuilder = new QueryBuilder().and(
-                    new QueryBuilder().put("firstName").regex(firstNamePattern).get(),
-                    new QueryBuilder().put("lastName").regex(lastNamePattern).get()
-            );
-        } else {
-            // Case when we have search without spaces like "foo". The firstName OR lastName could be "foo" (everything case-insensitive)
-            nameBuilder = new QueryBuilder().or(
-                    new QueryBuilder().put("firstName").regex(caseInsensitivePattern).get(),
-                    new QueryBuilder().put("lastName").regex(caseInsensitivePattern).get()
-            );
-        }
-
-        QueryBuilder builder = new QueryBuilder().and(
-                new QueryBuilder().and("realmId").is(getId()).get(),
-                new QueryBuilder().or(
-                        new QueryBuilder().put("loginName").regex(caseInsensitivePattern).get(),
-                        new QueryBuilder().put("email").regex(caseInsensitivePattern).get(),
-                        nameBuilder.get()
-
-                ).get()
-        );
-
-        List<UserEntity> users = getMongoStore().loadEntities(UserEntity.class, builder.get(), invocationContext);
-        return convertUserEntities(users);
-    }
-
-    @Override
-    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
-        QueryBuilder queryBuilder = new QueryBuilder()
-                .and("realmId").is(getId());
-
-        for (Map.Entry<String, String> entry : attributes.entrySet()) {
-            if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
-                queryBuilder.and("loginName").regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
-            } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
-                queryBuilder.and(UserModel.FIRST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
-
-            } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
-                queryBuilder.and(UserModel.LAST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
-
-            } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
-                queryBuilder.and(UserModel.EMAIL).regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
-            }
-        }
-        List<UserEntity> users = getMongoStore().loadEntities(UserEntity.class, queryBuilder.get(), invocationContext);
-        return convertUserEntities(users);
-    }
-
-    protected List<UserModel> convertUserEntities(List<UserEntity> userEntities) {
-        List<UserModel> userModels = new ArrayList<UserModel>();
-        for (UserEntity user : userEntities) {
-            userModels.add(new UserAdapter(user, invocationContext));
-        }
-        return userModels;
-    }
-
-    @Override
-    public Map<String, String> getSmtpConfig() {
-        return realm.getSmtpConfig();
-    }
-
-    @Override
-    public void setSmtpConfig(Map<String, String> smtpConfig) {
-        realm.setSmtpConfig(smtpConfig);
-        updateRealm();
-    }
-
-    @Override
-    public Map<String, String> getSocialConfig() {
-        return realm.getSocialConfig();
-    }
-
-    @Override
-    public void setSocialConfig(Map<String, String> socialConfig) {
-        realm.setSocialConfig(socialConfig);
-        updateRealm();
-    }
-
-    @Override
-    public AbstractMongoIdentifiableEntity getMongoEntity() {
-        return realm;
-    }
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.jboss.logging.Logger;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+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.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
+import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
+import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
+import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
+import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
+import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
+import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
+import org.keycloak.models.mongo.keycloak.entities.UserEntity;
+import org.keycloak.models.mongo.utils.MongoModelUtils;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
+import org.keycloak.models.utils.TimeBasedOTP;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class RealmAdapter extends AbstractAdapter implements RealmModel {
+
+    private static final Logger logger = Logger.getLogger(RealmAdapter.class);
+
+    private final RealmEntity realm;
+
+    protected volatile transient PublicKey publicKey;
+    protected volatile transient PrivateKey privateKey;
+
+    private volatile transient PasswordPolicy passwordPolicy;
+
+    public RealmAdapter(RealmEntity realmEntity, MongoStoreInvocationContext invocationContext) {
+        super(invocationContext);
+        this.realm = realmEntity;
+    }
+
+    @Override
+    public String getId() {
+        return realm.getId();
+    }
+
+    @Override
+    public String getName() {
+        return realm.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        realm.setName(name);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return realm.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        realm.setEnabled(enabled);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isSslNotRequired() {
+        return realm.isSslNotRequired();
+    }
+
+    @Override
+    public void setSslNotRequired(boolean sslNotRequired) {
+        realm.setSslNotRequired(sslNotRequired);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isRegistrationAllowed() {
+        return realm.isRegistrationAllowed();
+    }
+
+    @Override
+    public void setRegistrationAllowed(boolean registrationAllowed) {
+        realm.setRegistrationAllowed(registrationAllowed);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isRememberMe() {
+        return realm.isRememberMe();
+    }
+
+    @Override
+    public void setRememberMe(boolean rememberMe) {
+        realm.setRememberMe(rememberMe);
+        updateRealm();
+    }
+
+
+    @Override
+    public boolean isVerifyEmail() {
+        return realm.isVerifyEmail();
+    }
+
+    @Override
+    public void setVerifyEmail(boolean verifyEmail) {
+        realm.setVerifyEmail(verifyEmail);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isResetPasswordAllowed() {
+        return realm.isResetPasswordAllowed();
+    }
+
+    @Override
+    public void setResetPasswordAllowed(boolean resetPassword) {
+        realm.setResetPasswordAllowed(resetPassword);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isSocial() {
+        return realm.isSocial();
+    }
+
+    @Override
+    public void setSocial(boolean social) {
+        realm.setSocial(social);
+        updateRealm();
+    }
+
+    @Override
+    public boolean isUpdateProfileOnInitialSocialLogin() {
+        return realm.isUpdateProfileOnInitialSocialLogin();
+    }
+
+    @Override
+    public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
+        realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin);
+        updateRealm();
+    }
+
+    @Override
+    public PasswordPolicy getPasswordPolicy() {
+        if (passwordPolicy == null) {
+            passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy());
+        }
+        return passwordPolicy;
+    }
+
+    @Override
+    public void setPasswordPolicy(PasswordPolicy policy) {
+        this.passwordPolicy = policy;
+        realm.setPasswordPolicy(policy.toString());
+        updateRealm();
+    }
+
+    @Override
+    public int getNotBefore() {
+        return realm.getNotBefore();
+    }
+
+    @Override
+    public void setNotBefore(int notBefore) {
+        realm.setNotBefore(notBefore);
+    }
+
+
+    @Override
+    public int getAccessTokenLifespan() {
+        return realm.getAccessTokenLifespan();
+    }
+
+    @Override
+    public void setAccessTokenLifespan(int tokenLifespan) {
+        realm.setAccessTokenLifespan(tokenLifespan);
+        updateRealm();
+    }
+
+    @Override
+    public int getCentralLoginLifespan() {
+        return realm.getCentralLoginLifespan();
+    }
+
+    @Override
+    public void setCentralLoginLifespan(int lifespan) {
+        realm.setCentralLoginLifespan(lifespan);
+        updateRealm();
+    }
+
+
+    @Override
+    public int getRefreshTokenLifespan() {
+        return realm.getRefreshTokenLifespan();
+    }
+
+    @Override
+    public void setRefreshTokenLifespan(int tokenLifespan) {
+        realm.setRefreshTokenLifespan(tokenLifespan);
+        updateRealm();
+    }
+
+    @Override
+    public int getAccessCodeLifespan() {
+        return realm.getAccessCodeLifespan();
+    }
+
+    @Override
+    public void setAccessCodeLifespan(int accessCodeLifespan) {
+        realm.setAccessCodeLifespan(accessCodeLifespan);
+        updateRealm();
+    }
+
+    @Override
+    public int getAccessCodeLifespanUserAction() {
+        return realm.getAccessCodeLifespanUserAction();
+    }
+
+    @Override
+    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+        realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
+        updateRealm();
+    }
+
+    @Override
+    public String getPublicKeyPem() {
+        return realm.getPublicKeyPem();
+    }
+
+    @Override
+    public void setPublicKeyPem(String publicKeyPem) {
+        realm.setPublicKeyPem(publicKeyPem);
+        this.publicKey = null;
+        updateRealm();
+    }
+
+    @Override
+    public String getPrivateKeyPem() {
+        return realm.getPrivateKeyPem();
+    }
+
+    @Override
+    public void setPrivateKeyPem(String privateKeyPem) {
+        realm.setPrivateKeyPem(privateKeyPem);
+        this.privateKey = null;
+        updateRealm();
+    }
+
+    @Override
+    public PublicKey getPublicKey() {
+        if (publicKey != null) return publicKey;
+        publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
+        return publicKey;
+    }
+
+    @Override
+    public void setPublicKey(PublicKey publicKey) {
+        this.publicKey = publicKey;
+        String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey);
+        setPublicKeyPem(publicKeyPem);
+    }
+
+    @Override
+    public PrivateKey getPrivateKey() {
+        if (privateKey != null) return privateKey;
+        privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
+        return privateKey;
+    }
+
+    @Override
+    public void setPrivateKey(PrivateKey privateKey) {
+        this.privateKey = privateKey;
+        String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey);
+        setPrivateKeyPem(privateKeyPem);
+    }
+
+    @Override
+    public String getLoginTheme() {
+        return realm.getLoginTheme();
+    }
+
+    @Override
+    public void setLoginTheme(String name) {
+        realm.setLoginTheme(name);
+        updateRealm();
+    }
+
+    @Override
+    public String getAccountTheme() {
+        return realm.getAccountTheme();
+    }
+
+    @Override
+    public void setAccountTheme(String name) {
+        realm.setAccountTheme(name);
+        updateRealm();
+    }
+
+    @Override
+    public UserAdapter getUser(String name) {
+        DBObject query = new QueryBuilder()
+                .and("loginName").is(name)
+                .and("realmId").is(getId())
+                .get();
+        UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
+
+        if (user == null) {
+            return null;
+        } else {
+            return new UserAdapter(user, invocationContext);
+        }
+    }
+
+    @Override
+    public UserModel getUserByEmail(String email) {
+        DBObject query = new QueryBuilder()
+                .and("email").is(email)
+                .and("realmId").is(getId())
+                .get();
+        UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
+
+        if (user == null) {
+            return null;
+        } else {
+            return new UserAdapter(user, invocationContext);
+        }
+    }
+
+    @Override
+    public UserModel getUserById(String id) {
+        UserEntity user = getMongoStore().loadEntity(UserEntity.class, id, invocationContext);
+
+        // Check that it's user from this realm
+        if (user == null || !getId().equals(user.getRealmId())) {
+            return null;
+        } else {
+            return new UserAdapter(user, invocationContext);
+        }
+    }
+
+    @Override
+    public UserAdapter addUser(String username) {
+        UserAdapter userModel = addUserEntity(username);
+
+        for (String r : getDefaultRoles()) {
+            grantRole(userModel, getRole(r));
+        }
+
+        for (ApplicationModel application : getApplications()) {
+            for (String r : application.getDefaultRoles()) {
+                grantRole(userModel, application.getRole(r));
+            }
+        }
+
+        return userModel;
+    }
+
+    // Add just user entity without defaultRoles
+    protected UserAdapter addUserEntity(String username) {
+        if (getUser(username) != null) {
+            throw new IllegalArgumentException("User " + username + " already exists");
+        }
+
+        UserEntity userEntity = new UserEntity();
+        userEntity.setLoginName(username);
+        userEntity.setEnabled(true);
+        userEntity.setRealmId(getId());
+
+        getMongoStore().insertEntity(userEntity, invocationContext);
+        return new UserAdapter(userEntity, invocationContext);
+    }
+
+    @Override
+    public boolean removeUser(String name) {
+        DBObject query = new QueryBuilder()
+                .and("loginName").is(name)
+                .and("realmId").is(getId())
+                .get();
+        return getMongoStore().removeEntities(UserEntity.class, query, invocationContext);
+    }
+
+    @Override
+    public RoleAdapter getRole(String name) {
+        DBObject query = new QueryBuilder()
+                .and("name").is(name)
+                .and("realmId").is(getId())
+                .get();
+        RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext);
+        if (role == null) {
+            return null;
+        } else {
+            return new RoleAdapter(this, role, this, invocationContext);
+        }
+    }
+
+    @Override
+    public RoleModel addRole(String name) {
+        RoleAdapter role = getRole(name);
+        if (role != null) {
+            // Compatibility with JPA model
+            return role;
+            // throw new IllegalArgumentException("Role " + name + " already exists");
+        }
+
+        RoleEntity roleEntity = new RoleEntity();
+        roleEntity.setName(name);
+        roleEntity.setRealmId(getId());
+
+        getMongoStore().insertEntity(roleEntity, invocationContext);
+        return new RoleAdapter(this, roleEntity, this, invocationContext);
+    }
+
+    @Override
+    public boolean removeRole(RoleModel role) {
+        return removeRoleById(role.getId());
+    }
+
+    @Override
+    public boolean removeRoleById(String id) {
+        return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext);
+    }
+
+    @Override
+    public Set<RoleModel> getRoles() {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .get();
+        List<RoleEntity> roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext);
+
+        Set<RoleModel> result = new HashSet<RoleModel>();
+
+        if (roles == null) return result;
+        for (RoleEntity role : roles) {
+            result.add(new RoleAdapter(this, role, this, invocationContext));
+        }
+
+        return result;
+    }
+
+    @Override
+    public RoleModel getRoleById(String id) {
+        RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext);
+        if (role == null) return null;
+        if (role.getRealmId() != null) {
+            if (!role.getRealmId().equals(this.getId())) return null;
+        } else {
+            ApplicationModel app = getApplicationById(role.getApplicationId());
+            if (app == null) return null;
+        }
+        return new RoleAdapter(this, role, null, invocationContext);
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        return realm.getDefaultRoles();
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        RoleModel role = getRole(name);
+        if (role == null) {
+            addRole(name);
+        }
+
+        getMongoStore().pushItemToList(realm, "defaultRoles", name, true, invocationContext);
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        List<String> roleNames = new ArrayList<String>();
+        for (String roleName : defaultRoles) {
+            RoleModel role = getRole(roleName);
+            if (role == null) {
+                addRole(roleName);
+            }
+
+            roleNames.add(roleName);
+        }
+
+        realm.setDefaultRoles(roleNames);
+        updateRealm();
+    }
+
+    @Override
+    public ClientModel findClient(String clientId) {
+        ClientModel model = getApplicationByName(clientId);
+        if (model != null) return model;
+        return getOAuthClient(clientId);
+    }
+
+
+    @Override
+    public ApplicationModel getApplicationById(String id) {
+        ApplicationEntity appData = getMongoStore().loadEntity(ApplicationEntity.class, id, invocationContext);
+
+        // Check if application belongs to this realm
+        if (appData == null || !getId().equals(appData.getRealmId())) {
+            return null;
+        }
+
+        return new ApplicationAdapter(this, appData, invocationContext);
+    }
+
+    @Override
+    public ApplicationModel getApplicationByName(String name) {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .and("name").is(name)
+                .get();
+        ApplicationEntity appEntity = getMongoStore().loadSingleEntity(ApplicationEntity.class, query, invocationContext);
+        return appEntity==null ? null : new ApplicationAdapter(this, appEntity, invocationContext);
+    }
+
+    @Override
+    public Map<String, ApplicationModel> getApplicationNameMap() {
+        Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
+        for (ApplicationModel resource : getApplications()) {
+            resourceMap.put(resource.getName(), resource);
+        }
+        return resourceMap;
+    }
+
+    @Override
+    public List<ApplicationModel> getApplications() {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .get();
+        List<ApplicationEntity> appDatas = getMongoStore().loadEntities(ApplicationEntity.class, query, invocationContext);
+
+        List<ApplicationModel> result = new ArrayList<ApplicationModel>();
+        for (ApplicationEntity appData : appDatas) {
+            result.add(new ApplicationAdapter(this, appData, invocationContext));
+        }
+        return result;
+    }
+
+    @Override
+    public ApplicationModel addApplication(String name) {
+        ApplicationEntity appData = new ApplicationEntity();
+        appData.setName(name);
+        appData.setRealmId(getId());
+        appData.setEnabled(true);
+        getMongoStore().insertEntity(appData, invocationContext);
+
+        return new ApplicationAdapter(this, appData, invocationContext);
+    }
+
+    @Override
+    public boolean removeApplication(String id) {
+        return getMongoStore().removeEntity(ApplicationEntity.class, id, invocationContext);
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, RoleModel role) {
+        Set<RoleModel> roles = getRoleMappings(user);
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void grantRole(UserModel user, RoleModel role) {
+        UserEntity userEntity = ((UserAdapter)user).getUser();
+        getMongoStore().pushItemToList(userEntity, "roleIds", role.getId(), true, invocationContext);
+    }
+
+    @Override
+    public Set<RoleModel> getRoleMappings(UserModel user) {
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        List<RoleEntity> roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext);
+
+        for (RoleEntity role : roles) {
+            if (getId().equals(role.getRealmId())) {
+                result.add(new RoleAdapter(this, role, this, invocationContext));
+            } else {
+                // Likely applicationRole, but we don't have this application yet
+                result.add(new RoleAdapter(this, role, invocationContext));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Set<RoleModel> getRealmRoleMappings(UserModel user) {
+        Set<RoleModel> allRoles = getRoleMappings(user);
+
+        // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user?
+        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
+        for (RoleModel role : allRoles) {
+            RoleEntity roleEntity = ((RoleAdapter)role).getRole();
+
+            if (getId().equals(roleEntity.getRealmId())) {
+                realmRoles.add(role);
+            }
+        }
+        return realmRoles;
+    }
+
+    @Override
+    public void deleteRoleMapping(UserModel user, RoleModel role) {
+        if (user == null || role == null) return;
+
+        UserEntity userEntity = ((UserAdapter)user).getUser();
+        getMongoStore().pullItemFromList(userEntity, "roleIds", role.getId(), invocationContext);
+    }
+
+    @Override
+    public Set<RoleModel> getScopeMappings(ClientModel client) {
+        Set<RoleModel> result = new HashSet<RoleModel>();
+        List<RoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
+
+        for (RoleEntity role : roles) {
+            if (getId().equals(role.getRealmId())) {
+                result.add(new RoleAdapter(this, role, this, invocationContext));
+            } else {
+                // Likely applicationRole, but we don't have this application yet
+                result.add(new RoleAdapter(this, role, invocationContext));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Set<RoleModel> getRealmScopeMappings(ClientModel client) {
+        Set<RoleModel> allScopes = getScopeMappings(client);
+
+        // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user?
+        Set<RoleModel> realmRoles = new HashSet<RoleModel>();
+        for (RoleModel role : allScopes) {
+            RoleEntity roleEntity = ((RoleAdapter)role).getRole();
+
+            if (getId().equals(roleEntity.getRealmId())) {
+                realmRoles.add(role);
+            }
+        }
+        return realmRoles;
+    }
+
+    @Override
+    public boolean hasScope(ClientModel client, RoleModel role) {
+        Set<RoleModel> roles = getScopeMappings(client);
+        if (roles.contains(role)) return true;
+
+        for (RoleModel mapping : roles) {
+            if (mapping.hasRole(role)) return true;
+        }
+        return false;
+    }
+
+
+    @Override
+    public void addScopeMapping(ClientModel client, RoleModel role) {
+        getMongoStore().pushItemToList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), true, invocationContext);
+    }
+
+    @Override
+    public void deleteScopeMapping(ClientModel client, RoleModel role) {
+        getMongoStore().pullItemFromList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), invocationContext);
+    }
+
+    @Override
+    public OAuthClientModel addOAuthClient(String name) {
+        OAuthClientEntity oauthClient = new OAuthClientEntity();
+        oauthClient.setRealmId(getId());
+        oauthClient.setName(name);
+        getMongoStore().insertEntity(oauthClient, invocationContext);
+
+        return new OAuthClientAdapter(this, oauthClient, invocationContext);
+    }
+
+    @Override
+    public boolean removeOAuthClient(String id) {
+        return getMongoStore().removeEntity(OAuthClientEntity.class, id, invocationContext);
+    }
+
+    @Override
+    public OAuthClientModel getOAuthClient(String name) {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .and("name").is(name)
+                .get();
+        OAuthClientEntity oauthClient = getMongoStore().loadSingleEntity(OAuthClientEntity.class, query, invocationContext);
+        return oauthClient == null ? null : new OAuthClientAdapter(this, oauthClient, invocationContext);
+    }
+
+    @Override
+    public OAuthClientModel getOAuthClientById(String id) {
+        OAuthClientEntity clientEntity = getMongoStore().loadEntity(OAuthClientEntity.class, id, invocationContext);
+
+        // Check if client belongs to this realm
+        if (clientEntity == null || !getId().equals(clientEntity.getRealmId())) return null;
+
+        return new OAuthClientAdapter(this, clientEntity, invocationContext);
+    }
+
+    @Override
+    public List<OAuthClientModel> getOAuthClients() {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .get();
+        List<OAuthClientEntity> results = getMongoStore().loadEntities(OAuthClientEntity.class, query, invocationContext);
+        List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
+        for (OAuthClientEntity data : results) {
+            list.add(new OAuthClientAdapter(this, data, invocationContext));
+        }
+        return list;
+    }
+
+    @Override
+    public void addRequiredCredential(String type) {
+        RequiredCredentialModel credentialModel = initRequiredCredentialModel(type);
+        addRequiredCredential(credentialModel, realm.getRequiredCredentials());
+    }
+
+    protected void addRequiredCredential(RequiredCredentialModel credentialModel, List<RequiredCredentialEntity> persistentCollection) {
+        RequiredCredentialEntity credEntity = new RequiredCredentialEntity();
+        credEntity.setType(credentialModel.getType());
+        credEntity.setFormLabel(credentialModel.getFormLabel());
+        credEntity.setInput(credentialModel.isInput());
+        credEntity.setSecret(credentialModel.isSecret());
+
+        persistentCollection.add(credEntity);
+
+        updateRealm();
+    }
+
+    @Override
+    public void updateRequiredCredentials(Set<String> creds) {
+        updateRequiredCredentials(creds, realm.getRequiredCredentials());
+    }
+
+    protected void updateRequiredCredentials(Set<String> creds, List<RequiredCredentialEntity> credsEntities) {
+        Set<String> already = new HashSet<String>();
+        Set<RequiredCredentialEntity> toRemove = new HashSet<RequiredCredentialEntity>();
+        for (RequiredCredentialEntity entity : credsEntities) {
+            if (!creds.contains(entity.getType())) {
+                toRemove.add(entity);
+            } else {
+                already.add(entity.getType());
+            }
+        }
+        for (RequiredCredentialEntity entity : toRemove) {
+            credsEntities.remove(entity);
+        }
+        for (String cred : creds) {
+            logger.info("updating cred: " + cred);
+            if (!already.contains(cred)) {
+                RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred);
+                addRequiredCredential(credentialModel, credsEntities);
+            }
+        }
+    }
+
+    @Override
+    public List<RequiredCredentialModel> getRequiredCredentials() {
+        return convertRequiredCredentialEntities(realm.getRequiredCredentials());
+    }
+
+    protected List<RequiredCredentialModel> convertRequiredCredentialEntities(Collection<RequiredCredentialEntity> credEntities) {
+
+        List<RequiredCredentialModel> result = new ArrayList<RequiredCredentialModel>();
+        for (RequiredCredentialEntity entity : credEntities) {
+            RequiredCredentialModel model = new RequiredCredentialModel();
+            model.setFormLabel(entity.getFormLabel());
+            model.setInput(entity.isInput());
+            model.setSecret(entity.isSecret());
+            model.setType(entity.getType());
+
+            result.add(model);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean validatePassword(UserModel user, String password) {
+        for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+            if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
+                return new Pbkdf2PasswordEncoder(cred.getSalt()).verify(password, cred.getValue());
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean validateTOTP(UserModel user, String password, String token) {
+        if (!validatePassword(user, password)) return false;
+        for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+            if (cred.getType().equals(UserCredentialModel.TOTP)) {
+                return new TimeBasedOTP().validate(token, cred.getValue().getBytes());
+            }
+        }
+        return false;
+    }
+
+
+    @Override
+    public void updateCredential(UserModel user, UserCredentialModel cred) {
+        CredentialEntity credentialEntity = null;
+        UserEntity userEntity = ((UserAdapter) user).getUser();
+        for (CredentialEntity entity : userEntity.getCredentials()) {
+            if (entity.getType().equals(cred.getType())) {
+                credentialEntity = entity;
+            }
+        }
+
+        if (credentialEntity == null) {
+            credentialEntity = new CredentialEntity();
+            credentialEntity.setType(cred.getType());
+            credentialEntity.setDevice(cred.getDevice());
+            userEntity.getCredentials().add(credentialEntity);
+        }
+        if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
+            byte[] salt = Pbkdf2PasswordEncoder.getSalt();
+            credentialEntity.setValue(new Pbkdf2PasswordEncoder(salt).encode(cred.getValue()));
+            credentialEntity.setSalt(salt);
+        } else {
+            credentialEntity.setValue(cred.getValue());
+        }
+        credentialEntity.setDevice(cred.getDevice());
+
+        getMongoStore().updateEntity(userEntity, invocationContext);
+    }
+
+    @Override
+    public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
+        DBObject query = new QueryBuilder()
+                .and("socialLinks.socialProvider").is(socialLink.getSocialProvider())
+                .and("socialLinks.socialUsername").is(socialLink.getSocialUsername())
+                .and("realmId").is(getId())
+                .get();
+        UserEntity userEntity = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
+        return userEntity==null ? null : new UserAdapter(userEntity, invocationContext);
+    }
+
+    @Override
+    public Set<SocialLinkModel> getSocialLinks(UserModel user) {
+        UserEntity userEntity = ((UserAdapter)user).getUser();
+        List<SocialLinkEntity> linkEntities = userEntity.getSocialLinks();
+
+        if (linkEntities == null) {
+            return Collections.EMPTY_SET;
+        }
+
+        Set<SocialLinkModel> result = new HashSet<SocialLinkModel>();
+        for (SocialLinkEntity socialLinkEntity : linkEntities) {
+            SocialLinkModel model = new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUsername());
+            result.add(model);
+        }
+        return result;
+    }
+
+    @Override
+    public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
+        UserEntity userEntity = ((UserAdapter)user).getUser();
+        SocialLinkEntity socialLinkEntity = new SocialLinkEntity();
+        socialLinkEntity.setSocialProvider(socialLink.getSocialProvider());
+        socialLinkEntity.setSocialUsername(socialLink.getSocialUsername());
+
+        getMongoStore().pushItemToList(userEntity, "socialLinks", socialLinkEntity, true, invocationContext);
+    }
+
+    @Override
+    public void removeSocialLink(UserModel user, SocialLinkModel socialLink) {
+        SocialLinkEntity socialLinkEntity = new SocialLinkEntity();
+        socialLinkEntity.setSocialProvider(socialLink.getSocialProvider());
+        socialLinkEntity.setSocialUsername(socialLink.getSocialUsername());
+
+        UserEntity userEntity = ((UserAdapter)user).getUser();
+        getMongoStore().pullItemFromList(userEntity, "socialLinks", socialLinkEntity, invocationContext);
+    }
+
+    protected void updateRealm() {
+        getMongoStore().updateEntity(realm, invocationContext);
+    }
+
+    protected RequiredCredentialModel initRequiredCredentialModel(String type) {
+        RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
+        if (model == null) {
+            throw new RuntimeException("Unknown credential type " + type);
+        }
+        return model;
+    }
+
+    @Override
+    public List<UserModel> getUsers() {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .get();
+        List<UserEntity> users = getMongoStore().loadEntities(UserEntity.class, query, invocationContext);
+        return convertUserEntities(users);
+    }
+
+    @Override
+    public List<UserModel> searchForUser(String search) {
+        search = search.trim();
+        Pattern caseInsensitivePattern = Pattern.compile("(?i:" + search + ")");
+
+        QueryBuilder nameBuilder;
+        int spaceInd = search.lastIndexOf(" ");
+
+        // Case when we have search string like "ohn Bow". Then firstName must end with "ohn" AND lastName must start with "bow" (everything case-insensitive)
+        if (spaceInd != -1) {
+            String firstName = search.substring(0, spaceInd);
+            String lastName = search.substring(spaceInd + 1);
+            Pattern firstNamePattern =  Pattern.compile("(?i:" + firstName + "$)");
+            Pattern lastNamePattern =  Pattern.compile("(?i:^" + lastName + ")");
+            nameBuilder = new QueryBuilder().and(
+                    new QueryBuilder().put("firstName").regex(firstNamePattern).get(),
+                    new QueryBuilder().put("lastName").regex(lastNamePattern).get()
+            );
+        } else {
+            // Case when we have search without spaces like "foo". The firstName OR lastName could be "foo" (everything case-insensitive)
+            nameBuilder = new QueryBuilder().or(
+                    new QueryBuilder().put("firstName").regex(caseInsensitivePattern).get(),
+                    new QueryBuilder().put("lastName").regex(caseInsensitivePattern).get()
+            );
+        }
+
+        QueryBuilder builder = new QueryBuilder().and(
+                new QueryBuilder().and("realmId").is(getId()).get(),
+                new QueryBuilder().or(
+                        new QueryBuilder().put("loginName").regex(caseInsensitivePattern).get(),
+                        new QueryBuilder().put("email").regex(caseInsensitivePattern).get(),
+                        nameBuilder.get()
+
+                ).get()
+        );
+
+        List<UserEntity> users = getMongoStore().loadEntities(UserEntity.class, builder.get(), invocationContext);
+        return convertUserEntities(users);
+    }
+
+    @Override
+    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
+        QueryBuilder queryBuilder = new QueryBuilder()
+                .and("realmId").is(getId());
+
+        for (Map.Entry<String, String> entry : attributes.entrySet()) {
+            if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
+                queryBuilder.and("loginName").regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
+                queryBuilder.and(UserModel.FIRST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
+
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
+                queryBuilder.and(UserModel.LAST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
+
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
+                queryBuilder.and(UserModel.EMAIL).regex(Pattern.compile("(?i:" + entry.getValue() + "$)"));
+            }
+        }
+        List<UserEntity> users = getMongoStore().loadEntities(UserEntity.class, queryBuilder.get(), invocationContext);
+        return convertUserEntities(users);
+    }
+
+    protected List<UserModel> convertUserEntities(List<UserEntity> userEntities) {
+        List<UserModel> userModels = new ArrayList<UserModel>();
+        for (UserEntity user : userEntities) {
+            userModels.add(new UserAdapter(user, invocationContext));
+        }
+        return userModels;
+    }
+
+    @Override
+    public Map<String, String> getSmtpConfig() {
+        return realm.getSmtpConfig();
+    }
+
+    @Override
+    public void setSmtpConfig(Map<String, String> smtpConfig) {
+        realm.setSmtpConfig(smtpConfig);
+        updateRealm();
+    }
+
+    @Override
+    public Map<String, String> getSocialConfig() {
+        return realm.getSocialConfig();
+    }
+
+    @Override
+    public void setSocialConfig(Map<String, String> socialConfig) {
+        realm.setSocialConfig(socialConfig);
+        updateRealm();
+    }
+
+    @Override
+    public AbstractMongoIdentifiableEntity getMongoEntity() {
+        return realm;
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
old mode 100644
new mode 100755
index 0436569..1165da3
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
@@ -7,6 +7,7 @@ import java.util.Set;
 
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
@@ -26,15 +27,17 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
 
     private final RoleEntity role;
     private RoleContainerModel roleContainer;
+    private RealmModel realm;
 
-    public RoleAdapter(RoleEntity roleEntity, MongoStoreInvocationContext invContext) {
-        this(roleEntity, null, invContext);
+    public RoleAdapter(RealmModel realm, RoleEntity roleEntity, MongoStoreInvocationContext invContext) {
+        this(realm, roleEntity, null, invContext);
     }
 
-    public RoleAdapter(RoleEntity roleEntity, RoleContainerModel roleContainer, MongoStoreInvocationContext invContext) {
+    public RoleAdapter(RealmModel realm, RoleEntity roleEntity, RoleContainerModel roleContainer, MongoStoreInvocationContext invContext) {
         super(invContext);
         this.role = roleEntity;
         this.roleContainer = roleContainer;
+        this.realm = realm;
     }
 
     @Override
@@ -96,7 +99,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
 
         Set<RoleModel> set = new HashSet<RoleModel>();
         for (RoleEntity childRole : childRoles) {
-            set.add(new RoleAdapter(childRole, invocationContext));
+            set.add(new RoleAdapter(realm, childRole, invocationContext));
         }
         return set;
     }
@@ -116,7 +119,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
                 if (appEntity == null) {
                     throw new IllegalStateException("Application with id: " + role.getApplicationId() + " doesn't exists");
                 }
-                roleContainer = new ApplicationAdapter(appEntity, invocationContext);
+                roleContainer = new ApplicationAdapter(realm, appEntity, invocationContext);
             } else {
                 throw new IllegalStateException("Both realmId and applicationId are null for role: " + this);
             }
@@ -141,4 +144,22 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
     public AbstractMongoIdentifiableEntity getMongoEntity() {
         return role;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        RoleAdapter that = (RoleAdapter) o;
+
+        if (!role.getId().equals(that.role.getId())) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return role.getId().hashCode();
+    }
+
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
index 8f22a7b..d3d4d6a 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
@@ -1,166 +1,166 @@
-package org.keycloak.models.mongo.keycloak.adapters;
-
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.keycloak.entities.UserEntity;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl)
- *
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class UserAdapter extends AbstractAdapter implements UserModel {
-
-    private final UserEntity user;
-
-    public UserAdapter(UserEntity userEntity, MongoStoreInvocationContext invContext) {
-        super(invContext);
-        this.user = userEntity;
-    }
-
-    @Override
-    public String getId() {
-        return user.getId();
-    }
-
-    @Override
-    public String getLoginName() {
-        return user.getLoginName();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return user.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        user.setEnabled(enabled);
-        updateUser();
-    }
-
-    @Override
-    public String getFirstName() {
-        return user.getFirstName();
-    }
-
-    @Override
-    public void setFirstName(String firstName) {
-        user.setFirstName(firstName);
-        updateUser();
-    }
-
-    @Override
-    public String getLastName() {
-        return user.getLastName();
-    }
-
-    @Override
-    public void setLastName(String lastName) {
-        user.setLastName(lastName);
-        updateUser();
-    }
-
-    @Override
-    public String getEmail() {
-        return user.getEmail();
-    }
-
-    @Override
-    public void setEmail(String email) {
-        user.setEmail(email);
-        updateUser();
-    }
-
-    @Override
-    public boolean isEmailVerified() {
-        return user.isEmailVerified();
-    }
-
-    @Override
-    public void setEmailVerified(boolean verified) {
-        user.setEmailVerified(verified);
-        updateUser();
-    }
-
-    @Override
-    public void setAttribute(String name, String value) {
-        if (user.getAttributes() == null) {
-            user.setAttributes(new HashMap<String, String>());
-        }
-
-        user.getAttributes().put(name, value);
-        updateUser();
-    }
-
-    @Override
-    public void removeAttribute(String name) {
-        if (user.getAttributes() == null) return;
-
-        user.getAttributes().remove(name);
-        updateUser();
-    }
-
-    @Override
-    public String getAttribute(String name) {
-        return user.getAttributes()==null ? null : user.getAttributes().get(name);
-    }
-
-    @Override
-    public Map<String, String> getAttributes() {
-        return user.getAttributes()==null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(user.getAttributes());
-    }
-
-    public UserEntity getUser() {
-        return user;
-    }
-
-
-    @Override
-    public Set<RequiredAction> getRequiredActions() {
-        Set<RequiredAction> result = new HashSet<RequiredAction>();
-        if (user.getRequiredActions() != null) {
-            result.addAll(user.getRequiredActions());
-        }
-        return result;
-    }
-
-    @Override
-    public void addRequiredAction(RequiredAction action) {
-        getMongoStore().pushItemToList(user, "requiredActions", action, true, invocationContext);
-    }
-
-    @Override
-    public void removeRequiredAction(RequiredAction action) {
-        getMongoStore().pullItemFromList(user, "requiredActions", action, invocationContext);
-    }
-
-    @Override
-    public boolean isTotp() {
-        return user.isTotp();
-    }
-
-    @Override
-    public void setTotp(boolean totp) {
-        user.setTotp(totp);
-        updateUser();
-    }
-
-    protected void updateUser() {
-        getMongoStore().updateEntity(user, invocationContext);
-    }
-
-    @Override
-    public AbstractMongoIdentifiableEntity getMongoEntity() {
-        return user;
-    }
-}
+package org.keycloak.models.mongo.keycloak.adapters;
+
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.keycloak.entities.UserEntity;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl)
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class UserAdapter extends AbstractAdapter implements UserModel {
+
+    private final UserEntity user;
+
+    public UserAdapter(UserEntity userEntity, MongoStoreInvocationContext invContext) {
+        super(invContext);
+        this.user = userEntity;
+    }
+
+    @Override
+    public String getId() {
+        return user.getId();
+    }
+
+    @Override
+    public String getLoginName() {
+        return user.getLoginName();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return user.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        user.setEnabled(enabled);
+        updateUser();
+    }
+
+    @Override
+    public String getFirstName() {
+        return user.getFirstName();
+    }
+
+    @Override
+    public void setFirstName(String firstName) {
+        user.setFirstName(firstName);
+        updateUser();
+    }
+
+    @Override
+    public String getLastName() {
+        return user.getLastName();
+    }
+
+    @Override
+    public void setLastName(String lastName) {
+        user.setLastName(lastName);
+        updateUser();
+    }
+
+    @Override
+    public String getEmail() {
+        return user.getEmail();
+    }
+
+    @Override
+    public void setEmail(String email) {
+        user.setEmail(email);
+        updateUser();
+    }
+
+    @Override
+    public boolean isEmailVerified() {
+        return user.isEmailVerified();
+    }
+
+    @Override
+    public void setEmailVerified(boolean verified) {
+        user.setEmailVerified(verified);
+        updateUser();
+    }
+
+    @Override
+    public void setAttribute(String name, String value) {
+        if (user.getAttributes() == null) {
+            user.setAttributes(new HashMap<String, String>());
+        }
+
+        user.getAttributes().put(name, value);
+        updateUser();
+    }
+
+    @Override
+    public void removeAttribute(String name) {
+        if (user.getAttributes() == null) return;
+
+        user.getAttributes().remove(name);
+        updateUser();
+    }
+
+    @Override
+    public String getAttribute(String name) {
+        return user.getAttributes()==null ? null : user.getAttributes().get(name);
+    }
+
+    @Override
+    public Map<String, String> getAttributes() {
+        return user.getAttributes()==null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(user.getAttributes());
+    }
+
+    public UserEntity getUser() {
+        return user;
+    }
+
+
+    @Override
+    public Set<RequiredAction> getRequiredActions() {
+        Set<RequiredAction> result = new HashSet<RequiredAction>();
+        if (user.getRequiredActions() != null) {
+            result.addAll(user.getRequiredActions());
+        }
+        return result;
+    }
+
+    @Override
+    public void addRequiredAction(RequiredAction action) {
+        getMongoStore().pushItemToList(user, "requiredActions", action, true, invocationContext);
+    }
+
+    @Override
+    public void removeRequiredAction(RequiredAction action) {
+        getMongoStore().pullItemFromList(user, "requiredActions", action, invocationContext);
+    }
+
+    @Override
+    public boolean isTotp() {
+        return user.isTotp();
+    }
+
+    @Override
+    public void setTotp(boolean totp) {
+        user.setTotp(totp);
+        updateUser();
+    }
+
+    protected void updateUser() {
+        getMongoStore().updateEntity(user, invocationContext);
+    }
+
+    @Override
+    public AbstractMongoIdentifiableEntity getMongoEntity() {
+        return user;
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
index f77b6a8..60f1667 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
@@ -1,157 +1,157 @@
-package org.keycloak.models.mongo.keycloak.entities;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-@MongoCollection(collectionName = "applications")
-public class ApplicationEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
-
-    private String name;
-    private boolean enabled;
-    private boolean surrogateAuthRequired;
-    private String managementUrl;
-    private String baseUrl;
-    private String secret;
-
-    private String realmId;
-    private long allowedClaimsMask;
-    private List<String> scopeIds;
-    private List<String> webOrigins;
-    private List<String> redirectUris;
-
-
-    // We are using names of defaultRoles (not ids)
-    private List<String> defaultRoles = new ArrayList<String>();
-
-    @MongoField
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @MongoField
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    @MongoField
-    public boolean isSurrogateAuthRequired() {
-        return surrogateAuthRequired;
-    }
-
-    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
-        this.surrogateAuthRequired = surrogateAuthRequired;
-    }
-
-    @MongoField
-    public String getManagementUrl() {
-        return managementUrl;
-    }
-
-    public void setManagementUrl(String managementUrl) {
-        this.managementUrl = managementUrl;
-    }
-
-    @MongoField
-    public String getBaseUrl() {
-        return baseUrl;
-    }
-
-    public void setBaseUrl(String baseUrl) {
-        this.baseUrl = baseUrl;
-    }
-
-    @Override
-    @MongoField
-    public List<String> getScopeIds() {
-        return scopeIds;
-    }
-
-    @Override
-    public void setScopeIds(List<String> scopeIds) {
-        this.scopeIds = scopeIds;
-    }
-
-    @MongoField
-    public List<String> getWebOrigins() {
-        return webOrigins;
-    }
-
-    public void setWebOrigins(List<String> webOrigins) {
-        this.webOrigins = webOrigins;
-    }
-
-    @MongoField
-    public List<String> getRedirectUris() {
-        return redirectUris;
-    }
-
-    public void setRedirectUris(List<String> redirectUris) {
-        this.redirectUris = redirectUris;
-    }
-
-
-
-    @MongoField
-    public long getAllowedClaimsMask() {
-        return allowedClaimsMask;
-    }
-
-    public void setAllowedClaimsMask(long allowedClaimsMask) {
-        this.allowedClaimsMask = allowedClaimsMask;
-    }
-
-    @MongoField
-    public String getRealmId() {
-        return realmId;
-    }
-
-    public void setRealmId(String realmId) {
-        this.realmId = realmId;
-    }
-
-    @MongoField
-    public String getSecret() {
-        return secret;
-    }
-
-    public void setSecret(String secret) {
-        this.secret = secret;
-    }
-
-    @MongoField
-    public List<String> getDefaultRoles() {
-        return defaultRoles;
-    }
-
-    public void setDefaultRoles(List<String> defaultRoles) {
-        this.defaultRoles = defaultRoles;
-    }
-
-    @Override
-    public void afterRemove(MongoStoreInvocationContext context) {
-        // Remove all roles, which belongs to this application
-        DBObject query = new QueryBuilder()
-                .and("applicationId").is(getId())
-                .get();
-        context.getMongoStore().removeEntities(RoleEntity.class, query, context);
-    }
-}
+package org.keycloak.models.mongo.keycloak.entities;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@MongoCollection(collectionName = "applications")
+public class ApplicationEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
+
+    private String name;
+    private boolean enabled;
+    private boolean surrogateAuthRequired;
+    private String managementUrl;
+    private String baseUrl;
+    private String secret;
+
+    private String realmId;
+    private long allowedClaimsMask;
+    private List<String> scopeIds;
+    private List<String> webOrigins;
+    private List<String> redirectUris;
+
+
+    // We are using names of defaultRoles (not ids)
+    private List<String> defaultRoles = new ArrayList<String>();
+
+    @MongoField
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @MongoField
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    @MongoField
+    public boolean isSurrogateAuthRequired() {
+        return surrogateAuthRequired;
+    }
+
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        this.surrogateAuthRequired = surrogateAuthRequired;
+    }
+
+    @MongoField
+    public String getManagementUrl() {
+        return managementUrl;
+    }
+
+    public void setManagementUrl(String managementUrl) {
+        this.managementUrl = managementUrl;
+    }
+
+    @MongoField
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public void setBaseUrl(String baseUrl) {
+        this.baseUrl = baseUrl;
+    }
+
+    @Override
+    @MongoField
+    public List<String> getScopeIds() {
+        return scopeIds;
+    }
+
+    @Override
+    public void setScopeIds(List<String> scopeIds) {
+        this.scopeIds = scopeIds;
+    }
+
+    @MongoField
+    public List<String> getWebOrigins() {
+        return webOrigins;
+    }
+
+    public void setWebOrigins(List<String> webOrigins) {
+        this.webOrigins = webOrigins;
+    }
+
+    @MongoField
+    public List<String> getRedirectUris() {
+        return redirectUris;
+    }
+
+    public void setRedirectUris(List<String> redirectUris) {
+        this.redirectUris = redirectUris;
+    }
+
+
+
+    @MongoField
+    public long getAllowedClaimsMask() {
+        return allowedClaimsMask;
+    }
+
+    public void setAllowedClaimsMask(long allowedClaimsMask) {
+        this.allowedClaimsMask = allowedClaimsMask;
+    }
+
+    @MongoField
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    @MongoField
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    @MongoField
+    public List<String> getDefaultRoles() {
+        return defaultRoles;
+    }
+
+    public void setDefaultRoles(List<String> defaultRoles) {
+        this.defaultRoles = defaultRoles;
+    }
+
+    @Override
+    public void afterRemove(MongoStoreInvocationContext context) {
+        // Remove all roles, which belongs to this application
+        DBObject query = new QueryBuilder()
+                .and("applicationId").is(getId())
+                .get();
+        context.getMongoStore().removeEntities(RoleEntity.class, query, context);
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
index c59443f..9ef85a3 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
@@ -1,105 +1,105 @@
-package org.keycloak.models.mongo.keycloak.entities;
-
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-@MongoCollection(collectionName = "oauthClients")
-public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
-
-    private String name;
-    private boolean enabled;
-    private String realmId;
-    private String secret;
-    private long allowedClaimsMask;
-    private List<String> scopeIds;
-    private List<String> webOrigins;
-    private List<String> redirectUris;
-
-    @MongoField
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @MongoField
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    @MongoField
-    public String getRealmId() {
-        return realmId;
-    }
-
-    public void setRealmId(String realmId) {
-        this.realmId = realmId;
-    }
-
-    @MongoField
-    public String getSecret() {
-        return secret;
-    }
-
-    public void setSecret(String secret) {
-        this.secret = secret;
-    }
-
-
-    @MongoField
-    public long getAllowedClaimsMask() {
-        return allowedClaimsMask;
-    }
-
-    public void setAllowedClaimsMask(long allowedClaimsMask) {
-        this.allowedClaimsMask = allowedClaimsMask;
-    }
-
-    @MongoField
-    public List<String> getWebOrigins() {
-        return webOrigins;
-    }
-
-    public void setWebOrigins(List<String> webOrigins) {
-        this.webOrigins = webOrigins;
-    }
-
-    @MongoField
-    public List<String> getRedirectUris() {
-        return redirectUris;
-    }
-
-    public void setRedirectUris(List<String> redirectUris) {
-        this.redirectUris = redirectUris;
-    }
-
-    @MongoField
-    public List<String> getScopeIds() {
-        return scopeIds;
-    }
-
-    public void setScopeIds(List<String> scopeIds) {
-        this.scopeIds = scopeIds;
-    }
-
-
-
-
-    @Override
-    public void afterRemove(MongoStoreInvocationContext context) {
-    }
-}
+package org.keycloak.models.mongo.keycloak.entities;
+
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@MongoCollection(collectionName = "oauthClients")
+public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
+
+    private String name;
+    private boolean enabled;
+    private String realmId;
+    private String secret;
+    private long allowedClaimsMask;
+    private List<String> scopeIds;
+    private List<String> webOrigins;
+    private List<String> redirectUris;
+
+    @MongoField
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @MongoField
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    @MongoField
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    @MongoField
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+
+    @MongoField
+    public long getAllowedClaimsMask() {
+        return allowedClaimsMask;
+    }
+
+    public void setAllowedClaimsMask(long allowedClaimsMask) {
+        this.allowedClaimsMask = allowedClaimsMask;
+    }
+
+    @MongoField
+    public List<String> getWebOrigins() {
+        return webOrigins;
+    }
+
+    public void setWebOrigins(List<String> webOrigins) {
+        this.webOrigins = webOrigins;
+    }
+
+    @MongoField
+    public List<String> getRedirectUris() {
+        return redirectUris;
+    }
+
+    public void setRedirectUris(List<String> redirectUris) {
+        this.redirectUris = redirectUris;
+    }
+
+    @MongoField
+    public List<String> getScopeIds() {
+        return scopeIds;
+    }
+
+    public void setScopeIds(List<String> scopeIds) {
+        this.scopeIds = scopeIds;
+    }
+
+
+
+
+    @Override
+    public void afterRemove(MongoStoreInvocationContext context) {
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java
index b8b2ef2..90f39a8 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java
@@ -1,285 +1,285 @@
-package org.keycloak.models.mongo.keycloak.entities;
-
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-@MongoCollection(collectionName = "realms")
-public class RealmEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
-
-    private String name;
-    private boolean enabled;
-    private boolean sslNotRequired;
-    private boolean registrationAllowed;
-    private boolean rememberMe;
-    private boolean verifyEmail;
-    private boolean resetPasswordAllowed;
-    private boolean social;
-    private boolean updateProfileOnInitialSocialLogin;
-    private String passwordPolicy;
-
-    private int centralLoginLifespan;
-    private int accessTokenLifespan;
-    private int accessCodeLifespan;
-    private int accessCodeLifespanUserAction;
-    private int refreshTokenLifespan;
-    private int notBefore;
-
-    private String publicKeyPem;
-    private String privateKeyPem;
-
-    private String loginTheme;
-    private String accountTheme;
-
-    // We are using names of defaultRoles (not ids)
-    private List<String> defaultRoles = new ArrayList<String>();
-
-    private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
-
-    private Map<String, String> smtpConfig = new HashMap<String, String>();
-    private Map<String, String> socialConfig = new HashMap<String, String>();
-
-    @MongoField
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String realmName) {
-        this.name = realmName;
-    }
-
-    @MongoField
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    @MongoField
-    public boolean isSslNotRequired() {
-        return sslNotRequired;
-    }
-
-    public void setSslNotRequired(boolean sslNotRequired) {
-        this.sslNotRequired = sslNotRequired;
-    }
-
-    @MongoField
-    public boolean isRegistrationAllowed() {
-        return registrationAllowed;
-    }
-
-    public void setRegistrationAllowed(boolean registrationAllowed) {
-        this.registrationAllowed = registrationAllowed;
-    }
-
-    @MongoField
-    public boolean isRememberMe() {
-        return rememberMe;
-    }
-
-    public void setRememberMe(boolean rememberMe) {
-        this.rememberMe = rememberMe;
-    }
-
-    @MongoField
-    public boolean isVerifyEmail() {
-        return verifyEmail;
-    }
-
-    public void setVerifyEmail(boolean verifyEmail) {
-        this.verifyEmail = verifyEmail;
-    }
-
-    @MongoField
-    public boolean isResetPasswordAllowed() {
-        return resetPasswordAllowed;
-    }
-
-    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
-        this.resetPasswordAllowed = resetPasswordAllowed;
-    }
-
-    @MongoField
-    public boolean isSocial() {
-        return social;
-    }
-
-    public void setSocial(boolean social) {
-        this.social = social;
-    }
-
-    @MongoField
-    public boolean isUpdateProfileOnInitialSocialLogin() {
-        return updateProfileOnInitialSocialLogin;
-    }
-
-    public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
-        this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
-    }
-
-    @MongoField
-    public String getPasswordPolicy() {
-        return passwordPolicy;
-    }
-
-    public void setPasswordPolicy(String passwordPolicy) {
-        this.passwordPolicy = passwordPolicy;
-    }
-
-    @MongoField
-    public int getNotBefore() {
-        return notBefore;
-    }
-
-    public void setNotBefore(int notBefore) {
-        this.notBefore = notBefore;
-    }
-
-    @MongoField
-    public int getCentralLoginLifespan() {
-        return centralLoginLifespan;
-    }
-
-    public void setCentralLoginLifespan(int centralLoginLifespan) {
-        this.centralLoginLifespan = centralLoginLifespan;
-    }
-
-    @MongoField
-    public int getAccessTokenLifespan() {
-        return accessTokenLifespan;
-    }
-
-    public void setAccessTokenLifespan(int accessTokenLifespan) {
-        this.accessTokenLifespan = accessTokenLifespan;
-    }
-
-    @MongoField
-    public int getRefreshTokenLifespan() {
-        return refreshTokenLifespan;
-    }
-
-    public void setRefreshTokenLifespan(int refreshTokenLifespan) {
-        this.refreshTokenLifespan = refreshTokenLifespan;
-    }
-
-    @MongoField
-    public int getAccessCodeLifespan() {
-        return accessCodeLifespan;
-    }
-
-    public void setAccessCodeLifespan(int accessCodeLifespan) {
-        this.accessCodeLifespan = accessCodeLifespan;
-    }
-
-    @MongoField
-    public int getAccessCodeLifespanUserAction() {
-        return accessCodeLifespanUserAction;
-    }
-
-    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
-        this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
-    }
-
-    @MongoField
-    public String getPublicKeyPem() {
-        return publicKeyPem;
-    }
-
-    public void setPublicKeyPem(String publicKeyPem) {
-        this.publicKeyPem = publicKeyPem;
-    }
-
-    @MongoField
-    public String getPrivateKeyPem() {
-        return privateKeyPem;
-    }
-
-    public void setPrivateKeyPem(String privateKeyPem) {
-        this.privateKeyPem = privateKeyPem;
-    }
-
-    @MongoField
-    public String getLoginTheme() {
-        return loginTheme;
-    }
-
-    public void setLoginTheme(String loginTheme) {
-        this.loginTheme = loginTheme;
-    }
-
-    @MongoField
-    public String getAccountTheme() {
-        return accountTheme;
-    }
-
-    public void setAccountTheme(String accountTheme) {
-        this.accountTheme = accountTheme;
-    }
-
-    @MongoField
-    public List<String> getDefaultRoles() {
-        return defaultRoles;
-    }
-
-    public void setDefaultRoles(List<String> defaultRoles) {
-        this.defaultRoles = defaultRoles;
-    }
-
-    @MongoField
-    public List<RequiredCredentialEntity> getRequiredCredentials() {
-        return requiredCredentials;
-    }
-
-    public void setRequiredCredentials(List<RequiredCredentialEntity> requiredCredentials) {
-        this.requiredCredentials = requiredCredentials;
-    }
-
-    @MongoField
-    public Map<String, String> getSmtpConfig() {
-        return smtpConfig;
-    }
-
-    public void setSmtpConfig(Map<String, String> smptConfig) {
-        this.smtpConfig = smptConfig;
-    }
-
-    @MongoField
-    public Map<String, String> getSocialConfig() {
-        return socialConfig;
-    }
-
-    public void setSocialConfig(Map<String, String> socialConfig) {
-        this.socialConfig = socialConfig;
-    }
-
-    @Override
-    public void afterRemove(MongoStoreInvocationContext context) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .get();
-
-        // Remove all users of this realm
-        context.getMongoStore().removeEntities(UserEntity.class, query, context);
-
-        // Remove all roles of this realm
-        context.getMongoStore().removeEntities(RoleEntity.class, query, context);
-
-        // Remove all applications of this realm
-        context.getMongoStore().removeEntities(ApplicationEntity.class, query, context);
-    }
-}
+package org.keycloak.models.mongo.keycloak.entities;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@MongoCollection(collectionName = "realms")
+public class RealmEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
+
+    private String name;
+    private boolean enabled;
+    private boolean sslNotRequired;
+    private boolean registrationAllowed;
+    private boolean rememberMe;
+    private boolean verifyEmail;
+    private boolean resetPasswordAllowed;
+    private boolean social;
+    private boolean updateProfileOnInitialSocialLogin;
+    private String passwordPolicy;
+
+    private int centralLoginLifespan;
+    private int accessTokenLifespan;
+    private int accessCodeLifespan;
+    private int accessCodeLifespanUserAction;
+    private int refreshTokenLifespan;
+    private int notBefore;
+
+    private String publicKeyPem;
+    private String privateKeyPem;
+
+    private String loginTheme;
+    private String accountTheme;
+
+    // We are using names of defaultRoles (not ids)
+    private List<String> defaultRoles = new ArrayList<String>();
+
+    private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
+
+    private Map<String, String> smtpConfig = new HashMap<String, String>();
+    private Map<String, String> socialConfig = new HashMap<String, String>();
+
+    @MongoField
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String realmName) {
+        this.name = realmName;
+    }
+
+    @MongoField
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    @MongoField
+    public boolean isSslNotRequired() {
+        return sslNotRequired;
+    }
+
+    public void setSslNotRequired(boolean sslNotRequired) {
+        this.sslNotRequired = sslNotRequired;
+    }
+
+    @MongoField
+    public boolean isRegistrationAllowed() {
+        return registrationAllowed;
+    }
+
+    public void setRegistrationAllowed(boolean registrationAllowed) {
+        this.registrationAllowed = registrationAllowed;
+    }
+
+    @MongoField
+    public boolean isRememberMe() {
+        return rememberMe;
+    }
+
+    public void setRememberMe(boolean rememberMe) {
+        this.rememberMe = rememberMe;
+    }
+
+    @MongoField
+    public boolean isVerifyEmail() {
+        return verifyEmail;
+    }
+
+    public void setVerifyEmail(boolean verifyEmail) {
+        this.verifyEmail = verifyEmail;
+    }
+
+    @MongoField
+    public boolean isResetPasswordAllowed() {
+        return resetPasswordAllowed;
+    }
+
+    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+        this.resetPasswordAllowed = resetPasswordAllowed;
+    }
+
+    @MongoField
+    public boolean isSocial() {
+        return social;
+    }
+
+    public void setSocial(boolean social) {
+        this.social = social;
+    }
+
+    @MongoField
+    public boolean isUpdateProfileOnInitialSocialLogin() {
+        return updateProfileOnInitialSocialLogin;
+    }
+
+    public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
+        this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
+    }
+
+    @MongoField
+    public String getPasswordPolicy() {
+        return passwordPolicy;
+    }
+
+    public void setPasswordPolicy(String passwordPolicy) {
+        this.passwordPolicy = passwordPolicy;
+    }
+
+    @MongoField
+    public int getNotBefore() {
+        return notBefore;
+    }
+
+    public void setNotBefore(int notBefore) {
+        this.notBefore = notBefore;
+    }
+
+    @MongoField
+    public int getCentralLoginLifespan() {
+        return centralLoginLifespan;
+    }
+
+    public void setCentralLoginLifespan(int centralLoginLifespan) {
+        this.centralLoginLifespan = centralLoginLifespan;
+    }
+
+    @MongoField
+    public int getAccessTokenLifespan() {
+        return accessTokenLifespan;
+    }
+
+    public void setAccessTokenLifespan(int accessTokenLifespan) {
+        this.accessTokenLifespan = accessTokenLifespan;
+    }
+
+    @MongoField
+    public int getRefreshTokenLifespan() {
+        return refreshTokenLifespan;
+    }
+
+    public void setRefreshTokenLifespan(int refreshTokenLifespan) {
+        this.refreshTokenLifespan = refreshTokenLifespan;
+    }
+
+    @MongoField
+    public int getAccessCodeLifespan() {
+        return accessCodeLifespan;
+    }
+
+    public void setAccessCodeLifespan(int accessCodeLifespan) {
+        this.accessCodeLifespan = accessCodeLifespan;
+    }
+
+    @MongoField
+    public int getAccessCodeLifespanUserAction() {
+        return accessCodeLifespanUserAction;
+    }
+
+    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+        this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
+    }
+
+    @MongoField
+    public String getPublicKeyPem() {
+        return publicKeyPem;
+    }
+
+    public void setPublicKeyPem(String publicKeyPem) {
+        this.publicKeyPem = publicKeyPem;
+    }
+
+    @MongoField
+    public String getPrivateKeyPem() {
+        return privateKeyPem;
+    }
+
+    public void setPrivateKeyPem(String privateKeyPem) {
+        this.privateKeyPem = privateKeyPem;
+    }
+
+    @MongoField
+    public String getLoginTheme() {
+        return loginTheme;
+    }
+
+    public void setLoginTheme(String loginTheme) {
+        this.loginTheme = loginTheme;
+    }
+
+    @MongoField
+    public String getAccountTheme() {
+        return accountTheme;
+    }
+
+    public void setAccountTheme(String accountTheme) {
+        this.accountTheme = accountTheme;
+    }
+
+    @MongoField
+    public List<String> getDefaultRoles() {
+        return defaultRoles;
+    }
+
+    public void setDefaultRoles(List<String> defaultRoles) {
+        this.defaultRoles = defaultRoles;
+    }
+
+    @MongoField
+    public List<RequiredCredentialEntity> getRequiredCredentials() {
+        return requiredCredentials;
+    }
+
+    public void setRequiredCredentials(List<RequiredCredentialEntity> requiredCredentials) {
+        this.requiredCredentials = requiredCredentials;
+    }
+
+    @MongoField
+    public Map<String, String> getSmtpConfig() {
+        return smtpConfig;
+    }
+
+    public void setSmtpConfig(Map<String, String> smptConfig) {
+        this.smtpConfig = smptConfig;
+    }
+
+    @MongoField
+    public Map<String, String> getSocialConfig() {
+        return socialConfig;
+    }
+
+    public void setSocialConfig(Map<String, String> socialConfig) {
+        this.socialConfig = socialConfig;
+    }
+
+    @Override
+    public void afterRemove(MongoStoreInvocationContext context) {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(getId())
+                .get();
+
+        // Remove all users of this realm
+        context.getMongoStore().removeEntities(UserEntity.class, query, context);
+
+        // Remove all roles of this realm
+        context.getMongoStore().removeEntities(RoleEntity.class, query, context);
+
+        // Remove all applications of this realm
+        context.getMongoStore().removeEntities(ApplicationEntity.class, query, context);
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java
index e2e9727..ee8b72f 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java
@@ -1,131 +1,131 @@
-package org.keycloak.models.mongo.keycloak.entities;
-
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.jboss.logging.Logger;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-import org.keycloak.models.mongo.api.MongoStore;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-@MongoCollection(collectionName = "roles")
-public class RoleEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
-
-    private static final Logger logger = Logger.getLogger(RoleEntity.class);
-
-    private String name;
-    private String description;
-
-    private List<String> compositeRoleIds;
-
-    private String realmId;
-    private String applicationId;
-
-    @MongoField
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @MongoField
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    @MongoField
-    public List<String> getCompositeRoleIds() {
-        return compositeRoleIds;
-    }
-
-    public void setCompositeRoleIds(List<String> compositeRoleIds) {
-        this.compositeRoleIds = compositeRoleIds;
-    }
-
-    @MongoField
-    public String getRealmId() {
-        return realmId;
-    }
-
-    public void setRealmId(String realmId) {
-        this.realmId = realmId;
-    }
-
-    @MongoField
-    public String getApplicationId() {
-        return applicationId;
-    }
-
-    public void setApplicationId(String applicationId) {
-        this.applicationId = applicationId;
-    }
-
-    @Override
-    public void afterRemove(MongoStoreInvocationContext invContext) {
-        MongoStore mongoStore = invContext.getMongoStore();
-
-        // Remove this role from all users, which has it
-        DBObject query = new QueryBuilder()
-                .and("roleIds").is(getId())
-                .get();
-
-        List<UserEntity> users = mongoStore.loadEntities(UserEntity.class, query, invContext);
-        for (UserEntity user : users) {
-            logger.info("Removing role " + getName() + " from user " + user.getLoginName());
-            mongoStore.pullItemFromList(user, "roleIds", getId(), invContext);
-        }
-
-        // Remove this scope from all users, which has it
-        query = new QueryBuilder()
-                .and("scopeIds").is(getId())
-                .get();
-
-        users = mongoStore.loadEntities(UserEntity.class, query, invContext);
-        for (UserEntity user : users) {
-            logger.info("Removing scope " + getName() + " from user " + user.getLoginName());
-            mongoStore.pullItemFromList(user, "scopeIds", getId(), invContext);
-        }
-
-        // Remove defaultRoles from realm
-        if (realmId != null) {
-            RealmEntity realmEntity = mongoStore.loadEntity(RealmEntity.class, realmId, invContext);
-
-            // Realm might be already removed at this point
-            if (realmEntity != null) {
-                mongoStore.pullItemFromList(realmEntity, "defaultRoles", getId(), invContext);
-            }
-        }
-
-        // Remove defaultRoles from application
-        if (applicationId != null) {
-            ApplicationEntity appEntity = mongoStore.loadEntity(ApplicationEntity.class, applicationId, invContext);
-
-            // Application might be already removed at this point
-            if (appEntity != null) {
-                mongoStore.pullItemFromList(appEntity, "defaultRoles", getId(), invContext);
-            }
-        }
-
-        // Remove this role from others who has it as composite
-        query = new QueryBuilder()
-                .and("compositeRoleIds").is(getId())
-                .get();
-        List<RoleEntity> parentRoles = mongoStore.loadEntities(RoleEntity.class, query, invContext);
-        for (RoleEntity role : parentRoles) {
-            mongoStore.pullItemFromList(role, "compositeRoleIds", getId(), invContext);
-        }
-    }
-}
+package org.keycloak.models.mongo.keycloak.entities;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.jboss.logging.Logger;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+import org.keycloak.models.mongo.api.MongoStore;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@MongoCollection(collectionName = "roles")
+public class RoleEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
+
+    private static final Logger logger = Logger.getLogger(RoleEntity.class);
+
+    private String name;
+    private String description;
+
+    private List<String> compositeRoleIds;
+
+    private String realmId;
+    private String applicationId;
+
+    @MongoField
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @MongoField
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @MongoField
+    public List<String> getCompositeRoleIds() {
+        return compositeRoleIds;
+    }
+
+    public void setCompositeRoleIds(List<String> compositeRoleIds) {
+        this.compositeRoleIds = compositeRoleIds;
+    }
+
+    @MongoField
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    @MongoField
+    public String getApplicationId() {
+        return applicationId;
+    }
+
+    public void setApplicationId(String applicationId) {
+        this.applicationId = applicationId;
+    }
+
+    @Override
+    public void afterRemove(MongoStoreInvocationContext invContext) {
+        MongoStore mongoStore = invContext.getMongoStore();
+
+        // Remove this role from all users, which has it
+        DBObject query = new QueryBuilder()
+                .and("roleIds").is(getId())
+                .get();
+
+        List<UserEntity> users = mongoStore.loadEntities(UserEntity.class, query, invContext);
+        for (UserEntity user : users) {
+            logger.info("Removing role " + getName() + " from user " + user.getLoginName());
+            mongoStore.pullItemFromList(user, "roleIds", getId(), invContext);
+        }
+
+        // Remove this scope from all users, which has it
+        query = new QueryBuilder()
+                .and("scopeIds").is(getId())
+                .get();
+
+        users = mongoStore.loadEntities(UserEntity.class, query, invContext);
+        for (UserEntity user : users) {
+            logger.info("Removing scope " + getName() + " from user " + user.getLoginName());
+            mongoStore.pullItemFromList(user, "scopeIds", getId(), invContext);
+        }
+
+        // Remove defaultRoles from realm
+        if (realmId != null) {
+            RealmEntity realmEntity = mongoStore.loadEntity(RealmEntity.class, realmId, invContext);
+
+            // Realm might be already removed at this point
+            if (realmEntity != null) {
+                mongoStore.pullItemFromList(realmEntity, "defaultRoles", getId(), invContext);
+            }
+        }
+
+        // Remove defaultRoles from application
+        if (applicationId != null) {
+            ApplicationEntity appEntity = mongoStore.loadEntity(ApplicationEntity.class, applicationId, invContext);
+
+            // Application might be already removed at this point
+            if (appEntity != null) {
+                mongoStore.pullItemFromList(appEntity, "defaultRoles", getId(), invContext);
+            }
+        }
+
+        // Remove this role from others who has it as composite
+        query = new QueryBuilder()
+                .and("compositeRoleIds").is(getId())
+                .get();
+        List<RoleEntity> parentRoles = mongoStore.loadEntities(RoleEntity.class, query, invContext);
+        for (RoleEntity role : parentRoles) {
+            mongoStore.pullItemFromList(role, "compositeRoleIds", getId(), invContext);
+        }
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java
index c21a726..753ab8b 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java
@@ -1,153 +1,153 @@
-package org.keycloak.models.mongo.keycloak.entities;
-
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-@MongoCollection(collectionName = "users")
-public class UserEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
-
-    private String loginName;
-    private String firstName;
-    private String lastName;
-    private String email;
-    private boolean emailVerified;
-    private boolean totp;
-    private boolean enabled;
-
-    private String realmId;
-
-    private List<String> roleIds;
-
-    private Map<String, String> attributes;
-    private List<UserModel.RequiredAction> requiredActions;
-    private List<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
-    private List<SocialLinkEntity> socialLinks;
-
-    @MongoField
-    public String getLoginName() {
-        return loginName;
-    }
-
-    public void setLoginName(String loginName) {
-        this.loginName = loginName;
-    }
-
-    @MongoField
-    public String getFirstName() {
-        return firstName;
-    }
-
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    @MongoField
-    public String getLastName() {
-        return lastName;
-    }
-
-    public void setLastName(String lastName) {
-        this.lastName = lastName;
-    }
-
-    @MongoField
-    public String getEmail() {
-        return email;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    @MongoField
-    public boolean isEmailVerified() {
-        return emailVerified;
-    }
-
-    public void setEmailVerified(boolean emailVerified) {
-        this.emailVerified = emailVerified;
-    }
-
-    @MongoField
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    @MongoField
-    public boolean isTotp() {
-        return totp;
-    }
-
-    public void setTotp(boolean totp) {
-        this.totp = totp;
-    }
-
-    @MongoField
-    public String getRealmId() {
-        return realmId;
-    }
-
-    public void setRealmId(String realmId) {
-        this.realmId = realmId;
-    }
-
-    @MongoField
-    public List<String> getRoleIds() {
-        return roleIds;
-    }
-
-    public void setRoleIds(List<String> roleIds) {
-        this.roleIds = roleIds;
-    }
-
-
-    @MongoField
-    public Map<String, String> getAttributes() {
-        return attributes;
-    }
-
-    public void setAttributes(Map<String, String> attributes) {
-        this.attributes = attributes;
-    }
-
-    @MongoField
-    public List<UserModel.RequiredAction> getRequiredActions() {
-        return requiredActions;
-    }
-
-    public void setRequiredActions(List<UserModel.RequiredAction> requiredActions) {
-        this.requiredActions = requiredActions;
-    }
-
-    @MongoField
-    public List<CredentialEntity> getCredentials() {
-        return credentials;
-    }
-
-    public void setCredentials(List<CredentialEntity> credentials) {
-        this.credentials = credentials;
-    }
-
-    @MongoField
-    public List<SocialLinkEntity> getSocialLinks() {
-        return socialLinks;
-    }
-
-    public void setSocialLinks(List<SocialLinkEntity> socialLinks) {
-        this.socialLinks = socialLinks;
-    }
-}
+package org.keycloak.models.mongo.keycloak.entities;
+
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@MongoCollection(collectionName = "users")
+public class UserEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
+
+    private String loginName;
+    private String firstName;
+    private String lastName;
+    private String email;
+    private boolean emailVerified;
+    private boolean totp;
+    private boolean enabled;
+
+    private String realmId;
+
+    private List<String> roleIds;
+
+    private Map<String, String> attributes;
+    private List<UserModel.RequiredAction> requiredActions;
+    private List<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
+    private List<SocialLinkEntity> socialLinks;
+
+    @MongoField
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    @MongoField
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    @MongoField
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    @MongoField
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    @MongoField
+    public boolean isEmailVerified() {
+        return emailVerified;
+    }
+
+    public void setEmailVerified(boolean emailVerified) {
+        this.emailVerified = emailVerified;
+    }
+
+    @MongoField
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    @MongoField
+    public boolean isTotp() {
+        return totp;
+    }
+
+    public void setTotp(boolean totp) {
+        this.totp = totp;
+    }
+
+    @MongoField
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    @MongoField
+    public List<String> getRoleIds() {
+        return roleIds;
+    }
+
+    public void setRoleIds(List<String> roleIds) {
+        this.roleIds = roleIds;
+    }
+
+
+    @MongoField
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Map<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+    @MongoField
+    public List<UserModel.RequiredAction> getRequiredActions() {
+        return requiredActions;
+    }
+
+    public void setRequiredActions(List<UserModel.RequiredAction> requiredActions) {
+        this.requiredActions = requiredActions;
+    }
+
+    @MongoField
+    public List<CredentialEntity> getCredentials() {
+        return credentials;
+    }
+
+    public void setCredentials(List<CredentialEntity> credentials) {
+        this.credentials = credentials;
+    }
+
+    @MongoField
+    public List<SocialLinkEntity> getSocialLinks() {
+        return socialLinks;
+    }
+
+    public void setSocialLinks(List<SocialLinkEntity> socialLinks) {
+        this.socialLinks = socialLinks;
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java
index 050e936..8b1a26e 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java
@@ -1,54 +1,54 @@
-package org.keycloak.models.mongo.utils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
-import org.bson.types.ObjectId;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.keycloak.adapters.AbstractAdapter;
-import org.keycloak.models.mongo.keycloak.adapters.UserAdapter;
-import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
-import org.keycloak.models.mongo.keycloak.entities.ScopedEntity;
-import org.keycloak.models.mongo.keycloak.entities.UserEntity;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MongoModelUtils {
-
-    // Get everything including both application and realm roles
-    public static List<RoleEntity> getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) {
-        UserEntity userEntity = ((UserAdapter)user).getUser();
-        List<String> roleIds = userEntity.getRoleIds();
-
-        if (roleIds == null || roleIds.isEmpty()) {
-            return Collections.EMPTY_LIST;
-        }
-
-        DBObject query = new QueryBuilder()
-                .and("_id").in(roleIds)
-                .get();
-        return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
-    }
-
-    // Get everything including both application and realm scopes
-    public static List<RoleEntity> getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) {
-        ScopedEntity scopedEntity = (ScopedEntity)((AbstractAdapter)client).getMongoEntity();
-        List<String> scopeIds = scopedEntity.getScopeIds();
-
-        if (scopeIds == null || scopeIds.isEmpty()) {
-            return Collections.EMPTY_LIST;
-        }
-
-        DBObject query = new QueryBuilder()
-                .and("_id").in(scopeIds)
-                .get();
-        return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
-    }
-}
+package org.keycloak.models.mongo.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import com.mongodb.DBObject;
+import com.mongodb.QueryBuilder;
+import org.bson.types.ObjectId;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.keycloak.adapters.AbstractAdapter;
+import org.keycloak.models.mongo.keycloak.adapters.UserAdapter;
+import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
+import org.keycloak.models.mongo.keycloak.entities.ScopedEntity;
+import org.keycloak.models.mongo.keycloak.entities.UserEntity;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoModelUtils {
+
+    // Get everything including both application and realm roles
+    public static List<RoleEntity> getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) {
+        UserEntity userEntity = ((UserAdapter)user).getUser();
+        List<String> roleIds = userEntity.getRoleIds();
+
+        if (roleIds == null || roleIds.isEmpty()) {
+            return Collections.EMPTY_LIST;
+        }
+
+        DBObject query = new QueryBuilder()
+                .and("_id").in(roleIds)
+                .get();
+        return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
+    }
+
+    // Get everything including both application and realm scopes
+    public static List<RoleEntity> getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) {
+        ScopedEntity scopedEntity = (ScopedEntity)((AbstractAdapter)client).getMongoEntity();
+        List<String> scopeIds = scopedEntity.getScopeIds();
+
+        if (scopeIds == null || scopeIds.isEmpty()) {
+            return Collections.EMPTY_LIST;
+        }
+
+        DBObject query = new QueryBuilder()
+                .and("_id").in(scopeIds)
+                .get();
+        return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java
index ce24c63..1b0c075 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java
@@ -1,55 +1,55 @@
-package org.keycloak.models.mongo.utils;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class SystemPropertiesConfigurationProvider {
-
-    private static final String MONGO_HOST = "keycloak.mongo.host";
-    private static final String MONGO_PORT = "keycloak.mongo.port";
-    private static final String MONGO_DB_NAME = "keycloak.mongo.db";
-    private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.mongo.clearOnStartup";
-
-    // Property names from Liveoak . Those are used as fallback in case that original value is not available
-    private static final String MONGO_HOST_2 = "mongo.host";
-    private static final String MONGO_PORT_2 = "mongo.port";
-    private static final String MONGO_DB_NAME_2 = "mongo.db";
-    private static final String MONGO_CLEAR_ON_STARTUP_2 = "mongo.clearCollectionsOnStartup";
-
-    // Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance
-    private static final String MONGO_DEFAULT_PORT = "27017";
-
-    public static String getMongoHost() {
-        return getSystemPropertyWithFallback(MONGO_HOST, MONGO_HOST_2, "localhost");
-    }
-
-    public static int getMongoPort() {
-        String portProp = getSystemPropertyWithFallback(MONGO_PORT, MONGO_PORT_2, MONGO_DEFAULT_PORT);
-        return Integer.parseInt(portProp);
-    }
-
-    public static String getMongoDbName() {
-        return getSystemPropertyWithFallback(MONGO_DB_NAME, MONGO_DB_NAME_2, "keycloak");
-    }
-
-    public static boolean isClearCollectionsOnStartup() {
-        String property = getSystemPropertyWithFallback(MONGO_CLEAR_ON_STARTUP, MONGO_CLEAR_ON_STARTUP_2, "false");
-        return "true".equalsIgnoreCase(property);
-    }
-
-    // Check if property propName1 (like "keycloak.mongo.host" is available and if not, then fallback to property "mongo.host" )
-    private static String getSystemPropertyWithFallback(String propName1, String propName2, String defaultValue) {
-        String propValue1 = System.getProperty(propName1);
-        return propValue1!=null ? propValue1 : System.getProperty(propName2, defaultValue);
-    }
-
-    // Create configuration based on system properties
-    public static MongoConfiguration createConfiguration() {
-        return new MongoConfiguration(
-                getMongoHost(),
-                getMongoPort(),
-                getMongoDbName(),
-                isClearCollectionsOnStartup()
-        );
-    }
-}
+package org.keycloak.models.mongo.utils;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SystemPropertiesConfigurationProvider {
+
+    private static final String MONGO_HOST = "keycloak.mongo.host";
+    private static final String MONGO_PORT = "keycloak.mongo.port";
+    private static final String MONGO_DB_NAME = "keycloak.mongo.db";
+    private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.mongo.clearOnStartup";
+
+    // Property names from Liveoak . Those are used as fallback in case that original value is not available
+    private static final String MONGO_HOST_2 = "mongo.host";
+    private static final String MONGO_PORT_2 = "mongo.port";
+    private static final String MONGO_DB_NAME_2 = "mongo.db";
+    private static final String MONGO_CLEAR_ON_STARTUP_2 = "mongo.clearCollectionsOnStartup";
+
+    // Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance
+    private static final String MONGO_DEFAULT_PORT = "27017";
+
+    public static String getMongoHost() {
+        return getSystemPropertyWithFallback(MONGO_HOST, MONGO_HOST_2, "localhost");
+    }
+
+    public static int getMongoPort() {
+        String portProp = getSystemPropertyWithFallback(MONGO_PORT, MONGO_PORT_2, MONGO_DEFAULT_PORT);
+        return Integer.parseInt(portProp);
+    }
+
+    public static String getMongoDbName() {
+        return getSystemPropertyWithFallback(MONGO_DB_NAME, MONGO_DB_NAME_2, "keycloak");
+    }
+
+    public static boolean isClearCollectionsOnStartup() {
+        String property = getSystemPropertyWithFallback(MONGO_CLEAR_ON_STARTUP, MONGO_CLEAR_ON_STARTUP_2, "false");
+        return "true".equalsIgnoreCase(property);
+    }
+
+    // Check if property propName1 (like "keycloak.mongo.host" is available and if not, then fallback to property "mongo.host" )
+    private static String getSystemPropertyWithFallback(String propName1, String propName2, String defaultValue) {
+        String propValue1 = System.getProperty(propName1);
+        return propValue1!=null ? propValue1 : System.getProperty(propName2, defaultValue);
+    }
+
+    // Create configuration based on system properties
+    public static MongoConfiguration createConfiguration() {
+        return new MongoConfiguration(
+                getMongoHost(),
+                getMongoPort(),
+                getMongoDbName(),
+                isClearCollectionsOnStartup()
+        );
+    }
+}
diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java
index 81bd7d8..30aaa27 100755
--- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java
+++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java
@@ -1,43 +1,43 @@
-package org.keycloak.models.mongo.test;
-
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoField;
-
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class Address implements MongoEntity {
-
-    private String street;
-    private int number;
-    private List<String> flatNumbers;
-
-    @MongoField
-    public String getStreet() {
-        return street;
-    }
-
-    public void setStreet(String street) {
-        this.street = street;
-    }
-
-    @MongoField
-    public int getNumber() {
-        return number;
-    }
-
-    public void setNumber(int number) {
-        this.number = number;
-    }
-
-    @MongoField
-    public List<String> getFlatNumbers() {
-        return flatNumbers;
-    }
-
-    public void setFlatNumbers(List<String> flatNumbers) {
-        this.flatNumbers = flatNumbers;
-    }
-}
+package org.keycloak.models.mongo.test;
+
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoField;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class Address implements MongoEntity {
+
+    private String street;
+    private int number;
+    private List<String> flatNumbers;
+
+    @MongoField
+    public String getStreet() {
+        return street;
+    }
+
+    public void setStreet(String street) {
+        this.street = street;
+    }
+
+    @MongoField
+    public int getNumber() {
+        return number;
+    }
+
+    public void setNumber(int number) {
+        this.number = number;
+    }
+
+    @MongoField
+    public List<String> getFlatNumbers() {
+        return flatNumbers;
+    }
+
+    public void setFlatNumbers(List<String> flatNumbers) {
+        this.flatNumbers = flatNumbers;
+    }
+}
diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java
index fba9489..219293b 100755
--- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java
+++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java
@@ -1,146 +1,146 @@
-package org.keycloak.models.mongo.test;
-
-import com.mongodb.DB;
-import com.mongodb.DBObject;
-import com.mongodb.MongoClient;
-import com.mongodb.QueryBuilder;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.models.mongo.api.MongoEntity;
-import org.keycloak.models.mongo.api.MongoStore;
-import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
-import org.keycloak.models.mongo.impl.MongoStoreImpl;
-import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
-import org.keycloak.models.mongo.utils.SystemPropertiesConfigurationProvider;
-
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class MongoStoreTest {
-
-    private static final Class<? extends MongoEntity>[] MANAGED_DATA_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
-            Person.class,
-            Address.class,
-    };
-
-    private MongoClient mongoClient;
-    private MongoStore mongoStore;
-
-    @Before
-    public void before() throws Exception {
-        try {
-            // TODO: authentication support
-            mongoClient = new MongoClient("localhost", SystemPropertiesConfigurationProvider.getMongoPort());
-
-            DB db = mongoClient.getDB("keycloakTest");
-            mongoStore = new MongoStoreImpl(db, true, MANAGED_DATA_TYPES);
-
-        } catch (UnknownHostException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @After
-    public void after() throws Exception {
-        mongoClient.close();
-    }
-
-    @Test
-    public void mongoModelTest() throws Exception {
-        MongoStoreInvocationContext context = new TransactionMongoStoreInvocationContext(mongoStore);
-
-        // Add some user
-        Person john = new Person();
-        john.setFirstName("john");
-        john.setAge(25);
-        john.setGender(Person.Gender.MALE);
-
-        mongoStore.insertEntity(john, context);
-
-        // Add another user
-        Person mary = new Person();
-        mary.setFirstName("mary");
-        mary.setKids(asList("Peter", "Paul", "Wendy"));
-
-        Address addr1 = new Address();
-        addr1.setStreet("Elm");
-        addr1.setNumber(5);
-        addr1.setFlatNumbers(asList("flat1", "flat2"));
-        Address addr2 = new Address();
-        List<Address> addresses = new ArrayList<Address>();
-        addresses.add(addr1);
-        addresses.add(addr2);
-
-        mary.setAddresses(addresses);
-        mary.setMainAddress(addr1);
-        mary.setGender(Person.Gender.FEMALE);
-        mary.setGenders(asList(Person.Gender.FEMALE));
-
-        mongoStore.insertEntity(mary, context);
-
-        Assert.assertEquals(2, mongoStore.loadEntities(Person.class, new QueryBuilder().get(), context).size());
-
-        DBObject query = new QueryBuilder().and("addresses.flatNumbers").is("flat1").get();
-        List<Person> persons = mongoStore.loadEntities(Person.class, query, context);
-        Assert.assertEquals(1, persons.size());
-        mary = persons.get(0);
-        Assert.assertEquals(mary.getFirstName(), "mary");
-        Assert.assertTrue(mary.getKids().contains("Paul"));
-        Assert.assertEquals(2, mary.getAddresses().size());
-        Assert.assertEquals(Address.class, mary.getAddresses().get(0).getClass());
-
-        // Test push/pull
-        mongoStore.pushItemToList(mary, "kids", "Pauline", true, context);
-        mongoStore.pullItemFromList(mary, "kids", "Paul", context);
-
-        Address addr3 = new Address();
-        addr3.setNumber(6);
-        addr3.setStreet("Broadway");
-        mongoStore.pushItemToList(mary, "addresses", addr3, true, context);
-
-        mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
-        Assert.assertEquals(3, mary.getKids().size());
-        Assert.assertTrue(mary.getKids().contains("Pauline"));
-        Assert.assertFalse(mary.getKids().contains("Paul"));
-        Assert.assertEquals(3, mary.getAddresses().size());
-        Address mainAddress = mary.getMainAddress();
-        Assert.assertEquals("Elm", mainAddress.getStreet());
-        Assert.assertEquals(5, mainAddress.getNumber());
-        Assert.assertEquals(Person.Gender.FEMALE, mary.getGender());
-        Assert.assertTrue(mary.getGenders().contains(Person.Gender.FEMALE));
-
-
-        // Some test of Map (attributes)
-        mary.addAttribute("attr1", "value1");
-        mary.addAttribute("attr2", "value2");
-        mary.addAttribute("attr.some3", "value3");
-        mongoStore.updateEntity(mary, context);
-
-        mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
-        Assert.assertEquals(3, mary.getAttributes().size());
-
-        mary.removeAttribute("attr2");
-        mary.removeAttribute("nonExisting");
-        mongoStore.updateEntity(mary, context);
-
-        mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
-        Assert.assertEquals(2, mary.getAttributes().size());
-        Assert.assertEquals("value1", mary.getAttributes().get("attr1"));
-        Assert.assertEquals("value3", mary.getAttributes().get("attr.some3"));
-
-        context.commit();
-    }
-
-    private <T> List<T> asList(T... objects) {
-        List<T> list = new ArrayList<T>();
-        list.addAll(Arrays.asList(objects));
-        return list;
-    }
-}
+package org.keycloak.models.mongo.test;
+
+import com.mongodb.DB;
+import com.mongodb.DBObject;
+import com.mongodb.MongoClient;
+import com.mongodb.QueryBuilder;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.models.mongo.api.MongoEntity;
+import org.keycloak.models.mongo.api.MongoStore;
+import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.mongo.impl.MongoStoreImpl;
+import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
+import org.keycloak.models.mongo.utils.SystemPropertiesConfigurationProvider;
+
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MongoStoreTest {
+
+    private static final Class<? extends MongoEntity>[] MANAGED_DATA_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
+            Person.class,
+            Address.class,
+    };
+
+    private MongoClient mongoClient;
+    private MongoStore mongoStore;
+
+    @Before
+    public void before() throws Exception {
+        try {
+            // TODO: authentication support
+            mongoClient = new MongoClient("localhost", SystemPropertiesConfigurationProvider.getMongoPort());
+
+            DB db = mongoClient.getDB("keycloakTest");
+            mongoStore = new MongoStoreImpl(db, true, MANAGED_DATA_TYPES);
+
+        } catch (UnknownHostException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @After
+    public void after() throws Exception {
+        mongoClient.close();
+    }
+
+    @Test
+    public void mongoModelTest() throws Exception {
+        MongoStoreInvocationContext context = new TransactionMongoStoreInvocationContext(mongoStore);
+
+        // Add some user
+        Person john = new Person();
+        john.setFirstName("john");
+        john.setAge(25);
+        john.setGender(Person.Gender.MALE);
+
+        mongoStore.insertEntity(john, context);
+
+        // Add another user
+        Person mary = new Person();
+        mary.setFirstName("mary");
+        mary.setKids(asList("Peter", "Paul", "Wendy"));
+
+        Address addr1 = new Address();
+        addr1.setStreet("Elm");
+        addr1.setNumber(5);
+        addr1.setFlatNumbers(asList("flat1", "flat2"));
+        Address addr2 = new Address();
+        List<Address> addresses = new ArrayList<Address>();
+        addresses.add(addr1);
+        addresses.add(addr2);
+
+        mary.setAddresses(addresses);
+        mary.setMainAddress(addr1);
+        mary.setGender(Person.Gender.FEMALE);
+        mary.setGenders(asList(Person.Gender.FEMALE));
+
+        mongoStore.insertEntity(mary, context);
+
+        Assert.assertEquals(2, mongoStore.loadEntities(Person.class, new QueryBuilder().get(), context).size());
+
+        DBObject query = new QueryBuilder().and("addresses.flatNumbers").is("flat1").get();
+        List<Person> persons = mongoStore.loadEntities(Person.class, query, context);
+        Assert.assertEquals(1, persons.size());
+        mary = persons.get(0);
+        Assert.assertEquals(mary.getFirstName(), "mary");
+        Assert.assertTrue(mary.getKids().contains("Paul"));
+        Assert.assertEquals(2, mary.getAddresses().size());
+        Assert.assertEquals(Address.class, mary.getAddresses().get(0).getClass());
+
+        // Test push/pull
+        mongoStore.pushItemToList(mary, "kids", "Pauline", true, context);
+        mongoStore.pullItemFromList(mary, "kids", "Paul", context);
+
+        Address addr3 = new Address();
+        addr3.setNumber(6);
+        addr3.setStreet("Broadway");
+        mongoStore.pushItemToList(mary, "addresses", addr3, true, context);
+
+        mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
+        Assert.assertEquals(3, mary.getKids().size());
+        Assert.assertTrue(mary.getKids().contains("Pauline"));
+        Assert.assertFalse(mary.getKids().contains("Paul"));
+        Assert.assertEquals(3, mary.getAddresses().size());
+        Address mainAddress = mary.getMainAddress();
+        Assert.assertEquals("Elm", mainAddress.getStreet());
+        Assert.assertEquals(5, mainAddress.getNumber());
+        Assert.assertEquals(Person.Gender.FEMALE, mary.getGender());
+        Assert.assertTrue(mary.getGenders().contains(Person.Gender.FEMALE));
+
+
+        // Some test of Map (attributes)
+        mary.addAttribute("attr1", "value1");
+        mary.addAttribute("attr2", "value2");
+        mary.addAttribute("attr.some3", "value3");
+        mongoStore.updateEntity(mary, context);
+
+        mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
+        Assert.assertEquals(3, mary.getAttributes().size());
+
+        mary.removeAttribute("attr2");
+        mary.removeAttribute("nonExisting");
+        mongoStore.updateEntity(mary, context);
+
+        mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
+        Assert.assertEquals(2, mary.getAttributes().size());
+        Assert.assertEquals("value1", mary.getAttributes().get("attr1"));
+        Assert.assertEquals("value3", mary.getAttributes().get("attr.some3"));
+
+        context.commit();
+    }
+
+    private <T> List<T> asList(T... objects) {
+        List<T> list = new ArrayList<T>();
+        list.addAll(Arrays.asList(objects));
+        return list;
+    }
+}
diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java
index 47ac69b..8881126 100755
--- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java
+++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java
@@ -1,109 +1,109 @@
-package org.keycloak.models.mongo.test;
-
-import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
-import org.keycloak.models.mongo.api.MongoCollection;
-import org.keycloak.models.mongo.api.MongoField;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-@MongoCollection(collectionName = "persons")
-public class Person extends AbstractMongoIdentifiableEntity {
-
-    private String firstName;
-    private int age;
-    private List<String> kids;
-    private List<Address> addresses;
-    private Address mainAddress;
-    private Gender gender;
-    private List<Gender> genders;
-    private Map<String, String> attributes = new HashMap<String, String>();
-
-    @MongoField
-    public String getFirstName() {
-        return firstName;
-    }
-
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    @MongoField
-    public int getAge() {
-        return age;
-    }
-
-    public void setAge(int age) {
-        this.age = age;
-    }
-
-    @MongoField
-    public Gender getGender() {
-        return gender;
-    }
-
-    public void setGender(Gender gender) {
-        this.gender = gender;
-    }
-
-    @MongoField
-    public List<Gender> getGenders() {
-        return genders;
-    }
-
-    public void setGenders(List<Gender> genders) {
-        this.genders = genders;
-    }
-
-    @MongoField
-    public List<String> getKids() {
-        return kids;
-    }
-
-    public void setKids(List<String> kids) {
-        this.kids = kids;
-    }
-
-    @MongoField
-    public List<Address> getAddresses() {
-        return addresses;
-    }
-
-    public void setAddresses(List<Address> addresses) {
-        this.addresses = addresses;
-    }
-
-    @MongoField
-    public Address getMainAddress() {
-        return mainAddress;
-    }
-
-    public void setMainAddress(Address mainAddress) {
-        this.mainAddress = mainAddress;
-    }
-
-    @MongoField
-    public Map<String, String> getAttributes() {
-        return attributes;
-    }
-
-    public void setAttributes(Map<String, String> attributes) {
-        this.attributes = attributes;
-    }
-
-    public void addAttribute(String key, String value) {
-        attributes.put(key, value);
-    }
-
-    public void removeAttribute(String key) {
-        attributes.remove(key);
-    }
-
-    public static enum Gender {
-        MALE, FEMALE
-    }
-}
+package org.keycloak.models.mongo.test;
+
+import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
+import org.keycloak.models.mongo.api.MongoCollection;
+import org.keycloak.models.mongo.api.MongoField;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@MongoCollection(collectionName = "persons")
+public class Person extends AbstractMongoIdentifiableEntity {
+
+    private String firstName;
+    private int age;
+    private List<String> kids;
+    private List<Address> addresses;
+    private Address mainAddress;
+    private Gender gender;
+    private List<Gender> genders;
+    private Map<String, String> attributes = new HashMap<String, String>();
+
+    @MongoField
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    @MongoField
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    @MongoField
+    public Gender getGender() {
+        return gender;
+    }
+
+    public void setGender(Gender gender) {
+        this.gender = gender;
+    }
+
+    @MongoField
+    public List<Gender> getGenders() {
+        return genders;
+    }
+
+    public void setGenders(List<Gender> genders) {
+        this.genders = genders;
+    }
+
+    @MongoField
+    public List<String> getKids() {
+        return kids;
+    }
+
+    public void setKids(List<String> kids) {
+        this.kids = kids;
+    }
+
+    @MongoField
+    public List<Address> getAddresses() {
+        return addresses;
+    }
+
+    public void setAddresses(List<Address> addresses) {
+        this.addresses = addresses;
+    }
+
+    @MongoField
+    public Address getMainAddress() {
+        return mainAddress;
+    }
+
+    public void setMainAddress(Address mainAddress) {
+        this.mainAddress = mainAddress;
+    }
+
+    @MongoField
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Map<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+    public void addAttribute(String key, String value) {
+        attributes.put(key, value);
+    }
+
+    public void removeAttribute(String key) {
+        attributes.remove(key);
+    }
+
+    public static enum Gender {
+        MALE, FEMALE
+    }
+}
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
index 2dc9d63..9fa72d0 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
@@ -1,308 +1,308 @@
-package org.keycloak.models.picketlink;
-
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.picketlink.mappings.ApplicationData;
-import org.keycloak.models.picketlink.relationships.ScopeRelationship;
-import org.picketlink.idm.IdentityManagementException;
-import org.picketlink.idm.IdentityManager;
-import org.picketlink.idm.PartitionManager;
-import org.picketlink.idm.RelationshipManager;
-import org.picketlink.idm.model.IdentityType;
-import org.picketlink.idm.model.sample.Grant;
-import org.picketlink.idm.model.sample.Role;
-import org.picketlink.idm.model.sample.SampleModel;
-import org.picketlink.idm.query.IdentityQuery;
-import org.picketlink.idm.query.RelationshipQuery;
-
-import java.util.*;
-
-/**
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-public class ApplicationAdapter implements ApplicationModel {
-    protected ApplicationData applicationData;
-    protected RealmAdapter realm;
-    protected IdentityManager idm;
-    protected PartitionManager partitionManager;
-    protected RelationshipManager relationshipManager;
-
-    public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) {
-        this.applicationData = applicationData;
-        this.realm = realm;
-        this.partitionManager = partitionManager;
-    }
-
-    protected IdentityManager getIdm() {
-        if (idm == null) idm = partitionManager.createIdentityManager(applicationData);
-        return idm;
-    }
-
-    protected RelationshipManager getRelationshipManager() {
-        if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager();
-        return relationshipManager;
-    }
-
-    @Override
-    public void updateApplication() {
-        partitionManager.update(applicationData);
-    }
-
-    @Override
-    public UserAdapter getApplicationUser() {
-        return new UserAdapter(applicationData.getResourceUser(), realm.getIdm());
-    }
-
-    @Override
-    public String getId() {
-        // for some reason picketlink queries by name when finding partition, don't know what ID is used for now
-        return applicationData.getName();
-    }
-
-    @Override
-    public String getName() {
-        return applicationData.getResourceName();
-    }
-
-    @Override
-    public void setName(String name) {
-        applicationData.setResourceName(name);
-        updateApplication();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return applicationData.isEnabled();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        applicationData.setEnabled(enabled);
-        updateApplication();
-    }
-
-    @Override
-    public boolean isSurrogateAuthRequired() {
-        return applicationData.isSurrogateAuthRequired();
-    }
-
-    @Override
-    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
-        applicationData.setSurrogateAuthRequired(surrogateAuthRequired);
-        updateApplication();
-    }
-
-    @Override
-    public String getManagementUrl() {
-        return applicationData.getManagementUrl();
-    }
-
-    @Override
-    public void setManagementUrl(String url) {
-        applicationData.setManagementUrl(url);
-        updateApplication();
-    }
-
-    @Override
-    public String getBaseUrl() {
-        return applicationData.getBaseUrl();
-    }
-
-    @Override
-    public void setBaseUrl(String url) {
-        applicationData.setBaseUrl(url);
-        updateApplication();
-    }
-
-    @Override
-    public RoleAdapter getRole(String name) {
-        Role role = SampleModel.getRole(getIdm(), name);
-        if (role == null) return null;
-        return new RoleAdapter(role, getIdm());
-    }
-
-    @Override
-    public RoleModel getRoleById(String id) {
-        IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
-        query.setParameter(IdentityType.ID, id);
-        List<Role> roles = query.getResultList();
-        if (roles.size() == 0) return null;
-        return new RoleAdapter(roles.get(0), getIdm());
-    }
-
-    @Override
-    public void grantRole(UserModel user, RoleModel role) {
-        SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
-    }
-
-    @Override
-    public boolean hasRole(UserModel user, RoleModel role) {
-        return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
-    }
-
-    @Override
-    public boolean hasRole(UserModel user, String role) {
-        RoleModel roleModel = getRole(role);
-        return hasRole(user, roleModel);
-    }
-
-    @Override
-    public RoleAdapter addRole(String name) {
-        Role role = new Role(name);
-        getIdm().add(role);
-        return new RoleAdapter(role, getIdm());
-    }
-
-    @Override
-    public boolean removeRoleById(String id) {
-        try {
-            getIdm().remove(getIdm().lookupIdentityById(Role.class, id));
-            return true;
-        } catch (IdentityManagementException e) {
-            return false;
-        }
-    }
-
-    @Override
-    public List<RoleModel> getRoles() {
-        IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
-        query.setParameter(Role.PARTITION, applicationData);
-        List<Role> roles = query.getResultList();
-        List<RoleModel> roleModels = new ArrayList<RoleModel>();
-        for (Role role : roles) {
-            roleModels.add(new RoleAdapter(role, idm));
-        }
-        return roleModels;
-    }
-
-    @Override
-    public Set<String> getRoleMappingValues(UserModel user) {
-        RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
-        query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
-        List<Grant> grants = query.getResultList();
-        HashSet<String> set = new HashSet<String>();
-        for (Grant grant : grants) {
-            if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName());
-        }
-        return set;
-    }
-
-    @Override
-    public List<RoleModel> getRoleMappings(UserModel user) {
-        RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
-        query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
-        List<Grant> grants = query.getResultList();
-        List<RoleModel> set = new ArrayList<RoleModel>();
-        for (Grant grant : grants) {
-            if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm()));
-        }
-        return set;
-    }
-
-    @Override
-    public void deleteRoleMapping(UserModel user, RoleModel role) {
-        RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
-        query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
-        query.setParameter(Grant.ROLE, ((RoleAdapter)role).getRole());
-        List<Grant> grants = query.getResultList();
-        for (Grant grant : grants) {
-            getRelationshipManager().remove(grant);
-        }
-    }
-
-    @Override
-    public void addScopeMapping(UserModel agent, String roleName) {
-        IdentityManager idm = getIdm();
-        Role role = SampleModel.getRole(idm,roleName);
-        if (role == null) throw new RuntimeException("role not found");
-        addScopeMapping(agent, new RoleAdapter(role, idm));
-
-    }
-
-    @Override
-    public void addScopeMapping(UserModel agent, RoleModel role) {
-        ScopeRelationship scope = new ScopeRelationship();
-        scope.setClient(((UserAdapter)agent).getUser());
-        scope.setScope(((RoleAdapter)role).getRole());
-        getRelationshipManager().add(scope);
-    }
-
-    @Override
-    public void deleteScopeMapping(UserModel user, RoleModel role) {
-        RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
-        query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser());
-        query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole());
-        List<ScopeRelationship> grants = query.getResultList();
-        for (ScopeRelationship grant : grants) {
-            getRelationshipManager().remove(grant);
-        }
-    }
-
-
-    @Override
-    public Set<String> getScopeMappingValues(UserModel agent) {
-        RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
-        query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
-        List<ScopeRelationship> scope = query.getResultList();
-        HashSet<String> set = new HashSet<String>();
-        for (ScopeRelationship rel : scope) {
-            if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName());
-        }
-        return set;
-    }
-
-    @Override
-    public List<RoleModel> getScopeMappings(UserModel agent) {
-        RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
-        query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
-        List<ScopeRelationship> scope = query.getResultList();
-        List<RoleModel> roles = new ArrayList<RoleModel>();
-        for (ScopeRelationship rel : scope) {
-            if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm()));
-        }
-        return roles;
-    }
-
-    @Override
-    public List<String> getDefaultRoles() {
-        if ( applicationData.getDefaultRoles() != null) {
-            return Arrays.asList(applicationData.getDefaultRoles());
-        }
-        else {
-            return Collections.emptyList();
-        }
-    }
-
-    @Override
-    public void addDefaultRole(String name) {
-        if (getRole(name) == null) {
-            addRole(name);
-        }
-
-        String[] defaultRoles = applicationData.getDefaultRoles();
-        if (defaultRoles == null) {
-            defaultRoles = new String[1];
-        } else {
-            defaultRoles = Arrays.copyOf(defaultRoles, defaultRoles.length + 1);
-        }
-        defaultRoles[defaultRoles.length - 1] = name;
-
-        applicationData.setDefaultRoles(defaultRoles);
-        updateApplication();
-    }
-
-    @Override
-    public void updateDefaultRoles(String[] defaultRoles) {
-        for (String name : defaultRoles) {
-            if (getRole(name) == null) {
-                addRole(name);
-            }
-        }
-
-        applicationData.setDefaultRoles(defaultRoles);
-        updateApplication();
-    }
-
-}
+package org.keycloak.models.picketlink;
+
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.picketlink.mappings.ApplicationData;
+import org.keycloak.models.picketlink.relationships.ScopeRelationship;
+import org.picketlink.idm.IdentityManagementException;
+import org.picketlink.idm.IdentityManager;
+import org.picketlink.idm.PartitionManager;
+import org.picketlink.idm.RelationshipManager;
+import org.picketlink.idm.model.IdentityType;
+import org.picketlink.idm.model.sample.Grant;
+import org.picketlink.idm.model.sample.Role;
+import org.picketlink.idm.model.sample.SampleModel;
+import org.picketlink.idm.query.IdentityQuery;
+import org.picketlink.idm.query.RelationshipQuery;
+
+import java.util.*;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ApplicationAdapter implements ApplicationModel {
+    protected ApplicationData applicationData;
+    protected RealmAdapter realm;
+    protected IdentityManager idm;
+    protected PartitionManager partitionManager;
+    protected RelationshipManager relationshipManager;
+
+    public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) {
+        this.applicationData = applicationData;
+        this.realm = realm;
+        this.partitionManager = partitionManager;
+    }
+
+    protected IdentityManager getIdm() {
+        if (idm == null) idm = partitionManager.createIdentityManager(applicationData);
+        return idm;
+    }
+
+    protected RelationshipManager getRelationshipManager() {
+        if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager();
+        return relationshipManager;
+    }
+
+    @Override
+    public void updateApplication() {
+        partitionManager.update(applicationData);
+    }
+
+    @Override
+    public UserAdapter getApplicationUser() {
+        return new UserAdapter(applicationData.getResourceUser(), realm.getIdm());
+    }
+
+    @Override
+    public String getId() {
+        // for some reason picketlink queries by name when finding partition, don't know what ID is used for now
+        return applicationData.getName();
+    }
+
+    @Override
+    public String getName() {
+        return applicationData.getResourceName();
+    }
+
+    @Override
+    public void setName(String name) {
+        applicationData.setResourceName(name);
+        updateApplication();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return applicationData.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        applicationData.setEnabled(enabled);
+        updateApplication();
+    }
+
+    @Override
+    public boolean isSurrogateAuthRequired() {
+        return applicationData.isSurrogateAuthRequired();
+    }
+
+    @Override
+    public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        applicationData.setSurrogateAuthRequired(surrogateAuthRequired);
+        updateApplication();
+    }
+
+    @Override
+    public String getManagementUrl() {
+        return applicationData.getManagementUrl();
+    }
+
+    @Override
+    public void setManagementUrl(String url) {
+        applicationData.setManagementUrl(url);
+        updateApplication();
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return applicationData.getBaseUrl();
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        applicationData.setBaseUrl(url);
+        updateApplication();
+    }
+
+    @Override
+    public RoleAdapter getRole(String name) {
+        Role role = SampleModel.getRole(getIdm(), name);
+        if (role == null) return null;
+        return new RoleAdapter(role, getIdm());
+    }
+
+    @Override
+    public RoleModel getRoleById(String id) {
+        IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
+        query.setParameter(IdentityType.ID, id);
+        List<Role> roles = query.getResultList();
+        if (roles.size() == 0) return null;
+        return new RoleAdapter(roles.get(0), getIdm());
+    }
+
+    @Override
+    public void grantRole(UserModel user, RoleModel role) {
+        SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, RoleModel role) {
+        return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, String role) {
+        RoleModel roleModel = getRole(role);
+        return hasRole(user, roleModel);
+    }
+
+    @Override
+    public RoleAdapter addRole(String name) {
+        Role role = new Role(name);
+        getIdm().add(role);
+        return new RoleAdapter(role, getIdm());
+    }
+
+    @Override
+    public boolean removeRoleById(String id) {
+        try {
+            getIdm().remove(getIdm().lookupIdentityById(Role.class, id));
+            return true;
+        } catch (IdentityManagementException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public List<RoleModel> getRoles() {
+        IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
+        query.setParameter(Role.PARTITION, applicationData);
+        List<Role> roles = query.getResultList();
+        List<RoleModel> roleModels = new ArrayList<RoleModel>();
+        for (Role role : roles) {
+            roleModels.add(new RoleAdapter(role, idm));
+        }
+        return roleModels;
+    }
+
+    @Override
+    public Set<String> getRoleMappingValues(UserModel user) {
+        RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
+        query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
+        List<Grant> grants = query.getResultList();
+        HashSet<String> set = new HashSet<String>();
+        for (Grant grant : grants) {
+            if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName());
+        }
+        return set;
+    }
+
+    @Override
+    public List<RoleModel> getRoleMappings(UserModel user) {
+        RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
+        query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
+        List<Grant> grants = query.getResultList();
+        List<RoleModel> set = new ArrayList<RoleModel>();
+        for (Grant grant : grants) {
+            if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm()));
+        }
+        return set;
+    }
+
+    @Override
+    public void deleteRoleMapping(UserModel user, RoleModel role) {
+        RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
+        query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
+        query.setParameter(Grant.ROLE, ((RoleAdapter)role).getRole());
+        List<Grant> grants = query.getResultList();
+        for (Grant grant : grants) {
+            getRelationshipManager().remove(grant);
+        }
+    }
+
+    @Override
+    public void addScopeMapping(UserModel agent, String roleName) {
+        IdentityManager idm = getIdm();
+        Role role = SampleModel.getRole(idm,roleName);
+        if (role == null) throw new RuntimeException("role not found");
+        addScopeMapping(agent, new RoleAdapter(role, idm));
+
+    }
+
+    @Override
+    public void addScopeMapping(UserModel agent, RoleModel role) {
+        ScopeRelationship scope = new ScopeRelationship();
+        scope.setClient(((UserAdapter)agent).getUser());
+        scope.setScope(((RoleAdapter)role).getRole());
+        getRelationshipManager().add(scope);
+    }
+
+    @Override
+    public void deleteScopeMapping(UserModel user, RoleModel role) {
+        RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
+        query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser());
+        query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole());
+        List<ScopeRelationship> grants = query.getResultList();
+        for (ScopeRelationship grant : grants) {
+            getRelationshipManager().remove(grant);
+        }
+    }
+
+
+    @Override
+    public Set<String> getScopeMappingValues(UserModel agent) {
+        RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
+        query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
+        List<ScopeRelationship> scope = query.getResultList();
+        HashSet<String> set = new HashSet<String>();
+        for (ScopeRelationship rel : scope) {
+            if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName());
+        }
+        return set;
+    }
+
+    @Override
+    public List<RoleModel> getScopeMappings(UserModel agent) {
+        RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
+        query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
+        List<ScopeRelationship> scope = query.getResultList();
+        List<RoleModel> roles = new ArrayList<RoleModel>();
+        for (ScopeRelationship rel : scope) {
+            if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm()));
+        }
+        return roles;
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        if ( applicationData.getDefaultRoles() != null) {
+            return Arrays.asList(applicationData.getDefaultRoles());
+        }
+        else {
+            return Collections.emptyList();
+        }
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        if (getRole(name) == null) {
+            addRole(name);
+        }
+
+        String[] defaultRoles = applicationData.getDefaultRoles();
+        if (defaultRoles == null) {
+            defaultRoles = new String[1];
+        } else {
+            defaultRoles = Arrays.copyOf(defaultRoles, defaultRoles.length + 1);
+        }
+        defaultRoles[defaultRoles.length - 1] = name;
+
+        applicationData.setDefaultRoles(defaultRoles);
+        updateApplication();
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        for (String name : defaultRoles) {
+            if (getRole(name) == null) {
+                addRole(name);
+            }
+        }
+
+        applicationData.setDefaultRoles(defaultRoles);
+        updateApplication();
+    }
+
+}
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java
index da8f04f..62ec7e3 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java
@@ -1,73 +1,73 @@
-package org.keycloak.models.picketlink.relationships;
-
-import org.picketlink.idm.model.AbstractAttributedType;
-import org.picketlink.idm.model.Attribute;
-import org.picketlink.idm.model.Relationship;
-import org.picketlink.idm.model.annotation.AttributeProperty;
-import org.picketlink.idm.model.sample.User;
-import org.picketlink.idm.query.AttributeParameter;
-import org.picketlink.idm.query.RelationshipQueryParameter;
-
-/**
- * Binding between user and his social username for particular Social provider
- *
- * Example: Keycloak user "john" has username "john123" in social provider "facebook"
- *
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class SocialLinkRelationship extends AbstractAttributedType implements Relationship {
-
-    private static final long serialVersionUID = 154879L;
-
-    public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider");
-    public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername");
-
-    // realm is needed to allow searching as combination socialUsername+socialProvider may not be unique
-    // (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2")
-    public static final AttributeParameter REALM = new AttributeParameter("realm");
-
-    public static final RelationshipQueryParameter USER = new RelationshipQueryParameter() {
-
-        @Override
-        public String getName() {
-            return "user";
-        }
-    };
-
-    private User user;
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    @AttributeProperty
-    public String getSocialProvider() {
-        return (String)getAttribute("socialProvider").getValue();
-    }
-
-    public void setSocialProvider(String socialProvider) {
-        setAttribute(new Attribute<String>("socialProvider", socialProvider));
-    }
-
-    @AttributeProperty
-    public String getSocialUsername() {
-        return (String)getAttribute("socialUsername").getValue();
-    }
-
-    public void setSocialUsername(String socialProviderUserId) {
-        setAttribute(new Attribute<String>("socialUsername", socialProviderUserId));
-    }
-
-    @AttributeProperty
-    public String getRealm() {
-        return (String)getAttribute("realm").getValue();
-    }
-
-    public void setRealm(String realm) {
-        setAttribute(new Attribute<String>("realm", realm));
-    }
-}
+package org.keycloak.models.picketlink.relationships;
+
+import org.picketlink.idm.model.AbstractAttributedType;
+import org.picketlink.idm.model.Attribute;
+import org.picketlink.idm.model.Relationship;
+import org.picketlink.idm.model.annotation.AttributeProperty;
+import org.picketlink.idm.model.sample.User;
+import org.picketlink.idm.query.AttributeParameter;
+import org.picketlink.idm.query.RelationshipQueryParameter;
+
+/**
+ * Binding between user and his social username for particular Social provider
+ *
+ * Example: Keycloak user "john" has username "john123" in social provider "facebook"
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SocialLinkRelationship extends AbstractAttributedType implements Relationship {
+
+    private static final long serialVersionUID = 154879L;
+
+    public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider");
+    public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername");
+
+    // realm is needed to allow searching as combination socialUsername+socialProvider may not be unique
+    // (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2")
+    public static final AttributeParameter REALM = new AttributeParameter("realm");
+
+    public static final RelationshipQueryParameter USER = new RelationshipQueryParameter() {
+
+        @Override
+        public String getName() {
+            return "user";
+        }
+    };
+
+    private User user;
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    @AttributeProperty
+    public String getSocialProvider() {
+        return (String)getAttribute("socialProvider").getValue();
+    }
+
+    public void setSocialProvider(String socialProvider) {
+        setAttribute(new Attribute<String>("socialProvider", socialProvider));
+    }
+
+    @AttributeProperty
+    public String getSocialUsername() {
+        return (String)getAttribute("socialUsername").getValue();
+    }
+
+    public void setSocialUsername(String socialProviderUserId) {
+        setAttribute(new Attribute<String>("socialUsername", socialProviderUserId));
+    }
+
+    @AttributeProperty
+    public String getRealm() {
+        return (String)getAttribute("realm").getValue();
+    }
+
+    public void setRealm(String realm) {
+        setAttribute(new Attribute<String>("realm", realm));
+    }
+}

model/tests/pom.xml 138(+69 -69)

diff --git a/model/tests/pom.xml b/model/tests/pom.xml
index 8357eaa..c56a075 100755
--- a/model/tests/pom.xml
+++ b/model/tests/pom.xml
@@ -1,69 +1,69 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>keycloak-parent</artifactId>
-        <groupId>org.keycloak</groupId>
-        <version>1.0-alpha-3-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>keycloak-model-tests</artifactId>
-    <name>Keycloak Model Tests</name>
-    <description/>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-services</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.codehaus.jackson</groupId>
-            <artifactId>jackson-core-asl</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.codehaus.jackson</groupId>
-            <artifactId>jackson-mapper-asl</artifactId>
-            <scope>compile</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>package-tests-jar</id>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>test-jar</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <skipTests>true</skipTests>
-                </configuration>
-            </plugin>
-
-        </plugins>
-    </build>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>keycloak-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.0-alpha-3-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-model-tests</artifactId>
+    <name>Keycloak Model Tests</name>
+    <description/>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-services</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>package-tests-jar</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+
+</project>
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 c73f3b0..7a29945 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
@@ -241,8 +241,8 @@ public class AdapterTest extends AbstractModelTest {
         Assert.assertFalse(realmModel.removeRoleById(realmRole.getId()));
         Assert.assertNull(realmModel.getRole(realmRole.getName()));
 
-        Assert.assertTrue(app.removeRoleById(appRole.getId()));
-        Assert.assertFalse(app.removeRoleById(appRole.getId()));
+        Assert.assertTrue(realmModel.removeRoleById(appRole.getId()));
+        Assert.assertFalse(realmModel.removeRoleById(appRole.getId()));
         Assert.assertNull(app.getRole(appRole.getName()));
     }
 
@@ -431,13 +431,9 @@ public class AdapterTest extends AbstractModelTest {
         Set<RoleModel> appRoles = application.getRoles();
         Assert.assertEquals(2, appRoles.size());
         RoleModel appBarRole = application.getRole("bar");
+        Assert.assertNotNull(appBarRole);
 
-        // This should return null because it's realmRole
-        Assert.assertNull(application.getRoleById(realmUserRole.getId()));
-
-        // This should return null because appBarRole is application role
-        Assert.assertNull(realmModel.getRoleById(appBarRole.getId()));
-        found = application.getRoleById(appBarRole.getId());
+        found = realmModel.getRoleById(appBarRole.getId());
         Assert.assertNotNull(found);
         assertRolesEquals(found, appBarRole);
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
index c314619..ba7a03b 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
@@ -1,86 +1,86 @@
-package org.keycloak.model.test;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.services.managers.ApplicationManager;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
- */
-public class ApplicationModelTest extends AbstractModelTest {
-    private ApplicationModel application;
-    private RealmModel realm;
-    private ApplicationManager appManager;
-
-    @Before
-    public void before() throws Exception {
-        super.before();
-        appManager = new ApplicationManager(realmManager);
-
-        realm = realmManager.createRealm("original");
-        application = realm.addApplication("application");
-        application.setBaseUrl("http://base");
-        application.setManagementUrl("http://management");
-        application.setName("app-name");
-        application.addRole("role-1");
-        application.addRole("role-2");
-        application.addRole("role-3");
-        application.addDefaultRole("role-1");
-        application.addDefaultRole("role-2");
-
-        application.addRedirectUri("redirect-1");
-        application.addRedirectUri("redirect-2");
-
-        application.addWebOrigin("origin-1");
-        application.addWebOrigin("origin-2");
-
-        application.updateApplication();
-    }
-
-    @Test
-    public void persist() {
-        RealmModel persisted = realmManager.getRealm(realm.getId());
-
-        assertEquals(application, persisted.getApplicationNameMap().get("app-name"));
-    }
-
-    @Test
-    public void json() {
-        ApplicationRepresentation representation = appManager.toRepresentation(application);
-
-        RealmModel realm = realmManager.createRealm("copy");
-        ApplicationModel copy = appManager.createApplication(realm, representation);
-
-        assertEquals(application, copy);
-    }
-
-    public static void assertEquals(ApplicationModel expected, ApplicationModel actual) {
-        Assert.assertEquals(expected.getName(), actual.getName());
-        Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
-        Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
-        Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
-
-        Assert.assertTrue(expected.getRedirectUris().containsAll(actual.getRedirectUris()));
-        Assert.assertTrue(expected.getWebOrigins().containsAll(actual.getWebOrigins()));
-    }
-
-    public static void assertEquals(List<RoleModel> expected, List<RoleModel> actual) {
-        Assert.assertEquals(expected.size(), actual.size());
-        Iterator<RoleModel> exp = expected.iterator();
-        Iterator<RoleModel> act = actual.iterator();
-        while (exp.hasNext()) {
-            Assert.assertEquals(exp.next().getName(), act.next().getName());
-        }
-    }
-
-}
-
+package org.keycloak.model.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.services.managers.ApplicationManager;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class ApplicationModelTest extends AbstractModelTest {
+    private ApplicationModel application;
+    private RealmModel realm;
+    private ApplicationManager appManager;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        appManager = new ApplicationManager(realmManager);
+
+        realm = realmManager.createRealm("original");
+        application = realm.addApplication("application");
+        application.setBaseUrl("http://base");
+        application.setManagementUrl("http://management");
+        application.setName("app-name");
+        application.addRole("role-1");
+        application.addRole("role-2");
+        application.addRole("role-3");
+        application.addDefaultRole("role-1");
+        application.addDefaultRole("role-2");
+
+        application.addRedirectUri("redirect-1");
+        application.addRedirectUri("redirect-2");
+
+        application.addWebOrigin("origin-1");
+        application.addWebOrigin("origin-2");
+
+        application.updateApplication();
+    }
+
+    @Test
+    public void persist() {
+        RealmModel persisted = realmManager.getRealm(realm.getId());
+
+        assertEquals(application, persisted.getApplicationNameMap().get("app-name"));
+    }
+
+    @Test
+    public void json() {
+        ApplicationRepresentation representation = appManager.toRepresentation(application);
+
+        RealmModel realm = realmManager.createRealm("copy");
+        ApplicationModel copy = appManager.createApplication(realm, representation);
+
+        assertEquals(application, copy);
+    }
+
+    public static void assertEquals(ApplicationModel expected, ApplicationModel actual) {
+        Assert.assertEquals(expected.getName(), actual.getName());
+        Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
+        Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
+        Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
+
+        Assert.assertTrue(expected.getRedirectUris().containsAll(actual.getRedirectUris()));
+        Assert.assertTrue(expected.getWebOrigins().containsAll(actual.getWebOrigins()));
+    }
+
+    public static void assertEquals(List<RoleModel> expected, List<RoleModel> actual) {
+        Assert.assertEquals(expected.size(), actual.size());
+        Iterator<RoleModel> exp = expected.iterator();
+        Iterator<RoleModel> act = actual.iterator();
+        while (exp.hasNext()) {
+            Assert.assertEquals(exp.next().getName(), act.next().getName());
+        }
+    }
+
+}
+
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 c4d316c..3faddc9 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
@@ -1,150 +1,150 @@
-package org.keycloak.model.test;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserModel.RequiredAction;
-import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
-
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import java.util.UUID;
-
-public class AuthenticationManagerTest extends AbstractModelTest {
-
-    private AuthenticationManager am;
-    private MultivaluedMap<String, String> formData;
-    private TimeBasedOTP otp;
-    private RealmModel realm;
-    private UserModel user;
-
-    @Test
-    public void authForm() {
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
-    }
-
-    @Test
-    public void authFormInvalidPassword() {
-        formData.remove(CredentialRepresentation.PASSWORD);
-        formData.add(CredentialRepresentation.PASSWORD, "invalid");
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
-    }
-
-    @Test
-    public void authFormMissingPassword() {
-        formData.remove(CredentialRepresentation.PASSWORD);
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
-    }
-
-    @Test
-    public void authFormRequiredAction() {
-        realm.addRequiredCredential(CredentialRepresentation.TOTP);
-        user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
-        
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
-    }
-
-    @Test
-    public void authFormUserDisabled() {
-        user.setEnabled(false);
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
-    }
-
-    @Test
-    public void authFormWithTotp() {
-        realm.addRequiredCredential(CredentialRepresentation.TOTP);
-        
-        String totpSecret = UUID.randomUUID().toString();
-
-        UserCredentialModel credential = new UserCredentialModel();
-        credential.setType(CredentialRepresentation.TOTP);
-        credential.setValue(totpSecret);
-
-        realm.updateCredential(user, credential);
-
-        user.setTotp(true);
-
-        String token = otp.generate(totpSecret);
-
-        formData.add(CredentialRepresentation.TOTP, token);
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
-    }
-
-    @Test
-    public void authFormWithTotpInvalidPassword() {
-        authFormWithTotp();
-
-        formData.remove(CredentialRepresentation.PASSWORD);
-        formData.add(CredentialRepresentation.PASSWORD, "invalid");
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
-    }
-
-    @Test
-    public void authFormWithTotpInvalidTotp() {
-        authFormWithTotp();
-
-        formData.remove(CredentialRepresentation.TOTP);
-        formData.add(CredentialRepresentation.TOTP, "invalid");
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
-    }
-
-    @Test
-    public void authFormWithTotpMissingTotp() {
-        authFormWithTotp();
-
-        formData.remove(CredentialRepresentation.TOTP);
-
-        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
-        Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
-    }
-
-    @Before
-    public void before() throws Exception {
-        super.before();
-        realm = realmManager.createRealm("Test");
-        realm.setAccessCodeLifespan(100);
-        realm.setEnabled(true);
-        realm.setName("Test");
-        realm.setPrivateKeyPem("0234234");
-        realm.setPublicKeyPem("0234234");
-        realm.setAccessTokenLifespan(1000);
-        realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
-
-        am = new AuthenticationManager();
-
-        user = realm.addUser("test");
-        user.setEnabled(true);
-
-        UserCredentialModel credential = new UserCredentialModel();
-        credential.setType(CredentialRepresentation.PASSWORD);
-        credential.setValue("password");
-
-        realm.updateCredential(user, credential);
-
-        formData = new MultivaluedHashMap<String, String>();
-        formData.add(CredentialRepresentation.PASSWORD, "password");
-
-        otp = new TimeBasedOTP();
-    }
-
-}
+package org.keycloak.model.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.models.utils.TimeBasedOTP;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.UUID;
+
+public class AuthenticationManagerTest extends AbstractModelTest {
+
+    private AuthenticationManager am;
+    private MultivaluedMap<String, String> formData;
+    private TimeBasedOTP otp;
+    private RealmModel realm;
+    private UserModel user;
+
+    @Test
+    public void authForm() {
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
+    }
+
+    @Test
+    public void authFormInvalidPassword() {
+        formData.remove(CredentialRepresentation.PASSWORD);
+        formData.add(CredentialRepresentation.PASSWORD, "invalid");
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
+    }
+
+    @Test
+    public void authFormMissingPassword() {
+        formData.remove(CredentialRepresentation.PASSWORD);
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
+    }
+
+    @Test
+    public void authFormRequiredAction() {
+        realm.addRequiredCredential(CredentialRepresentation.TOTP);
+        user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
+        
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
+    }
+
+    @Test
+    public void authFormUserDisabled() {
+        user.setEnabled(false);
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
+    }
+
+    @Test
+    public void authFormWithTotp() {
+        realm.addRequiredCredential(CredentialRepresentation.TOTP);
+        
+        String totpSecret = UUID.randomUUID().toString();
+
+        UserCredentialModel credential = new UserCredentialModel();
+        credential.setType(CredentialRepresentation.TOTP);
+        credential.setValue(totpSecret);
+
+        realm.updateCredential(user, credential);
+
+        user.setTotp(true);
+
+        String token = otp.generate(totpSecret);
+
+        formData.add(CredentialRepresentation.TOTP, token);
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
+    }
+
+    @Test
+    public void authFormWithTotpInvalidPassword() {
+        authFormWithTotp();
+
+        formData.remove(CredentialRepresentation.PASSWORD);
+        formData.add(CredentialRepresentation.PASSWORD, "invalid");
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
+    }
+
+    @Test
+    public void authFormWithTotpInvalidTotp() {
+        authFormWithTotp();
+
+        formData.remove(CredentialRepresentation.TOTP);
+        formData.add(CredentialRepresentation.TOTP, "invalid");
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
+    }
+
+    @Test
+    public void authFormWithTotpMissingTotp() {
+        authFormWithTotp();
+
+        formData.remove(CredentialRepresentation.TOTP);
+
+        AuthenticationStatus status = am.authenticateForm(realm, user, formData);
+        Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
+    }
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        realm = realmManager.createRealm("Test");
+        realm.setAccessCodeLifespan(100);
+        realm.setEnabled(true);
+        realm.setName("Test");
+        realm.setPrivateKeyPem("0234234");
+        realm.setPublicKeyPem("0234234");
+        realm.setAccessTokenLifespan(1000);
+        realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
+
+        am = new AuthenticationManager();
+
+        user = realm.addUser("test");
+        user.setEnabled(true);
+
+        UserCredentialModel credential = new UserCredentialModel();
+        credential.setType(CredentialRepresentation.PASSWORD);
+        credential.setValue("password");
+
+        realm.updateCredential(user, credential);
+
+        formData = new MultivaluedHashMap<String, String>();
+        formData.add(CredentialRepresentation.PASSWORD, "password");
+
+        otp = new TimeBasedOTP();
+    }
+
+}
diff --git a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
index 2472ed0..61d5621 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
@@ -1,113 +1,113 @@
-package org.keycloak.model.test;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.RealmManager;
-
-/**
- * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
- */
-public class CompositeRolesModelTest extends AbstractModelTest {
-
-    @Before
-    public void before() throws Exception {
-        super.before();
-        RealmManager manager = realmManager;
-        RealmRepresentation rep = AbstractModelTest.loadJson("testcomposites.json");
-        RealmModel realm = manager.createRealm("Test", rep.getRealm());
-        manager.importRealm(rep, realm);
-    }
-
-    @Test
-    public void testComposites() {
-        Set<RoleModel> requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER");
-        Assert.assertEquals(2, requestedRoles.size());
-        assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
-        assertContains("realm", "REALM_ROLE_1", requestedRoles);
-
-        requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER");
-        Assert.assertEquals(1, requestedRoles.size());
-        assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
-
-        requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
-        Assert.assertEquals(1, requestedRoles.size());
-        assertContains("realm", "REALM_COMPOSITE_1", requestedRoles);
-
-        requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
-        Assert.assertEquals(1, requestedRoles.size());
-        assertContains("realm", "REALM_ROLE_1", requestedRoles);
-
-        requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER");
-        Assert.assertEquals(1, requestedRoles.size());
-        assertContains("realm", "REALM_ROLE_1", requestedRoles);
-    }
-
-    // Same algorithm as in TokenManager.createAccessCode
-    private Set<RoleModel> getRequestedRoles(String applicationName, String username) {
-        Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
-
-        RealmModel realm = realmManager.getRealm("Test");
-        UserModel user = realm.getUser(username);
-        ApplicationModel application = realm.getApplicationByName(applicationName);
-
-        Set<RoleModel> roleMappings = realm.getRoleMappings(user);
-        Set<RoleModel> scopeMappings = realm.getScopeMappings(application);
-        Set<RoleModel> appRoles = application.getRoles();
-        if (appRoles != null) scopeMappings.addAll(appRoles);
-
-        for (RoleModel role : roleMappings) {
-            if (role.getContainer().equals(application)) requestedRoles.add(role);
-            for (RoleModel desiredRole : scopeMappings) {
-                Set<RoleModel> visited = new HashSet<RoleModel>();
-                applyScope(role, desiredRole, visited, requestedRoles);
-            }
-        }
-
-        return requestedRoles;
-    }
-
-    private static void applyScope(RoleModel role, RoleModel scope, Set<RoleModel> visited, Set<RoleModel> requested) {
-        if (visited.contains(scope)) return;
-        visited.add(scope);
-        if (role.hasRole(scope)) {
-            requested.add(scope);
-            return;
-        }
-        if (!scope.isComposite()) return;
-
-        for (RoleModel contained : scope.getComposites()) {
-            applyScope(role, contained, visited, requested);
-        }
-    }
-
-    private RoleModel getRole(String appName, String roleName) {
-        RealmModel realm = realmManager.getRealm("Test");
-        if ("realm".equals(appName)) {
-            return realm.getRole(roleName);
-        }  else {
-            return realm.getApplicationByName(appName).getRole(roleName);
-        }
-    }
-
-    private void assertContains(String appName, String roleName, Set<RoleModel> requestedRoles) {
-        RoleModel expectedRole = getRole(appName, roleName);
-
-        Assert.assertTrue(requestedRoles.contains(expectedRole));
-
-        // Check if requestedRole has correct role container
-        for (RoleModel role : requestedRoles) {
-            if (role.equals(expectedRole)) {
-                Assert.assertEquals(role.getContainer(), expectedRole.getContainer());
-            }
-        }
-    }
-}
+package org.keycloak.model.test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.RealmManager;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class CompositeRolesModelTest extends AbstractModelTest {
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        RealmManager manager = realmManager;
+        RealmRepresentation rep = AbstractModelTest.loadJson("testcomposites.json");
+        RealmModel realm = manager.createRealm("Test", rep.getRealm());
+        manager.importRealm(rep, realm);
+    }
+
+    @Test
+    public void testComposites() {
+        Set<RoleModel> requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER");
+        Assert.assertEquals(2, requestedRoles.size());
+        assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
+        assertContains("realm", "REALM_ROLE_1", requestedRoles);
+
+        requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER");
+        Assert.assertEquals(1, requestedRoles.size());
+        assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
+
+        requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
+        Assert.assertEquals(1, requestedRoles.size());
+        assertContains("realm", "REALM_COMPOSITE_1", requestedRoles);
+
+        requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
+        Assert.assertEquals(1, requestedRoles.size());
+        assertContains("realm", "REALM_ROLE_1", requestedRoles);
+
+        requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER");
+        Assert.assertEquals(1, requestedRoles.size());
+        assertContains("realm", "REALM_ROLE_1", requestedRoles);
+    }
+
+    // Same algorithm as in TokenManager.createAccessCode
+    private Set<RoleModel> getRequestedRoles(String applicationName, String username) {
+        Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
+
+        RealmModel realm = realmManager.getRealm("Test");
+        UserModel user = realm.getUser(username);
+        ApplicationModel application = realm.getApplicationByName(applicationName);
+
+        Set<RoleModel> roleMappings = realm.getRoleMappings(user);
+        Set<RoleModel> scopeMappings = realm.getScopeMappings(application);
+        Set<RoleModel> appRoles = application.getRoles();
+        if (appRoles != null) scopeMappings.addAll(appRoles);
+
+        for (RoleModel role : roleMappings) {
+            if (role.getContainer().equals(application)) requestedRoles.add(role);
+            for (RoleModel desiredRole : scopeMappings) {
+                Set<RoleModel> visited = new HashSet<RoleModel>();
+                applyScope(role, desiredRole, visited, requestedRoles);
+            }
+        }
+
+        return requestedRoles;
+    }
+
+    private static void applyScope(RoleModel role, RoleModel scope, Set<RoleModel> visited, Set<RoleModel> requested) {
+        if (visited.contains(scope)) return;
+        visited.add(scope);
+        if (role.hasRole(scope)) {
+            requested.add(scope);
+            return;
+        }
+        if (!scope.isComposite()) return;
+
+        for (RoleModel contained : scope.getComposites()) {
+            applyScope(role, contained, visited, requested);
+        }
+    }
+
+    private RoleModel getRole(String appName, String roleName) {
+        RealmModel realm = realmManager.getRealm("Test");
+        if ("realm".equals(appName)) {
+            return realm.getRole(roleName);
+        }  else {
+            return realm.getApplicationByName(appName).getRole(roleName);
+        }
+    }
+
+    private void assertContains(String appName, String roleName, Set<RoleModel> requestedRoles) {
+        RoleModel expectedRole = getRole(appName, roleName);
+
+        Assert.assertTrue(requestedRoles.contains(expectedRole));
+
+        // Check if requestedRole has correct role container
+        for (RoleModel role : requestedRoles) {
+            if (role.equals(expectedRole)) {
+                Assert.assertEquals(role.getContainer(), expectedRole.getContainer());
+            }
+        }
+    }
+}
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
index b15e888..c2bafc4 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
@@ -1,78 +1,78 @@
-package org.keycloak.model.test;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.keycloak.models.PasswordPolicy;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-public class ModelTest extends AbstractModelTest {
-
-    @Test
-    public void importExportRealm() {
-        RealmModel realm = realmManager.createRealm("original");
-        realm.setRegistrationAllowed(true);
-        realm.setResetPasswordAllowed(true);
-        realm.setSocial(true);
-        realm.setSslNotRequired(true);
-        realm.setVerifyEmail(true);
-        realm.setAccessTokenLifespan(1000);
-        realm.setPasswordPolicy(new PasswordPolicy("length"));
-        realm.setAccessCodeLifespan(1001);
-        realm.setAccessCodeLifespanUserAction(1002);
-        realm.setPublicKeyPem("0234234");
-        realm.setPrivateKeyPem("1234234");
-        realm.addDefaultRole("default-role");
-
-        HashMap<String, String> smtp = new HashMap<String,String>();
-        smtp.put("from", "auto@keycloak");
-        smtp.put("hostname", "localhost");
-        realm.setSmtpConfig(smtp);
-
-        HashMap<String, String> social = new HashMap<String,String>();
-        social.put("google.key", "1234");
-        social.put("google.secret", "5678");
-        realm.setSocialConfig(social);
-
-        RealmModel persisted = realmManager.getRealm(realm.getId());
-        assertEquals(realm, persisted);
-
-        RealmModel copy = importExport(realm, "copy");
-        assertEquals(realm, copy);
-    }
-
-    public static void assertEquals(RealmModel expected, RealmModel actual) {
-        Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(),
-                actual.isUpdateProfileOnInitialSocialLogin());
-        Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
-        Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
-        Assert.assertEquals(expected.isSocial(), actual.isSocial());
-        Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired());
-        Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
-        Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());
-
-        Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan());
-        Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction());
-        Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem());
-        Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem());
-
-        Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
-
-        Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig());
-        Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig());
-    }
-
-    private RealmModel importExport(RealmModel src, String copyName) {
-        RealmRepresentation representation = ModelToRepresentation.toRepresentation(src);
-        RealmModel copy = realmManager.createRealm(copyName);
-        realmManager.importRealm(representation, copy);
-        return realmManager.getRealm(copy.getId());
-    }
-
-}
+package org.keycloak.model.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.ModelToRepresentation;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+public class ModelTest extends AbstractModelTest {
+
+    @Test
+    public void importExportRealm() {
+        RealmModel realm = realmManager.createRealm("original");
+        realm.setRegistrationAllowed(true);
+        realm.setResetPasswordAllowed(true);
+        realm.setSocial(true);
+        realm.setSslNotRequired(true);
+        realm.setVerifyEmail(true);
+        realm.setAccessTokenLifespan(1000);
+        realm.setPasswordPolicy(new PasswordPolicy("length"));
+        realm.setAccessCodeLifespan(1001);
+        realm.setAccessCodeLifespanUserAction(1002);
+        realm.setPublicKeyPem("0234234");
+        realm.setPrivateKeyPem("1234234");
+        realm.addDefaultRole("default-role");
+
+        HashMap<String, String> smtp = new HashMap<String,String>();
+        smtp.put("from", "auto@keycloak");
+        smtp.put("hostname", "localhost");
+        realm.setSmtpConfig(smtp);
+
+        HashMap<String, String> social = new HashMap<String,String>();
+        social.put("google.key", "1234");
+        social.put("google.secret", "5678");
+        realm.setSocialConfig(social);
+
+        RealmModel persisted = realmManager.getRealm(realm.getId());
+        assertEquals(realm, persisted);
+
+        RealmModel copy = importExport(realm, "copy");
+        assertEquals(realm, copy);
+    }
+
+    public static void assertEquals(RealmModel expected, RealmModel actual) {
+        Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(),
+                actual.isUpdateProfileOnInitialSocialLogin());
+        Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
+        Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
+        Assert.assertEquals(expected.isSocial(), actual.isSocial());
+        Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired());
+        Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
+        Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());
+
+        Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan());
+        Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction());
+        Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem());
+        Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem());
+
+        Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
+
+        Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig());
+        Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig());
+    }
+
+    private RealmModel importExport(RealmModel src, String copyName) {
+        RealmRepresentation representation = ModelToRepresentation.toRepresentation(src);
+        RealmModel copy = realmManager.createRealm(copyName);
+        realmManager.importRealm(representation, copy);
+        return realmManager.getRealm(copy.getId());
+    }
+
+}
diff --git a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
old mode 100644
new mode 100755
index 25808e3..8b33c3f
--- a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java
@@ -75,20 +75,11 @@ public class MultipleRealmsTest extends AbstractModelTest {
         Assert.assertEquals(r2cl1.getId(), realm2.getOAuthClientById(r2cl1.getId()).getId());
 
         RoleModel r1App1Role = r1app1.getRole("app1Role1");
-        Assert.assertNull(realm1.getRoleById(r1App1Role.getId()));
-        Assert.assertNull(realm2.getRoleById(r1App1Role.getId()));
-        Assert.assertEquals(r1App1Role, r1app1.getRoleById(r1App1Role.getId()));
-        Assert.assertNull(r1app2.getRoleById(r1App1Role.getId()));
-        Assert.assertNull(r2app1.getRoleById(r1App1Role.getId()));
-        Assert.assertNull(r2app2.getRoleById(r1App1Role.getId()));
+        Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId()));
 
         RoleModel r2Role1 = realm2.getRole("role2");
         Assert.assertNull(realm1.getRoleById(r2Role1.getId()));
         Assert.assertEquals(r2Role1, realm2.getRoleById(r2Role1.getId()));
-        Assert.assertNull(r1app1.getRoleById(r2Role1.getId()));
-        Assert.assertNull(r1app2.getRoleById(r2Role1.getId()));
-        Assert.assertNull(r2app1.getRoleById(r2Role1.getId()));
-        Assert.assertNull(r2app2.getRoleById(r2Role1.getId()));
     }
 
     private void createObjects(RealmModel realm) {
diff --git a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
index 5bc94d2..132e39c 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
@@ -1,121 +1,121 @@
-package org.keycloak.model.test;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserModel.RequiredAction;
-
-/**
- * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
- */
-public class UserModelTest extends AbstractModelTest {
-
-    @Test
-    public void persistUser() {
-        RealmModel realm = realmManager.createRealm("original");
-        UserModel user = realm.addUser("user");
-        user.setFirstName("first-name");
-        user.setLastName("last-name");
-        user.setEmail("email");
-
-        user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
-        user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
-
-        UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user");
-
-        assertEquals(user, persisted);
-
-        UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId());
-        assertEquals(user, persisted2);
-    }
-    
-    @Test
-    public void webOriginSetTest() {
-        RealmModel realm = realmManager.createRealm("original");
-        ClientModel client = realm.addApplication("user");
-
-        Assert.assertTrue(client.getWebOrigins().isEmpty());
-
-        client.addWebOrigin("origin-1");
-        Assert.assertEquals(1, client.getWebOrigins().size());
-
-        client.addWebOrigin("origin-2");
-        Assert.assertEquals(2, client.getWebOrigins().size());
-
-        client.removeWebOrigin("origin-2");
-        Assert.assertEquals(1, client.getWebOrigins().size());
-
-        client.removeWebOrigin("origin-1");
-        Assert.assertTrue(client.getWebOrigins().isEmpty());
-
-        client = realm.addOAuthClient("oauthclient2");
-
-        Assert.assertTrue(client.getWebOrigins().isEmpty());
-
-        client.addWebOrigin("origin-1");
-        Assert.assertEquals(1, client.getWebOrigins().size());
-
-        client.addWebOrigin("origin-2");
-        Assert.assertEquals(2, client.getWebOrigins().size());
-
-        client.removeWebOrigin("origin-2");
-        Assert.assertEquals(1, client.getWebOrigins().size());
-
-        client.removeWebOrigin("origin-1");
-        Assert.assertTrue(client.getWebOrigins().isEmpty());
-
-    }
-
-    @Test
-    public void testUserRequiredActions() throws Exception {
-        RealmModel realm = realmManager.createRealm("original");
-        UserModel user = realm.addUser("user");
-
-        Assert.assertTrue(user.getRequiredActions().isEmpty());
-
-        user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
-        String id = realm.getId();
-        commit();
-        realm = realmManager.getRealm(id);
-        user = realm.getUser("user");
-
-        Assert.assertEquals(1, user.getRequiredActions().size());
-        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
-
-        user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
-        user = realm.getUser("user");
-
-        Assert.assertEquals(1, user.getRequiredActions().size());
-        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
-
-        user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
-        user = realm.getUser("user");
-
-        Assert.assertEquals(2, user.getRequiredActions().size());
-        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
-        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
-
-        user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
-        user = realm.getUser("user");
-
-        Assert.assertEquals(1, user.getRequiredActions().size());
-        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
-
-        user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
-        user = realm.getUser("user");
-
-        Assert.assertTrue(user.getRequiredActions().isEmpty());
-    }
-
-    public static void assertEquals(UserModel expected, UserModel actual) {
-        Assert.assertEquals(expected.getLoginName(), actual.getLoginName());
-        Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
-        Assert.assertEquals(expected.getLastName(), actual.getLastName());
-        Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray());
-    }
-
-}
-
+package org.keycloak.model.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserModel.RequiredAction;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class UserModelTest extends AbstractModelTest {
+
+    @Test
+    public void persistUser() {
+        RealmModel realm = realmManager.createRealm("original");
+        UserModel user = realm.addUser("user");
+        user.setFirstName("first-name");
+        user.setLastName("last-name");
+        user.setEmail("email");
+
+        user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
+        user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
+
+        UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user");
+
+        assertEquals(user, persisted);
+
+        UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId());
+        assertEquals(user, persisted2);
+    }
+    
+    @Test
+    public void webOriginSetTest() {
+        RealmModel realm = realmManager.createRealm("original");
+        ClientModel client = realm.addApplication("user");
+
+        Assert.assertTrue(client.getWebOrigins().isEmpty());
+
+        client.addWebOrigin("origin-1");
+        Assert.assertEquals(1, client.getWebOrigins().size());
+
+        client.addWebOrigin("origin-2");
+        Assert.assertEquals(2, client.getWebOrigins().size());
+
+        client.removeWebOrigin("origin-2");
+        Assert.assertEquals(1, client.getWebOrigins().size());
+
+        client.removeWebOrigin("origin-1");
+        Assert.assertTrue(client.getWebOrigins().isEmpty());
+
+        client = realm.addOAuthClient("oauthclient2");
+
+        Assert.assertTrue(client.getWebOrigins().isEmpty());
+
+        client.addWebOrigin("origin-1");
+        Assert.assertEquals(1, client.getWebOrigins().size());
+
+        client.addWebOrigin("origin-2");
+        Assert.assertEquals(2, client.getWebOrigins().size());
+
+        client.removeWebOrigin("origin-2");
+        Assert.assertEquals(1, client.getWebOrigins().size());
+
+        client.removeWebOrigin("origin-1");
+        Assert.assertTrue(client.getWebOrigins().isEmpty());
+
+    }
+
+    @Test
+    public void testUserRequiredActions() throws Exception {
+        RealmModel realm = realmManager.createRealm("original");
+        UserModel user = realm.addUser("user");
+
+        Assert.assertTrue(user.getRequiredActions().isEmpty());
+
+        user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
+        String id = realm.getId();
+        commit();
+        realm = realmManager.getRealm(id);
+        user = realm.getUser("user");
+
+        Assert.assertEquals(1, user.getRequiredActions().size());
+        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
+
+        user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
+        user = realm.getUser("user");
+
+        Assert.assertEquals(1, user.getRequiredActions().size());
+        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
+
+        user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
+        user = realm.getUser("user");
+
+        Assert.assertEquals(2, user.getRequiredActions().size());
+        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
+        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
+
+        user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
+        user = realm.getUser("user");
+
+        Assert.assertEquals(1, user.getRequiredActions().size());
+        Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
+
+        user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
+        user = realm.getUser("user");
+
+        Assert.assertTrue(user.getRequiredActions().isEmpty());
+    }
+
+    public static void assertEquals(UserModel expected, UserModel actual) {
+        Assert.assertEquals(expected.getLoginName(), actual.getLoginName());
+        Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
+        Assert.assertEquals(expected.getLastName(), actual.getLastName());
+        Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray());
+    }
+
+}
+
diff --git a/model/tests/src/test/resources/testcomposites.json b/model/tests/src/test/resources/testcomposites.json
index d035fd5..61038ea 100755
--- a/model/tests/src/test/resources/testcomposites.json
+++ b/model/tests/src/test/resources/testcomposites.json
@@ -1,206 +1,206 @@
-{
-    "id": "Test",
-    "realm": "Test",
-    "enabled": true,
-    "accessTokenLifespan": 600,
-    "accessCodeLifespan": 600,
-    "accessCodeLifespanUserAction": 600,
-    "sslNotRequired": true,
-    "registrationAllowed": true,
-    "resetPasswordAllowed": true,
-    "requiredCredentials": [ "password" ],
-    "smtpServer": {
-        "from": "auto@keycloak.org",
-        "host": "localhost",
-        "port":"3025"
-    },
-    "users" : [
-        {
-            "username" : "REALM_COMPOSITE_1_USER",
-            "enabled": true,
-            "email" : "test-user@localhost",
-            "credentials" : [
-                { "type" : "password",
-                    "value" : "password" }
-            ]
-        },
-        {
-            "username" : "REALM_ROLE_1_USER",
-            "enabled": true,
-            "email" : "test-user@localhost",
-            "credentials" : [
-                { "type" : "password",
-                    "value" : "password" }
-            ]
-        },
-        {
-            "username" : "REALM_APP_COMPOSITE_USER",
-            "enabled": true,
-            "email" : "test-user@localhost",
-            "credentials" : [
-                { "type" : "password",
-                    "value" : "password" }
-            ]
-        },
-        {
-            "username" : "REALM_APP_ROLE_USER",
-            "enabled": true,
-            "email" : "test-user@localhost",
-            "credentials" : [
-                { "type" : "password",
-                    "value" : "password" }
-            ]
-        },
-        {
-            "username" : "APP_COMPOSITE_USER",
-            "enabled": true,
-            "email" : "test-user@localhost",
-            "credentials" : [
-                { "type" : "password",
-                    "value" : "password" }
-            ]
-        }
-    ],
-    "oauthClients" : [
-        {
-            "name" : "third-party",
-            "enabled": true,
-            "secret": "password"
-        }
-    ],
-    "roleMappings": [
-        {
-            "username": "REALM_COMPOSITE_1_USER",
-            "roles": ["REALM_COMPOSITE_1"]
-        },
-        {
-            "username": "REALM_ROLE_1_USER",
-            "roles": ["REALM_ROLE_1"]
-        },
-        {
-            "username": "REALM_APP_COMPOSITE_USER",
-            "roles": ["REALM_APP_COMPOSITE_ROLE"]
-        },
-        {
-            "username": "APP_COMPOSITE_USER",
-            "roles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"]
-        }
-    ],
-    "scopeMappings": [
-        {
-            "client": "REALM_COMPOSITE_1_APPLICATION",
-            "roles": ["REALM_COMPOSITE_1"]
-        },
-        {
-            "client": "REALM_ROLE_1_APPLICATION",
-            "roles": ["REALM_ROLE_1"]
-        }
-    ],
-    "applications": [
-        {
-            "name": "REALM_COMPOSITE_1_APPLICATION",
-            "enabled": true,
-            "baseUrl": "http://localhost:8081/app",
-            "adminUrl": "http://localhost:8081/app/logout",
-            "secret": "password"
-         },
-        {
-            "name": "REALM_ROLE_1_APPLICATION",
-            "enabled": true,
-            "baseUrl": "http://localhost:8081/app",
-            "adminUrl": "http://localhost:8081/app/logout",
-            "secret": "password"
-        },
-        {
-            "name": "APP_ROLE_APPLICATION",
-            "enabled": true,
-            "baseUrl": "http://localhost:8081/app",
-            "adminUrl": "http://localhost:8081/app/logout",
-            "secret": "password"
-        },
-        {
-            "name": "APP_COMPOSITE_APPLICATION",
-            "enabled": true,
-            "baseUrl": "http://localhost:8081/app",
-            "adminUrl": "http://localhost:8081/app/logout",
-            "secret": "password"
-        }
-    ],
-    "roles" : {
-        "realm" : [
-            {
-                "name": "REALM_ROLE_1"
-            },
-            {
-                "name": "REALM_ROLE_2"
-            },
-            {
-                "name": "REALM_ROLE_3"
-            },
-            {
-                "name": "REALM_COMPOSITE_1",
-                "composites": {
-                    "realm": ["REALM_ROLE_1"]
-                }
-            },
-            {
-                "name": "REALM_APP_COMPOSITE_ROLE",
-                "composites": {
-                    "application": {
-                        "APP_ROLE_APPLICATION" :[
-                            "APP_ROLE_1"
-                        ]
-                    }
-                }
-            }
-        ],
-        "application" : {
-            "APP_ROLE_APPLICATION" : [
-                {
-                    "name": "APP_ROLE_1"
-                },
-                {
-                    "name": "APP_ROLE_2"
-                }
-            ],
-            "APP_COMPOSITE_APPLICATION" : [
-                {
-                    "name": "APP_COMPOSITE_ROLE",
-                    "composites": {
-                        "realm" : [
-                            "REALM_ROLE_1",
-                            "REALM_ROLE_2",
-                            "REALM_ROLE_3"
-                        ],
-                        "application": {
-                            "APP_ROLE_APPLICATION" :[
-                                "APP_ROLE_1"
-                            ]
-                        }
-                    }
-                },
-                {
-                    "name": "APP_ROLE_2"
-                }
-            ]
-        }
-
-    },
-
-    "applicationRoleMappings": {
-        "APP_ROLE_APPLICATION": [
-            {
-                "username": "REALM_APP_ROLE_USER",
-                "roles": ["APP_ROLE_2"]
-            }
-        ]
-    },
-    "applicationScopeMappings": {
-        "APP_ROLE_APPLICATION": [
-            {
-                "client": "APP_COMPOSITE_APPLICATION",
-                "roles": ["APP_ROLE_2"]
-            }
-        ]
-    }
+{
+    "id": "Test",
+    "realm": "Test",
+    "enabled": true,
+    "accessTokenLifespan": 600,
+    "accessCodeLifespan": 600,
+    "accessCodeLifespanUserAction": 600,
+    "sslNotRequired": true,
+    "registrationAllowed": true,
+    "resetPasswordAllowed": true,
+    "requiredCredentials": [ "password" ],
+    "smtpServer": {
+        "from": "auto@keycloak.org",
+        "host": "localhost",
+        "port":"3025"
+    },
+    "users" : [
+        {
+            "username" : "REALM_COMPOSITE_1_USER",
+            "enabled": true,
+            "email" : "test-user@localhost",
+            "credentials" : [
+                { "type" : "password",
+                    "value" : "password" }
+            ]
+        },
+        {
+            "username" : "REALM_ROLE_1_USER",
+            "enabled": true,
+            "email" : "test-user@localhost",
+            "credentials" : [
+                { "type" : "password",
+                    "value" : "password" }
+            ]
+        },
+        {
+            "username" : "REALM_APP_COMPOSITE_USER",
+            "enabled": true,
+            "email" : "test-user@localhost",
+            "credentials" : [
+                { "type" : "password",
+                    "value" : "password" }
+            ]
+        },
+        {
+            "username" : "REALM_APP_ROLE_USER",
+            "enabled": true,
+            "email" : "test-user@localhost",
+            "credentials" : [
+                { "type" : "password",
+                    "value" : "password" }
+            ]
+        },
+        {
+            "username" : "APP_COMPOSITE_USER",
+            "enabled": true,
+            "email" : "test-user@localhost",
+            "credentials" : [
+                { "type" : "password",
+                    "value" : "password" }
+            ]
+        }
+    ],
+    "oauthClients" : [
+        {
+            "name" : "third-party",
+            "enabled": true,
+            "secret": "password"
+        }
+    ],
+    "roleMappings": [
+        {
+            "username": "REALM_COMPOSITE_1_USER",
+            "roles": ["REALM_COMPOSITE_1"]
+        },
+        {
+            "username": "REALM_ROLE_1_USER",
+            "roles": ["REALM_ROLE_1"]
+        },
+        {
+            "username": "REALM_APP_COMPOSITE_USER",
+            "roles": ["REALM_APP_COMPOSITE_ROLE"]
+        },
+        {
+            "username": "APP_COMPOSITE_USER",
+            "roles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"]
+        }
+    ],
+    "scopeMappings": [
+        {
+            "client": "REALM_COMPOSITE_1_APPLICATION",
+            "roles": ["REALM_COMPOSITE_1"]
+        },
+        {
+            "client": "REALM_ROLE_1_APPLICATION",
+            "roles": ["REALM_ROLE_1"]
+        }
+    ],
+    "applications": [
+        {
+            "name": "REALM_COMPOSITE_1_APPLICATION",
+            "enabled": true,
+            "baseUrl": "http://localhost:8081/app",
+            "adminUrl": "http://localhost:8081/app/logout",
+            "secret": "password"
+         },
+        {
+            "name": "REALM_ROLE_1_APPLICATION",
+            "enabled": true,
+            "baseUrl": "http://localhost:8081/app",
+            "adminUrl": "http://localhost:8081/app/logout",
+            "secret": "password"
+        },
+        {
+            "name": "APP_ROLE_APPLICATION",
+            "enabled": true,
+            "baseUrl": "http://localhost:8081/app",
+            "adminUrl": "http://localhost:8081/app/logout",
+            "secret": "password"
+        },
+        {
+            "name": "APP_COMPOSITE_APPLICATION",
+            "enabled": true,
+            "baseUrl": "http://localhost:8081/app",
+            "adminUrl": "http://localhost:8081/app/logout",
+            "secret": "password"
+        }
+    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "REALM_ROLE_1"
+            },
+            {
+                "name": "REALM_ROLE_2"
+            },
+            {
+                "name": "REALM_ROLE_3"
+            },
+            {
+                "name": "REALM_COMPOSITE_1",
+                "composites": {
+                    "realm": ["REALM_ROLE_1"]
+                }
+            },
+            {
+                "name": "REALM_APP_COMPOSITE_ROLE",
+                "composites": {
+                    "application": {
+                        "APP_ROLE_APPLICATION" :[
+                            "APP_ROLE_1"
+                        ]
+                    }
+                }
+            }
+        ],
+        "application" : {
+            "APP_ROLE_APPLICATION" : [
+                {
+                    "name": "APP_ROLE_1"
+                },
+                {
+                    "name": "APP_ROLE_2"
+                }
+            ],
+            "APP_COMPOSITE_APPLICATION" : [
+                {
+                    "name": "APP_COMPOSITE_ROLE",
+                    "composites": {
+                        "realm" : [
+                            "REALM_ROLE_1",
+                            "REALM_ROLE_2",
+                            "REALM_ROLE_3"
+                        ],
+                        "application": {
+                            "APP_ROLE_APPLICATION" :[
+                                "APP_ROLE_1"
+                            ]
+                        }
+                    }
+                },
+                {
+                    "name": "APP_ROLE_2"
+                }
+            ]
+        }
+
+    },
+
+    "applicationRoleMappings": {
+        "APP_ROLE_APPLICATION": [
+            {
+                "username": "REALM_APP_ROLE_USER",
+                "roles": ["APP_ROLE_2"]
+            }
+        ]
+    },
+    "applicationScopeMappings": {
+        "APP_ROLE_APPLICATION": [
+            {
+                "client": "APP_COMPOSITE_APPLICATION",
+                "roles": ["APP_ROLE_2"]
+            }
+        ]
+    }
 }
\ No newline at end of file
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
index f5b7cb0..501a725 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
@@ -1,6 +1,7 @@
 package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.logging.Logger;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.OAuthClientModel;
@@ -28,6 +29,7 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class RoleByIdResource extends RoleResource {
+    protected static final Logger logger = Logger.getLogger(RoleByIdResource.class);
     private final RealmModel realm;
     private final RealmAuth auth;
 
@@ -101,6 +103,8 @@ public class RoleByIdResource extends RoleResource {
     @NoCache
     @Produces("application/json")
     public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
+
+        logger.info("*** getRoleComposites: '" + id + "'");
         RoleModel role = getRoleModel(id);
         auth.requireView();
         return getRoleComposites(role);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index 94d95af..5eb952f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -28,7 +28,7 @@ public abstract class RoleResource {
     }
 
     protected void deleteRole(RoleModel role) {
-        if (!role.getContainer().removeRoleById(role.getId())) {
+        if (!role.getContainer().removeRole(role)) {
             throw new NotFoundException();
         }
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
index c6f9b03..6e7dbe4 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
@@ -173,7 +173,7 @@ public class ScopeMappedResource {
         }
 
         for (RoleRepresentation role : roles) {
-            RoleModel roleModel = app.getRoleById(role.getId());
+            RoleModel roleModel = app.getRole(role.getName());
             if (roleModel == null) {
                 throw new NotFoundException();
             }
@@ -202,7 +202,7 @@ public class ScopeMappedResource {
 
         } else {
             for (RoleRepresentation role : roles) {
-                RoleModel roleModel = app.getRoleById(role.getId());
+                RoleModel roleModel = app.getRole(role.getName());
                 if (roleModel == null) {
                     throw new NotFoundException();
                 }
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 6b07988..29b7374 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
@@ -281,8 +281,8 @@ public class UsersResource {
         }
 
         for (RoleRepresentation role : roles) {
-            RoleModel roleModel = realm.getRoleById(role.getId());
-            if (roleModel == null) {
+            RoleModel roleModel = realm.getRole(role.getName());
+            if (roleModel == null || !roleModel.getId().equals(role.getId())) {
                 throw new NotFoundException();
             }
             realm.grantRole(user, roleModel);
@@ -311,8 +311,8 @@ public class UsersResource {
 
         } else {
             for (RoleRepresentation role : roles) {
-                RoleModel roleModel = realm.getRoleById(role.getId());
-                if (roleModel == null) {
+                RoleModel roleModel = realm.getRole(role.getName());
+                if (roleModel == null || !roleModel.getId().equals(role.getId())) {
                     throw new NotFoundException();
                 }
                 realm.deleteRoleMapping(user, roleModel);
@@ -368,8 +368,8 @@ public class UsersResource {
         }
 
         for (RoleRepresentation role : roles) {
-            RoleModel roleModel = application.getRoleById(role.getId());
-            if (roleModel == null) {
+            RoleModel roleModel = application.getRole(role.getName());
+            if (roleModel == null || !roleModel.getId().equals(role.getId())) {
                 throw new NotFoundException();
             }
             realm.grantRole(user, roleModel);
@@ -406,8 +406,8 @@ public class UsersResource {
 
         } else {
             for (RoleRepresentation role : roles) {
-                RoleModel roleModel = application.getRoleById(role.getId());
-                if (roleModel == null) {
+                RoleModel roleModel = application.getRole(role.getName());
+                if (roleModel == null || !roleModel.getId().equals(role.getId())) {
                     throw new NotFoundException();
                 }
                 realm.deleteRoleMapping(user, roleModel);