keycloak-uncached

Changes

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

integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/OAuthAuthenticationServerValve.java 879(+0 -879)

model/pom.xml 2(+1 -1)

pom.xml 4(+2 -2)

services/pom.xml 6(+6 -0)

Details

diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/index.html b/admin-ui/src/main/resources/META-INF/resources/admin/index.html
index 9487218..4be31ec 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/index.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/index.html
@@ -73,8 +73,10 @@
         </button>
     </div>
 
-    <div id="loading">
-        <i class="icon-spinner icon-spin"></i> Loading...
+    <div id="loading" class="loading-backdrop">
+        <div class="loading">
+            <span>Loading...</span>
+        </div>
     </div>
 </div>
 
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 7025d2e..07579f7 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
@@ -11,6 +11,9 @@ module.config([ '$routeProvider', function($routeProvider) {
             resolve : {
                 realm : function(RealmLoader) {
                     return {};
+                },
+                roles : function() {
+                    return {};
                 }
             },
             controller : 'RealmDetailCtrl'
@@ -20,6 +23,9 @@ module.config([ '$routeProvider', function($routeProvider) {
             resolve : {
                 realm : function(RealmLoader) {
                     return RealmLoader();
+                },
+                roles : function(RoleListLoader) {
+                    return RoleListLoader();
                 }
             },
             controller : 'RealmDetailCtrl'
@@ -240,6 +246,9 @@ module.config([ '$routeProvider', function($routeProvider) {
                 },
                 application : function() {
                     return {};
+                },
+                roles : function() {
+                    return {};
                 }
             },
             controller : 'ApplicationDetailCtrl'
@@ -255,6 +264,9 @@ module.config([ '$routeProvider', function($routeProvider) {
                 },
                 application : function(ApplicationLoader) {
                     return ApplicationLoader();
+                },
+                roles : function(ApplicationRoleListLoader) {
+                    return ApplicationRoleListLoader();
                 }
             },
             controller : 'ApplicationDetailCtrl'
@@ -368,10 +380,42 @@ module.directive('collapsed', function() {
     }
 });
 
-
-
-
-
+/**
+ * Directive for presenting an ON-OFF switch for checkbox.
+ * Usage: <input ng-model="mmm" name="nnn" id="iii" onoffswitch [on-text="ooo" off-text="fff"] />
+ */
+module.directive('onoffswitch', function() {
+    return {
+        restrict: "EA",
+        require: 'ngModel',
+        replace: true,
+        scope: {
+            ngModel: '=',
+            ngBind: '=',
+            name: '=',
+            id: '=',
+            onText: '@onText',
+            offText: '@offText'
+        },
+        compile: function(element, attrs) {
+            if (!attrs.onText) { attrs.onText = "ON"; }
+            if (!attrs.offText) { attrs.offText = "OFF"; }
+
+            var html = "<div class=\"onoffswitch\">" +
+                "<input type=\"checkbox\" data-ng-model=\"ngModel\" class=\"onoffswitch-checkbox\" name=\"" + attrs.name + "\" id=\"" + attrs.id + "\">" +
+                "<label for=\"" + attrs.id + "\" class=\"onoffswitch-label\">" +
+                "<span class=\"onoffswitch-inner\">" +
+                "<span class=\"onoffswitch-active\">{{onText}}</span>" +
+                "<span class=\"onoffswitch-inactive\">{{offText}}</span>" +
+                "</span>" +
+                "<span class=\"onoffswitch-switch\"></span>" +
+                "</label>" +
+                "</div>";
+
+            element.replaceWith($(html));
+        }
+    }
+});
 
 
 module.directive('kcInput', function() {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js
index a154da3..d5908aa 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers.js
@@ -21,3 +21,16 @@ function randomString(len) {
     return randomString;
 }
 
+function getAvailableRoles(roles, systemRoles){
+    var complement = [];
+
+    for (var i = 0; i < roles.length; i++){
+        var roleName = roles[i].name;
+
+        if (systemRoles.indexOf(roleName) < 0){
+            complement.push(roleName);
+        }
+    }
+
+    return complement;
+}
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 cc28637..7b74454 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
@@ -171,7 +171,7 @@ module.controller('ApplicationListCtrl', function($scope, realm, applications, A
     });
 });
 
-module.controller('ApplicationDetailCtrl', function($scope, realm, application, Application, $location, Dialog, Notifications) {
+module.controller('ApplicationDetailCtrl', function($scope, realm, application, roles, Application, $location, Dialog, Notifications) {
     console.log('ApplicationDetailCtrl');
 
     $scope.realm = realm;
@@ -182,6 +182,17 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, 
         $scope.application = {};
     }
 
+    console.log(application);
+
+    var systemRoles = ["*", "KEYCLOAK_APPLICATION","KEYCLOAK_IDENTITY_REQUESTER"];
+    var availableRoles = getAvailableRoles(roles, systemRoles);
+
+    $scope.appDefaultRolesOptions = {
+        'multiple' : true,
+        'simple_tags' : true,
+        'tags' : availableRoles
+    };
+
     $scope.$watch(function() {
         return $location.path();
     }, function() {
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 fa11a54..3f0e6c3 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
@@ -44,11 +44,20 @@ module.controller('RealmDropdownCtrl', function($scope, Realm, Current, Auth, $l
     }
 });
 
-module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $http, $location, Dialog, Notifications) {
+module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, roles, $http, $location, Dialog, Notifications) {
     $scope.createRealm = !realm.id;
 
     console.log('RealmDetailCtrl');
 
+    var systemRoles = ["*", "KEYCLOAK_APPLICATION","KEYCLOAK_IDENTITY_REQUESTER"];
+    var availableRoles = getAvailableRoles(roles, systemRoles);
+
+    $scope.realmDefaultRolesOptions = {
+        'multiple' : true,
+        'simple_tags' : true,
+        'tags' : availableRoles
+    };
+
     if ($scope.createRealm) {
         $scope.realm = {
             enabled: true,
@@ -73,6 +82,8 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
         $scope.realm.requireSsl = !realm.sslNotRequired;
     }
 
+    $scope.social = $scope.realm.social;
+
     var oldCopy = angular.copy($scope.realm);
 
 
@@ -104,6 +115,7 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
                         }
                         $location.url("/realms/" + id);
                         Notifications.success("The realm has been created.");
+                        $scope.social = $scope.realm.social;
                     });
                 });
             } else {
@@ -122,6 +134,7 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
                     });
                     $location.url("/realms/" + id);
                     Notifications.success("Your changes have been saved to the realm.");
+                    $scope.social = $scope.realm.social;
                 });
             }
         } else {
@@ -207,8 +220,13 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
         $scope.realm["socialProviders"] = realm.socialProviders;
     }
 
-    // Hardcoded provider list
-    $scope.availableProviders = [ "google", "facebook", "twitter"];
+    // Hardcoded provider list in form of map providerId:providerName
+    $scope.allProviders = { google:"Google", facebook:"Facebook", twitter:"Twitter" };
+    $scope.availableProviders = [];
+
+    for (var provider in $scope.allProviders){
+        $scope.availableProviders.push(provider);
+    }
 
     var oldCopy = angular.copy($scope.realm);
     $scope.changed = false;
@@ -226,6 +244,9 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
 
     // Fill in configured providers
     var initSocial = function() {
+        // postSaveProviders is used for remembering providers which were already validated after pressing the save button
+        // thanks to this it's easy to distinguish between newly added fields and those already tried to be saved
+        $scope.postSaveProviders = [];
         $scope.unsetProviders = [];
         $scope.configuredProviders = [];
 
@@ -241,7 +262,7 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
 
         // If no providers are already configured, you can add any of them
         if ($scope.configuredProviders.length == 0){
-            $scope.unsetProviders = $scope.availableProviders;
+            $scope.unsetProviders = $scope.availableProviders.slice(0);
         } else {
             for (var i = 0; i < $scope.availableProviders.length; i++){
                 var providerId = $scope.availableProviders[i];
@@ -270,6 +291,13 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
         delete $scope.realm.socialProviders[pId+".key"];
         delete $scope.realm.socialProviders[pId+".secret"];
         $scope.configuredProviders.remove($scope.configuredProviders.indexOf(pId));
+
+        // Removing from postSaveProviders, so the empty fields are not red if the provider is added to the list again
+        var rId = $scope.postSaveProviders.indexOf(pId);
+        if (rId > -1){
+            $scope.postSaveProviders.remove(rId)
+        }
+
         $scope.unsetProviders.push(pId);
     };
 
@@ -280,8 +308,6 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
     }, true);
 
     $scope.save = function() {
-        $scope.saveClicked = true;
-
         if ($scope.realmForm.$valid) {
             var realmCopy = angular.copy($scope.realm);
             realmCopy.social = true;
@@ -289,10 +315,12 @@ module.controller('RealmSocialCtrl', function($scope, realm, Realm, $location, N
             Realm.update(realmCopy, function () {
                 $location.url("/realms/" + realm.id + "/social-settings");
                 Notifications.success("Saved changes to realm");
+                oldCopy = realmCopy;
             });
         } else {
             $scope.realmForm.showErrors = true;
             Notifications.error("Some required fields are missing values.");
+            $scope.postSaveProviders = $scope.configuredProviders.slice(0);
         }
     };
 
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 2c11b73..06e8b54 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
@@ -44,17 +44,7 @@
 
                         <div class="form-group clearfix block">
                             <label for="enabled" class="control-label">Enabled</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="application.enabled" class="onoffswitch-checkbox"
-                                       name="enabled" id="enabled">
-                                <label for="enabled" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="application.enabled" name="enabled" id="enabled" onoffswitch />
                         </div>
                         <div class="form-group">
                             <label for="baseUrl" class="control-label">Base URL</label>
@@ -103,6 +93,16 @@
                             </div>
                         </div>
                     </fieldset>
+                    <fieldset>
+                        <legend uncollapsed><span class="text">Default Roles</span></legend>
+                        <div class="form-group">
+                            <label for="default-roles" class="control-label two-lines">Default Application Roles</label>
+
+                            <div class="controls">
+                                <input id="default-roles" type="text" ui-select2="appDefaultRolesOptions" ng-model="application.defaultRoles" placeholder="Type a role and enter">
+                            </div>
+                        </div>
+                    </fieldset>
                     <div class="form-actions" data-ng-show="create">
                         <button type="submit" data-ng-click="save()" data-ng-show="changed" class="primary">Save
                         </button>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
index d35d8cd..b530a0c 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html
@@ -5,7 +5,7 @@
             <div class="top-nav" data-ng-hide="createRealm">
                 <ul class="rcue-tabs">
                     <li class="active"><a href="#/realms/{{realm.id}}">General</a></li>
-                    <li data-ng-show="realm.social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
+                    <li data-ng-show="social"><a href="#/realms/{{realm.id}}/social-settings">Social</a></li>
                     <li><a href="#/realms/{{realm.id}}/roles">Roles</a></li>
                     <li><a href="#/realms/{{realm.id}}/required-credentials">Credentials</a></li>
                     <li><a href="#/realms/{{realm.id}}/token-settings">Token</a></li>
@@ -34,112 +34,47 @@
                         </div>
                         <div class="form-group">
                             <label for="enabled" class="control-label">Enabled</label>
-
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.enabled" class="onoffswitch-checkbox"
-                                       name="enabled" id="enabled">
-                                <label for="enabled" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.enabled" name="enabled" id="enabled" onoffswitch />
                         </div>
                     </fieldset>
                     <fieldset>
                         <legend uncollapsed><span class="text">Login Options</span></legend>
                         <div class="form-group clearfix block">
                             <label for="social" class="control-label">Social login</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.social" class="onoffswitch-checkbox" name="social" id="social">
-                                <label for="social" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.social" name="social" id="social" onoffswitch />
                         </div>
                         <div class="form-group clearfix block">
                             <label for="registrationAllowed" class="control-label">User registration</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.registrationAllowed" class="onoffswitch-checkbox" name="registrationAllowed" id="registrationAllowed">
-                                <label for="registrationAllowed" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.registrationAllowed" name="registrationAllowed" id="registrationAllowed" onoffswitch />
                         </div>
                         <div class="form-group clearfix block">
                             <label for="resetPasswordAllowed" class="control-label">Reset password</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.resetPasswordAllowed" class="onoffswitch-checkbox" name="resetPasswordAllowed" id="resetPasswordAllowed">
-                                <label for="resetPasswordAllowed" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.resetPasswordAllowed" name="resetPasswordAllowed" id="resetPasswordAllowed" onoffswitch />
                         </div>
                         <div class="form-group clearfix block">
                             <label for="verifyEmail" class="control-label">Verify email</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.verifyEmail" class="onoffswitch-checkbox" name="verifyEmail" id="verifyEmail">
-                                <label for="verifyEmail" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch />
                         </div>
                         <div class="form-group clearfix block">
                             <label for="accountManagement" class="control-label two-lines">User account management</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.accountManagement" class="onoffswitch-checkbox"
-                                       name="accountManagement" id="accountManagement">
-                                <label for="accountManagement" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.accountManagement" name="accountManagement" id="accountManagement" onoffswitch />
                         </div>
                         <div class="form-group clearfix block">
                             <label for="requireSsl" class="control-label">Require SSL</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.requireSsl" class="onoffswitch-checkbox" name="requireSsl" id="requireSsl">
-                                <label for="requireSsl" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch />
                         </div>
                         <div class="form-group">
                             <label for="cookieLoginAllowed" class="control-label">Cookie login allowed</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.cookieLoginAllowed" class="onoffswitch-checkbox" name="cookieLoginAllowed" id="cookieLoginAllowed">
-                                <label for="cookieLoginAllowed" class="onoffswitch-label">
-                                            <span class="onoffswitch-inner">
-                                                <span class="onoffswitch-active">ON</span>
-                                                <span class="onoffswitch-inactive">OFF</span>
-                                            </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
+                            <input ng-model="realm.cookieLoginAllowed" name="cookieLoginAllowed" id="cookieLoginAllowed" onoffswitch />
+                        </div>
+                    </fieldset>
+                    <fieldset>
+                        <legend uncollapsed><span class="text">Default Roles</span></legend>
+                        <div class="form-group">
+                            <label for="default-roles" class="control-label two-lines">Default Realm Roles</label>
+
+                            <div class="controls">
+                                <input id="default-roles" type="text" ui-select2="realmDefaultRolesOptions" ng-model="realm.defaultRoles" placeholder="Type a role and enter">
                             </div>
                         </div>
                     </fieldset>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
index 16f7b78..87e0ed1 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html
@@ -1,5 +1,5 @@
 <ul data-ng-hide="createRealm">
-    <li data-ng-class="(!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' || path[2] == 'social-settings' || path[2] == 'required-credentials') && 'active'"><a href="#/realms/{{realm.id}}">Settings</a></li>
+    <li data-ng-class="(!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' || path[2] == 'social-settings' || path[2] == 'required-credentials' || path[2] == 'smtp-settings') && 'active'"><a href="#/realms/{{realm.id}}">Settings</a></li>
     <li data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.id}}/users">Users</a>
     </li>
     <li data-ng-class="(path[2] == 'applications' || path[1] == 'application') && 'active'"><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
index 6abd4ee..dd24ea7 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html
@@ -42,45 +42,18 @@
                         </div>
                         <div class="form-group clearfix">
                             <label for="smtpSSL" class="control-label">Enable SSL</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.smtpServer.ssl" class="onoffswitch-checkbox" name="smtpSSL" id="smtpSSL">
-                                <label for="smtpSSL" class="onoffswitch-label">
-                                        <span class="onoffswitch-inner">
-                                            <span class="onoffswitch-active">ON</span>
-                                            <span class="onoffswitch-inactive">OFF</span>
-                                        </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.smtpServer.ssl" name="smtpSSL" id="smtpSSL" onoffswitch />
                         </div>
                         <div class="form-group clearfix">
                             <label for="smtpStartTLS" class="control-label">Enable StartTLS</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.smtpServer.starttls" class="onoffswitch-checkbox" name="smtpStartTLS" id="smtpStartTLS">
-                                <label for="smtpStartTLS" class="onoffswitch-label">
-                                        <span class="onoffswitch-inner">
-                                            <span class="onoffswitch-active">ON</span>
-                                            <span class="onoffswitch-inactive">OFF</span>
-                                        </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.smtpServer.starttls" name="smtpStartTLS" id="smtpStartTLS" onoffswitch />
                         </div>
                     </fieldset>
                     <fieldset>
                         <legend collapsed><span class="text">Authentication</span></legend>
                         <div class="form-group clearfix">
                             <label for="smtpAuth" class="control-label">Enabled</label>
-                            <div class="onoffswitch">
-                                <input type="checkbox" data-ng-model="realm.smtpServer.auth" class="onoffswitch-checkbox" name="smtpAuth" id="smtpAuth">
-                                <label for="smtpAuth" class="onoffswitch-label">
-                                        <span class="onoffswitch-inner">
-                                            <span class="onoffswitch-active">ON</span>
-                                            <span class="onoffswitch-inactive">OFF</span>
-                                        </span>
-                                    <span class="onoffswitch-switch"></span>
-                                </label>
-                            </div>
+                            <input ng-model="realm.smtpServer.auth" name="smtpAuth" id="smtpAuth" onoffswitch />
                         </div>
                         <div class="form-group clearfix">
                             <label for="smtpUsername" class="control-label">Username <span class="required" ng-show="realm.smtpServer.auth">*</span></label>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
index a046cc5..b0ef465 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html
@@ -30,7 +30,8 @@
                                         <div class="actions">
                                             <div class="select-rcue">
                                                 <select ng-model="newProviderId"
-                                                        ng-options="p for p in unsetProviders"></select>
+                                                        ng-options="p as allProviders[p] for p in unsetProviders"
+                                                        placeholder="Please select"></select>
                                             </div>
                                             <div>
                                                 <button ng-click="addProvider()" ng-disabled="">Add Provider</button>
@@ -49,16 +50,16 @@
                                 <tr ng-repeat="pId in configuredProviders">
                                     <td>
                                         <div class="clearfix">
-                                            <input class="input-small disabled" type="text" placeholder="Key" value="{{pId}}" readonly>
+                                            <input class="input-small disabled" type="text" value="{{allProviders[pId]}}" readonly>
                                         </div>
                                     </td>
                                     <td>
                                         <input class="input-small" type="text" placeholder="Key" ng-model="realm.socialProviders[pId+'.key']"
-                                               ng-class="{'dirty': saveClicked}" required>
+                                               ng-class="{'dirty': postSaveProviders.indexOf(pId) > -1}" required>
                                     </td>
                                     <td>
                                         <input class="input-small" type="text" placeholder="Secret" ng-model="realm.socialProviders[pId+'.secret']"
-                                               ng-class="{'dirty': saveClicked}" required>
+                                               ng-class="{'dirty': postSaveProviders.indexOf(pId) > -1}" required>
                                     </td>
                                     <td>
                                         <div class="action-div"><i class="icon-question" ng-click="openHelp(pId)"></i></div>
diff --git a/admin-ui/src/main/resources/META-INF/web-fragment.xml b/admin-ui/src/main/resources/META-INF/web-fragment.xml
index af5af31..cf5933b 100755
--- a/admin-ui/src/main/resources/META-INF/web-fragment.xml
+++ b/admin-ui/src/main/resources/META-INF/web-fragment.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <web-fragment version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
-	xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd ">
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd ">
 </web-fragment>
diff --git a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css
index 6b3ca67..1cea3b5 100644
--- a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css
+++ b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.css
@@ -55,9 +55,19 @@ body {
   color: #fff;
   font-weight: bold;
 }
+.loading-backdrop {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1031;
+  background-color: #FFFFFF;
+  opacity: 0.75;
+}
 .loading {
   position: fixed;
-  z-index: 1000;
+  z-index: 1032;
   top: 50%;
   left: 50%;
   width: 6em;
@@ -75,10 +85,14 @@ body {
   border-radius: 0.4em;
 }
 .loading span {
-  font-size: 1.1em;
+  background: url(img/loader.gif) no-repeat center top;
+  font-size: 1.2em;
   color: #666;
   display: inline-block;
   padding-top: 0.36363636363636em;
+  margin-top: -2.27272727272727em;
+  margin-left: -2.27272727272727em;
+  padding-top: 2.90909090909091em;
 }
 /* Header */
 .header.rcue {
diff --git a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less
index 0109fe5..d5bfdf2 100644
--- a/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less
+++ b/admin-ui-styles/src/main/resources/META-INF/resources/admin-ui/css/admin-console.less
@@ -74,9 +74,20 @@ body {
     }
 }
 
+.loading-backdrop {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1031;
+  background-color: #FFFFFF;
+  opacity: 0.75;
+}
+
 .loading {
     position: fixed;
-    z-index: 1000;
+    z-index: 1032;
     top: 50%;
     left: 50%;
     width: 6em;
@@ -93,12 +104,16 @@ body {
         padding: 0.3em;
         border-radius: 0.4em;
     }
-    
+
     span {
-        font-size: 1.1em;
+        background: url(img/loader.gif) no-repeat center top;
+        font-size: 1.2em;
         color: #666;
         display: inline-block;
         padding-top: 0.36363636363636em;
+        margin-top: -2.27272727272727em;
+        margin-left: -2.27272727272727em;
+        padding-top: 2.90909090909091em;
     }
 }
 
diff --git a/admin-ui-styles/src/main/resources/META-INF/web-fragment.xml b/admin-ui-styles/src/main/resources/META-INF/web-fragment.xml
index af5af31..cf5933b 100755
--- a/admin-ui-styles/src/main/resources/META-INF/web-fragment.xml
+++ b/admin-ui-styles/src/main/resources/META-INF/web-fragment.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <web-fragment version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
-	xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd ">
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd ">
 </web-fragment>
diff --git a/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java b/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
index 0fde587..c4b4f7b 100755
--- a/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
+++ b/core/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
@@ -37,7 +37,8 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
                 .queryParam("state", state)
                 .build();
         NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
-        logger.info("NewCookie: " + cookie.toString());
+        logger.debug("NewCookie: " + cookie.toString());
+        logger.debug("Oauth Redirect to: " + url);
         return Response.status(302)
                 .location(url)
                 .cookie(cookie).build();
diff --git a/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java b/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
index 0a7f553..3b0a4e4 100755
--- a/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
+++ b/core/src/main/java/org/keycloak/representations/idm/admin/AdminAction.java
@@ -1,7 +1,6 @@
 package org.keycloak.representations.idm.admin;
 
 import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonProperty;
 
 /**
  * Posted to managed client from admin server.
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 65281dc..c520fd3 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -28,7 +28,7 @@ public class RealmRepresentation {
     protected String privateKey;
     protected String publicKey;
     protected List<RoleRepresentation> roles;
-    protected String[] defaultRoles;
+    protected List<String> defaultRoles;
     protected Set<String> requiredCredentials;
     protected Set<String> requiredApplicationCredentials;
     protected Set<String> requiredOAuthClientCredentials;
@@ -220,11 +220,11 @@ public class RealmRepresentation {
         this.roles = roles;
     }
 
-    public String[] getDefaultRoles() {
+    public List<String> getDefaultRoles() {
         return defaultRoles;
     }
 
-    public void setDefaultRoles(String[] defaultRoles) {
+    public void setDefaultRoles(List<String> defaultRoles) {
         this.defaultRoles = defaultRoles;
     }
 
diff --git a/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java b/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java
index 2b40251..601bbbe 100755
--- a/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java
+++ b/core/src/main/java/org/keycloak/representations/SkeletonKeyToken.java
@@ -4,7 +4,10 @@ import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.jboss.resteasy.jwt.JsonWebToken;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/core/src/test/java/org/keycloak/RSAVerifierTest.java b/core/src/test/java/org/keycloak/RSAVerifierTest.java
index 8841954..d169d37 100755
--- a/core/src/test/java/org/keycloak/RSAVerifierTest.java
+++ b/core/src/test/java/org/keycloak/RSAVerifierTest.java
@@ -6,13 +6,10 @@ import org.bouncycastle.openssl.PEMWriter;
 import org.bouncycastle.x509.X509V1CertificateGenerator;
 import org.jboss.resteasy.jose.jws.JWSBuilder;
 import org.jboss.resteasy.jwt.JsonSerialization;
-import org.keycloak.RSATokenVerifier;
-import org.keycloak.ResourceMetadata;
-import org.keycloak.VerificationException;
-import org.keycloak.representations.SkeletonKeyToken;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.keycloak.representations.SkeletonKeyToken;
 
 import javax.security.auth.x500.X500Principal;
 import java.io.IOException;
diff --git a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
index cf5e459..c9d2e0d 100755
--- a/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
+++ b/core/src/test/java/org/keycloak/SkeletonKeyTokenTest.java
@@ -5,9 +5,9 @@ import org.jboss.resteasy.jose.jws.JWSBuilder;
 import org.jboss.resteasy.jose.jws.JWSInput;
 import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
 import org.jboss.resteasy.jwt.JsonSerialization;
+import org.junit.Test;
 import org.keycloak.representations.SkeletonKeyScope;
 import org.keycloak.representations.SkeletonKeyToken;
-import org.junit.Test;
 
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
diff --git a/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp b/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
index 91657c9..54df669 100755
--- a/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
+++ b/examples/as7-eap-demo/customer-app/src/main/webapp/customers/view.jsp
@@ -1,4 +1,4 @@
-<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page import="javax.ws.rs.core.UriBuilder" language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
 <html>
 <head>
diff --git a/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp b/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
index fe8d990..bf1ca5a 100755
--- a/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
+++ b/examples/as7-eap-demo/product-app/src/main/webapp/products/view.jsp
@@ -1,4 +1,4 @@
-<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page import="javax.ws.rs.core.UriBuilder" language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
 <html>
 <head>
diff --git a/examples/as7-eap-demo/server/pom.xml b/examples/as7-eap-demo/server/pom.xml
index 3282368..6d21685 100755
--- a/examples/as7-eap-demo/server/pom.xml
+++ b/examples/as7-eap-demo/server/pom.xml
@@ -37,11 +37,6 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-model-picketlink</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
             <artifactId>keycloak-social-core</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -76,22 +71,6 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-idm-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-idm-impl</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-idm-simple-schema</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-config</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.jboss.resteasy</groupId>
             <artifactId>resteasy-jaxrs</artifactId>
             <scope>provided</scope>
diff --git a/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java b/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java
index b9bbc82..0b7b49d 100755
--- a/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java
+++ b/examples/as7-eap-demo/server/src/main/java/org/keycloak/example/demo/DemoApplication.java
@@ -1,11 +1,11 @@
 package org.keycloak.example.demo;
 
 import org.jboss.resteasy.jwt.JsonSerialization;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.ApplianceBootstrap;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
 import org.keycloak.services.resources.KeycloakApplication;
 
 import javax.servlet.ServletContext;
diff --git a/examples/as7-eap-demo/server/src/main/resources/META-INF/persistence.xml b/examples/as7-eap-demo/server/src/main/resources/META-INF/persistence.xml
index cb5a1c3..b949715 100755
--- a/examples/as7-eap-demo/server/src/main/resources/META-INF/persistence.xml
+++ b/examples/as7-eap-demo/server/src/main/resources/META-INF/persistence.xml
@@ -2,27 +2,25 @@
     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="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+    <persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
         <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
-        
-        <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>
+
+        <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</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.RealmScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.RoleEntity</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>
 
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
-        
+
         <properties>
             <property name="hibernate.hbm2ddl.auto" value="create-drop" />
             <property name="hibernate.show_sql" value="false" />
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/oauthGrantForm.jsp b/examples/as7-eap-demo/server/src/main/webapp/saas/oauthGrantForm.jsp
index 4bbd6df..d62b00e 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/oauthGrantForm.jsp
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/oauthGrantForm.jsp
@@ -1,5 +1,6 @@
-<%@ page import="org.keycloak.models.*,org.keycloak.services.resources.*,javax.ws.rs.core.*,java.util.*" language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page import="org.keycloak.models.RealmModel,org.keycloak.models.RoleModel,org.keycloak.models.UserModel,javax.ws.rs.core.MultivaluedMap" language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
+<%@ page import="java.util.List" %>
 <%
         RealmModel realm = (RealmModel)request.getAttribute(RealmModel.class.getName());
         String username = (String)request.getAttribute("username");
diff --git a/examples/as7-eap-dev/customer-app/src/main/webapp/customers/view.jsp b/examples/as7-eap-dev/customer-app/src/main/webapp/customers/view.jsp
index 91657c9..cc5925d 100755
--- a/examples/as7-eap-dev/customer-app/src/main/webapp/customers/view.jsp
+++ b/examples/as7-eap-dev/customer-app/src/main/webapp/customers/view.jsp
@@ -1,4 +1,4 @@
-<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
 <html>
 <head>
diff --git a/examples/as7-eap-dev/server/pom.xml b/examples/as7-eap-dev/server/pom.xml
index b568d69..4ccbd3e 100755
--- a/examples/as7-eap-dev/server/pom.xml
+++ b/examples/as7-eap-dev/server/pom.xml
@@ -37,11 +37,6 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-model-picketlink</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
             <artifactId>keycloak-social-core</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -66,22 +61,6 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-idm-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-idm-impl</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-idm-simple-schema</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-config</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.jboss.resteasy</groupId>
             <artifactId>resteasy-jaxrs</artifactId>
             <scope>provided</scope>
diff --git a/examples/as7-eap-dev/server/src/main/java/org/keycloak/example/demo/DemoApplication.java b/examples/as7-eap-dev/server/src/main/java/org/keycloak/example/demo/DemoApplication.java
index 2f512e2..856f355 100755
--- a/examples/as7-eap-dev/server/src/main/java/org/keycloak/example/demo/DemoApplication.java
+++ b/examples/as7-eap-dev/server/src/main/java/org/keycloak/example/demo/DemoApplication.java
@@ -1,11 +1,11 @@
 package org.keycloak.example.demo;
 
 import org.jboss.resteasy.jwt.JsonSerialization;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.ApplianceBootstrap;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
 import org.keycloak.services.resources.KeycloakApplication;
 
 import javax.servlet.ServletContext;
diff --git a/examples/as7-eap-dev/server/src/main/resources/META-INF/persistence.xml b/examples/as7-eap-dev/server/src/main/resources/META-INF/persistence.xml
index cb5a1c3..23f0913 100755
--- a/examples/as7-eap-dev/server/src/main/resources/META-INF/persistence.xml
+++ b/examples/as7-eap-dev/server/src/main/resources/META-INF/persistence.xml
@@ -2,27 +2,25 @@
     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="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+    <persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
         <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
-        
-        <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>
+
+        <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</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.RealmScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.RoleEntity</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>
 
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
-        
+
         <properties>
             <property name="hibernate.hbm2ddl.auto" value="create-drop" />
             <property name="hibernate.show_sql" value="false" />
@@ -30,4 +28,5 @@
         </properties>
     </persistence-unit>
 
+
 </persistence>
diff --git a/examples/as7-eap-dev/server/src/main/webapp/saas/oauthGrantForm.jsp b/examples/as7-eap-dev/server/src/main/webapp/saas/oauthGrantForm.jsp
index 4bbd6df..d62b00e 100755
--- a/examples/as7-eap-dev/server/src/main/webapp/saas/oauthGrantForm.jsp
+++ b/examples/as7-eap-dev/server/src/main/webapp/saas/oauthGrantForm.jsp
@@ -1,5 +1,6 @@
-<%@ page import="org.keycloak.models.*,org.keycloak.services.resources.*,javax.ws.rs.core.*,java.util.*" language="java" contentType="text/html; charset=ISO-8859-1"
+<%@ page import="org.keycloak.models.RealmModel,org.keycloak.models.RoleModel,org.keycloak.models.UserModel,javax.ws.rs.core.MultivaluedMap" language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
+<%@ page import="java.util.List" %>
 <%
         RealmModel realm = (RealmModel)request.getAttribute(RealmModel.class.getName());
         String username = (String)request.getAttribute("username");

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

diff --git a/forms/pom.xml b/forms/pom.xml
index 0af1892..933b9ae 100755
--- a/forms/pom.xml
+++ b/forms/pom.xml
@@ -34,11 +34,6 @@
 			<version>${project.version}</version>
 		</dependency>
         <dependency>
-            <groupId>org.picketlink</groupId>
-            <artifactId>picketlink-common</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
             <groupId>org.jboss.resteasy</groupId>
             <artifactId>resteasy-jaxrs</artifactId>
             <scope>provided</scope>
diff --git a/forms/src/main/java/org/keycloak/forms/LoginBean.java b/forms/src/main/java/org/keycloak/forms/LoginBean.java
index 9174813..02fc10b 100755
--- a/forms/src/main/java/org/keycloak/forms/LoginBean.java
+++ b/forms/src/main/java/org/keycloak/forms/LoginBean.java
@@ -21,12 +21,11 @@
  */
 package org.keycloak.forms;
 
-import java.util.LinkedList;
-import java.util.List;
+import org.keycloak.forms.model.RequiredCredential;
 
 import javax.ws.rs.core.MultivaluedMap;
-
-import org.keycloak.forms.model.RequiredCredential;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/forms/src/main/java/org/keycloak/forms/OAuthGrantBean.java b/forms/src/main/java/org/keycloak/forms/OAuthGrantBean.java
old mode 100644
new mode 100755
index ce7bf04..560c37a
--- a/forms/src/main/java/org/keycloak/forms/OAuthGrantBean.java
+++ b/forms/src/main/java/org/keycloak/forms/OAuthGrantBean.java
@@ -21,14 +21,13 @@
  */
 package org.keycloak.forms;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.ws.rs.core.MultivaluedMap;
-
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
  */
diff --git a/forms/src/main/java/org/keycloak/forms/RegisterBean.java b/forms/src/main/java/org/keycloak/forms/RegisterBean.java
index cb8c83d..94bb83c 100755
--- a/forms/src/main/java/org/keycloak/forms/RegisterBean.java
+++ b/forms/src/main/java/org/keycloak/forms/RegisterBean.java
@@ -21,11 +21,10 @@
  */
 package org.keycloak.forms;
 
+import javax.ws.rs.core.MultivaluedMap;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.ws.rs.core.MultivaluedMap;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/forms/src/main/java/org/keycloak/forms/SocialBean.java b/forms/src/main/java/org/keycloak/forms/SocialBean.java
old mode 100644
new mode 100755
index 19baaa7..0861b55
--- a/forms/src/main/java/org/keycloak/forms/SocialBean.java
+++ b/forms/src/main/java/org/keycloak/forms/SocialBean.java
@@ -21,15 +21,14 @@
  */
 package org.keycloak.forms;
 
-import java.net.URI;
-import java.util.*;
-
-import javax.imageio.spi.ServiceRegistry;
-import javax.ws.rs.core.UriBuilder;
-
 import org.keycloak.forms.model.SocialProvider;
 import org.keycloak.services.resources.flows.Urls;
 
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+import java.util.LinkedList;
+import java.util.List;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/forms/src/main/java/org/keycloak/forms/TotpBean.java b/forms/src/main/java/org/keycloak/forms/TotpBean.java
old mode 100644
new mode 100755
index a283c2e..5ce40bc
--- a/forms/src/main/java/org/keycloak/forms/TotpBean.java
+++ b/forms/src/main/java/org/keycloak/forms/TotpBean.java
@@ -21,11 +21,12 @@
  */
 package org.keycloak.forms;
 
+import org.keycloak.models.utils.Base32;
+
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.Random;
 
-import org.picketlink.common.util.Base32;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/forms/src/main/java/org/keycloak/forms/UrlBean.java b/forms/src/main/java/org/keycloak/forms/UrlBean.java
index 8d25c3d..49635a0 100755
--- a/forms/src/main/java/org/keycloak/forms/UrlBean.java
+++ b/forms/src/main/java/org/keycloak/forms/UrlBean.java
@@ -21,10 +21,10 @@
  */
 package org.keycloak.forms;
 
-import java.net.URI;
-
 import org.keycloak.services.resources.flows.Urls;
 
+import java.net.URI;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
old mode 100644
new mode 100755
index 6ec433e..b7b914c
--- a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
+++ b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
@@ -21,19 +21,12 @@
  */
 package org.keycloak.service;
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ResourceBundle;
-
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.forms.MessageBean;
 import org.keycloak.forms.LoginBean;
+import org.keycloak.forms.MessageBean;
 import org.keycloak.forms.OAuthGrantBean;
 import org.keycloak.forms.RealmBean;
 import org.keycloak.forms.RegisterBean;
@@ -45,6 +38,13 @@ import org.keycloak.forms.UserBean;
 import org.keycloak.services.FormService;
 import org.keycloak.services.resources.flows.Pages;
 
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+
 /**
  * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
  */
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
index 28cd21c..1e01298 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
@@ -71,7 +71,7 @@ body {
   width: auto;
   position: relative;
 }
-.rcue-login-register .background-area .separator .section,
+.rcue-login-register .background-area .section,
 .rcue-login-register .background-area .social .section {
   padding-top: 1.5em;
   padding-bottom: 1.5em;
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
index 96f8795..7a045e5 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
@@ -1,5 +1,5 @@
 <#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass="reset"; section>
+<@layout.registrationLayout bodyClass="reset" isSeparator=true forceSeparator=true; section>
     <#if section = "title">
 
     ${rb.getString('emailForgotHeader')}
@@ -23,6 +23,6 @@
         </form>
     </div>
     <#elseif section = "info" >
-        <p><a href="#">&laquo; Back to Login</a></p>
+        <p><a href="${url.loginUrl}">&laquo; Back to Login</a></p>
     </#if>
 </@layout.registrationLayout>
\ No newline at end of file
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl
index 74142e0..955d4df 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl
@@ -1,5 +1,5 @@
 <#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass="reset"; section>
+<@layout.registrationLayout bodyClass="reset" isSeparator=false forceSeparator=true; section>
     <#if section = "title">
 
     ${rb.getString('emailUpdateHeader')}
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl
index 32bdd23..ca707a5 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl
@@ -1,5 +1,5 @@
 <#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass=""; section>
+<@layout.registrationLayout bodyClass="" isSeparator=false forceSeparator=true; section>
     <#if section = "title">
 
     Update Account Information
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
index 0832666..cc83a85 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
@@ -1,5 +1,5 @@
 <#import "template-login-action.ftl" as layout>
-<@layout.registrationLayout bodyClass="email"; section>
+<@layout.registrationLayout bodyClass="email" isSeparator=false forceSeparator=true; section>
     <#if section = "title">
 
     Email verification
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
index acbb082..10c668a 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
@@ -1,4 +1,4 @@
-<#macro registrationLayout bodyClass>
+<#macro registrationLayout bodyClass isSeparator=false forceSeparator=false>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 
@@ -7,6 +7,7 @@
     <title>
         <#nested "title">
     </title>
+    <link rel="icon" href="${template.formsPath}/theme/${template.theme}/img/favicon.ico">
     <link href="${template.themeConfig.styles}" rel="stylesheet" />
     <style type="text/css">
         body.rcue-login-register {
@@ -18,7 +19,7 @@
 <body class="rcue-login-register ${bodyClass}">
     <#if (template.themeConfig.logo)?has_content>
         <h1>
-            <a href="#" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
+            <a href="${url.loginUrl}" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
         </h1>
     </#if>
 
@@ -28,7 +29,12 @@
         </h2>
 
         <div class="background-area">
-            <div class="form-area ${(realm.social)?string('social','')} clearfix">
+            <#if !forceSeparator && realm?has_content>
+                <#assign drawSeparator = realm.registrationAllowed>
+            <#else>
+                <#assign drawSeparator = isSeparator>
+            </#if>
+            <div class="form-area ${(realm.social && bodyClass != "register")?string('social','')} ${(drawSeparator)?string('separator','')} clearfix">
                 <div class="section app-form">
                     <h3>Application login area</h3>
                     <#if message?has_content && message.error>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
index 982b31f..f3113dc 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
@@ -1,4 +1,4 @@
-<#macro registrationLayout bodyClass isErrorPage=false>
+<#macro registrationLayout bodyClass isErrorPage=false isSeparator=false forceSeparator=false>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 
@@ -7,6 +7,7 @@
     <title>
         <#nested "title">
     </title>
+    <link rel="icon" href="${template.formsPath}/theme/${template.theme}/img/favicon.ico">
     <link href="${template.themeConfig.styles}" rel="stylesheet" />
     <style type="text/css">
         body.rcue-login-register {
@@ -25,7 +26,7 @@
     </div>
     <#if (template.themeConfig.logo)?has_content>
         <h1>
-            <a href="#" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
+            <a href="${url.loginUrl}" title="Go to the login page"><img src="${template.themeConfig.logo}" alt="Red Hat Logo" /></a>
         </h1>
     </#if>
 
@@ -35,7 +36,12 @@
         </h2>
 
         <div class="background-area">
-            <div class="form-area clearfix">
+            <#if !forceSeparator && realm?has_content>
+                <#assign drawSeparator = realm.registrationAllowed>
+            <#else>
+                <#assign drawSeparator = isSeparator>
+            </#if>
+            <div class="form-area clearfix ${(drawSeparator)?string('separator','')}">
                 <div class="section app-form">
                     <#if !isErrorPage && message?has_content>
                         <#if message.error>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl
index 61e24a8..4a45d93 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-main.ftl
@@ -4,8 +4,7 @@
 <head>
     <meta charset="utf-8">
     <title>Edit Account - <#nested "title"></title>
-    <!-- TODO replace with actual logo once
-    <link rel="icon" href="img/favicon.ico">
+    <link rel="icon" href="${template.formsPath}/theme/${template.theme}/img/favicon.ico">
 
     <!-- Frameworks -->
     <link rel="stylesheet" href="${template.formsPath}/theme/${template.theme}/css/reset.css">
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/AuthenticatedActionsValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/AuthenticatedActionsValve.java
index f151e15..5d2d7d4 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/AuthenticatedActionsValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/AuthenticatedActionsValve.java
@@ -7,7 +7,6 @@ import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.valves.ValveBase;
 import org.jboss.logging.Logger;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.SkeletonKeySession;
 import org.keycloak.adapters.as7.config.ManagedResourceConfig;
 import org.keycloak.representations.SkeletonKeyToken;
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java
index 655dd46..3aada8b 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfig.java
@@ -5,7 +5,6 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java
index cc6a2d6..29b1e60 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/config/ManagedResourceConfigLoader.java
@@ -13,7 +13,6 @@ import org.keycloak.PemUtils;
 import org.keycloak.ResourceMetadata;
 import org.keycloak.representations.idm.PublishedRealmRepresentation;
 
-import javax.ws.rs.client.WebTarget;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
diff --git a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
index 9a346f2..e5374b8 100755
--- a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
@@ -1,7 +1,6 @@
 package org.keycloak.models;
 
 import java.util.List;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/api/src/main/java/org/keycloak/models/Constants.java b/model/api/src/main/java/org/keycloak/models/Constants.java
index 18adf63..b02c9c2 100755
--- a/model/api/src/main/java/org/keycloak/models/Constants.java
+++ b/model/api/src/main/java/org/keycloak/models/Constants.java
@@ -15,4 +15,6 @@ public interface Constants {
     String ACCOUNT_APPLICATION = "Account";
     String ACCOUNT_PROFILE_ROLE = "view-profile";
     String ACCOUNT_MANAGE_ROLE = "manage-account";
+
+    String ACCOUNT_MANAGEMENT_APPLICATION = "Account Management";
 }
diff --git a/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java b/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
index 2b25f46..622500c 100755
--- a/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
@@ -1,7 +1,5 @@
 package org.keycloak.models;
 
-import org.keycloak.models.UserModel;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -10,8 +8,4 @@ public interface OAuthClientModel {
     String getId();
 
     UserModel getOAuthAgent();
-
-    String getBaseUrl();
-
-    void setBaseUrl(String base);
 }
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 2de3e58..3b0b149 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -2,7 +2,6 @@ package org.keycloak.models;
 
 import java.security.PrivateKey;
 import java.security.PublicKey;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -138,11 +137,11 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
 
     List<OAuthClientModel> getOAuthClients();
 
-    HashMap<String, String> getSmtpConfig();
+    Map<String, String> getSmtpConfig();
 
-    void setSmtpConfig(HashMap<String, String> smtpConfig);
+    void setSmtpConfig(Map<String, String> smtpConfig);
 
-    HashMap<String, String> getSocialConfig();
+    Map<String, String> getSocialConfig();
 
-    void setSocialConfig(HashMap<String, String> socialConfig);
+    void setSocialConfig(Map<String, String> socialConfig);
 }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/Base32.java b/model/api/src/main/java/org/keycloak/models/utils/Base32.java
new file mode 100755
index 0000000..aef4422
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/utils/Base32.java
@@ -0,0 +1,113 @@
+package org.keycloak.models.utils;
+
+
+/* (PD) 2006 The Bitzi Corporation
+ * Please see http://bitzi.com/publicdomain for more info.
+ *
+ * $Id: Base32.java,v 1.2 2006/07/14 04:58:39 gojomo Exp $
+ */
+
+/**
+ * Base32 - encodes and decodes RFC3548 Base32 (see http://www.faqs.org/rfcs/rfc3548.html )
+ *
+ * @author Robert Kaye
+ * @author Gordon Mohr
+ */
+public class Base32 {
+    private static final String base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+    private static final int[] base32Lookup = { 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+            0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
+            0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
+            0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+    /**
+     * Encodes byte array to Base32 String.
+     *
+     * @param bytes Bytes to encode.
+     * @return Encoded byte array <code>bytes</code> as a String.
+     *
+     */
+    public static String encode(final byte[] bytes) {
+        int i = 0, index = 0, digit = 0;
+        int currByte, nextByte;
+        StringBuffer base32 = new StringBuffer((bytes.length + 7) * 8 / 5);
+
+        while (i < bytes.length) {
+            currByte = (bytes[i] >= 0) ? bytes[i] : (bytes[i] + 256);
+
+            /* Is the current digit going to span a byte boundary? */
+            if (index > 3) {
+                if ((i + 1) < bytes.length) {
+                    nextByte = (bytes[i + 1] >= 0) ? bytes[i + 1] : (bytes[i + 1] + 256);
+                } else {
+                    nextByte = 0;
+                }
+
+                digit = currByte & (0xFF >> index);
+                index = (index + 5) % 8;
+                digit <<= index;
+                digit |= nextByte >> (8 - index);
+                i++;
+            } else {
+                digit = (currByte >> (8 - (index + 5))) & 0x1F;
+                index = (index + 5) % 8;
+                if (index == 0)
+                    i++;
+            }
+            base32.append(base32Chars.charAt(digit));
+        }
+
+        return base32.toString();
+    }
+
+    /**
+     * Decodes the given Base32 String to a raw byte array.
+     *
+     * @param base32
+     * @return Decoded <code>base32</code> String as a raw byte array.
+     */
+    public static byte[] decode(final String base32) {
+        int i, index, lookup, offset, digit;
+        byte[] bytes = new byte[base32.length() * 5 / 8];
+
+        for (i = 0, index = 0, offset = 0; i < base32.length(); i++) {
+            lookup = base32.charAt(i) - '0';
+
+            /* Skip chars outside the lookup table */
+            if (lookup < 0 || lookup >= base32Lookup.length) {
+                continue;
+            }
+
+            digit = base32Lookup[lookup];
+
+            /* If this digit is not in the table, ignore it */
+            if (digit == 0xFF) {
+                continue;
+            }
+
+            if (index <= 3) {
+                index = (index + 5) % 8;
+                if (index == 0) {
+                    bytes[offset] |= digit;
+                    offset++;
+                    if (offset >= bytes.length)
+                        break;
+                } else {
+                    bytes[offset] |= digit << (8 - index);
+                }
+            } else {
+                index = (index + 5) % 8;
+                bytes[offset] |= (digit >>> index);
+                offset++;
+
+                if (offset >= bytes.length) {
+                    break;
+                }
+                bytes[offset] |= digit << (8 - index);
+            }
+        }
+        return bytes;
+    }
+
+}
\ No newline at end of file
diff --git a/model/api/src/main/java/org/keycloak/models/utils/Base64.java b/model/api/src/main/java/org/keycloak/models/utils/Base64.java
new file mode 100755
index 0000000..2fa912b
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/utils/Base64.java
@@ -0,0 +1,2282 @@
+package org.keycloak.models.utils;
+
+/**
+ * <p>Encodes and decodes to and from Base64 notation.</p>
+ * <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
+ * <p/>
+ * <p>Example:</p>
+ * <p/>
+ * <code>String encoded = Base64.encode( myByteArray );</code>
+ * <br />
+ * <code>byte[] myByteArray = Base64.decode( encoded );</code>
+ * <p/>
+ * <p>The <tt>options</tt> parameter, which appears in a few places, is used to pass
+ * several pieces of information to the encoder. In the "higher level" methods such as
+ * encodeBytes( bytes, options ) the options parameter can be used to indicate such
+ * things as first gzipping the bytes before encoding them, not inserting linefeeds,
+ * and encoding using the URL-safe and Ordered dialects.</p>
+ * <p/>
+ * <p>Note, according to <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>,
+ * Section 2.1, implementations should not add line feeds unless explicitly told
+ * to do so. I've got Base64 set to this behavior now, although earlier versions
+ * broke lines by default.</p>
+ * <p/>
+ * <p>The constants defined in Base64 can be OR-ed together to combine options, so you
+ * might make a call like this:</p>
+ * <p/>
+ * <code>String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES );</code>
+ * <p>to compress the data before encoding it and then making the output have newline characters.</p>
+ * <p>Also...</p>
+ * <code>String encoded = Base64.encodeBytes( crazyString.getBytes() );</code>
+ * <p/>
+ * <p/>
+ * <p/>
+ * <p>
+ * Change Log:
+ * </p>
+ * <ul>
+ * <li>v2.3.7 - Fixed subtle bug when base 64 input stream contained the
+ * value 01111111, which is an invalid base 64 character but should not
+ * throw an ArrayIndexOutOfBoundsException either. Led to discovery of
+ * mishandling (or potential for better handling) of other bad input
+ * characters. You should now get an IOException if you try decoding
+ * something that has bad characters in it.</li>
+ * <li>v2.3.6 - Fixed bug when breaking lines and the final byte of the encoded
+ * string ended in the last column; the buffer was not properly shrunk and
+ * contained an extra (null) byte that made it into the string.</li>
+ * <li>v2.3.5 - Fixed bug in {@link #encodeFromFile} where estimated buffer size
+ * was wrong for files of size 31, 34, and 37 bytes.</li>
+ * <li>v2.3.4 - Fixed bug when working with gzipped streams whereby flushing
+ * the Base64.OutputStream closed the Base64 encoding (by padding with equals
+ * signs) too soon. Also added an option to suppress the automatic decoding
+ * of gzipped streams. Also added experimental support for specifying a
+ * class loader when using the
+ * {@link #decodeToObject(java.lang.String, int, java.lang.ClassLoader)}
+ * method.</li>
+ * <li>v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java
+ * footprint with its CharEncoders and so forth. Fixed some javadocs that were
+ * inconsistent. Removed imports and specified things like java.io.IOException
+ * explicitly inline.</li>
+ * <li>v2.3.2 - Reduced memory footprint! Finally refined the "guessing" of how big the
+ * final encoded data will be so that the code doesn't have to create two output
+ * arrays: an oversized initial one and then a final, exact-sized one. Big win
+ * when using the {@link #encodeBytesToBytes(byte[])} family of methods (and not
+ * using the gzip options which uses a different mechanism with streams and stuff).</li>
+ * <li>v2.3.1 - Added {@link #encodeBytesToBytes(byte[], int, int, int)} and some
+ * similar helper methods to be more efficient with memory by not returning a
+ * String but just a byte array.</li>
+ * <li>v2.3 - <strong>This is not a drop-in replacement!</strong> This is two years of comments
+ * and bug fixes queued up and finally executed. Thanks to everyone who sent
+ * me stuff, and I'm sorry I wasn't able to distribute your fixes to everyone else.
+ * Much bad coding was cleaned up including throwing exceptions where necessary
+ * instead of returning null values or something similar. Here are some changes
+ * that may affect you:
+ * <ul>
+ * <li><em>Does not break lines, by default.</em> This is to keep in compliance with
+ * <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>.</li>
+ * <li><em>Throws exceptions instead of returning null values.</em> Because some operations
+ * (especially those that may permit the GZIP option) use IO streams, there
+ * is a possiblity of an java.io.IOException being thrown. After some discussion and
+ * thought, I've changed the behavior of the methods to throw java.io.IOExceptions
+ * rather than return null if ever there's an error. I think this is more
+ * appropriate, though it will require some changes to your code. Sorry,
+ * it should have been done this way to begin with.</li>
+ * <li><em>Removed all references to System.out, System.err, and the like.</em>
+ * Shame on me. All I can say is sorry they were ever there.</li>
+ * <li><em>Throws NullPointerExceptions and IllegalArgumentExceptions</em> as needed
+ * such as when passed arrays are null or offsets are invalid.</li>
+ * <li>Cleaned up as much javadoc as I could to avoid any javadoc warnings.
+ * This was especially annoying before for people who were thorough in their
+ * own projects and then had gobs of javadoc warnings on this file.</li>
+ * </ul>
+ * <li>v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug
+ * when using very small files (~&lt; 40 bytes).</li>
+ * <li>v2.2 - Added some helper methods for encoding/decoding directly from
+ * one file to the next. Also added a main() method to support command line
+ * encoding/decoding from one file to the next. Also added these Base64 dialects:
+ * <ol>
+ * <li>The default is RFC3548 format.</li>
+ * <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates
+ * URL and file name friendly format as described in Section 4 of RFC3548.
+ * http://www.faqs.org/rfcs/rfc3548.html</li>
+ * <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates
+ * URL and file name friendly format that preserves lexical ordering as described
+ * in http://www.faqs.org/qa/rfcc-1940.html</li>
+ * </ol>
+ * Special thanks to Jim Kellerman at <a href="http://www.powerset.com/">http://www.powerset.com/</a>
+ * for contributing the new Base64 dialects.
+ * </li>
+ * <p/>
+ * <li>v2.1 - Cleaned up javadoc comments and unused variables and methods. Added
+ * some convenience methods for reading and writing to and from files.</li>
+ * <li>v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems
+ * with other encodings (like EBCDIC).</li>
+ * <li>v2.0.1 - Fixed an error when decoding a single byte, that is, when the
+ * encoded data was a single byte.</li>
+ * <li>v2.0 - I got rid of methods that used booleans to set options.
+ * Now everything is more consolidated and cleaner. The code now detects
+ * when data that's being decoded is gzip-compressed and will decompress it
+ * automatically. Generally things are cleaner. You'll probably have to
+ * change some method calls that you were making to support the new
+ * options format (<tt>int</tt>s that you "OR" together).</li>
+ * <li>v1.5.1 - Fixed bug when decompressing and decoding to a
+ * byte[] using <tt>decode( String s, boolean gzipCompressed )</tt>.
+ * Added the ability to "suspend" encoding in the Output Stream so
+ * you can turn on and off the encoding if you need to embed base64
+ * data in an otherwise "normal" stream (like an XML file).</li>
+ * <li>v1.5 - Output stream pases on flush() command but doesn't do anything itself.
+ * This helps when using GZIP streams.
+ * Added the ability to GZip-compress objects before encoding them.</li>
+ * <li>v1.4 - Added helper methods to read/write files.</li>
+ * <li>v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.</li>
+ * <li>v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream
+ * where last buffer being read, if not completely full, was not returned.</li>
+ * <li>v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.</li>
+ * <li>v1.3.3 - Fixed I/O streams which were totally messed up.</li>
+ * </ul>
+ * <p/>
+ * <p>
+ * I am placing this code in the Public Domain. Do with it as you will.
+ * This software comes with no guarantees or warranties but with
+ * plenty of well-wishing instead!
+ * Please visit <a href="http://iharder.net/base64">http://iharder.net/base64</a>
+ * periodically to check for updates or to contribute improvements.
+ * </p>
+ *
+ * @author Robert Harder
+ * @author rob@iharder.net
+ * @version 2.3.7
+ */
+public class Base64
+{
+
+/* ********  P U B L I C   F I E L D S  ******** */
+
+
+    /**
+     * No options specified. Value is zero.
+     */
+    public final static int NO_OPTIONS = 0;
+
+    /**
+     * Specify encoding in first bit. Value is one.
+     */
+    public final static int ENCODE = 1;
+
+
+    /**
+     * Specify decoding in first bit. Value is zero.
+     */
+    public final static int DECODE = 0;
+
+
+    /**
+     * Specify that data should be gzip-compressed in second bit. Value is two.
+     */
+    public final static int GZIP = 2;
+
+    /**
+     * Specify that gzipped data should <em>not</em> be automatically gunzipped.
+     */
+    public final static int DONT_GUNZIP = 4;
+
+
+    /**
+     * Do break lines when encoding. Value is 8.
+     */
+    public final static int DO_BREAK_LINES = 8;
+
+    /**
+     * Encode using Base64-like encoding that is URL- and Filename-safe as described
+     * in Section 4 of RFC3548:
+     * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
+     * It is important to note that data encoded this way is <em>not</em> officially valid Base64,
+     * or at the very least should not be called Base64 without also specifying that is
+     * was encoded using the URL- and Filename-safe dialect.
+     */
+    public final static int URL_SAFE = 16;
+
+
+    /**
+     * Encode using the special "ordered" dialect of Base64 described here:
+     * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
+     */
+    public final static int ORDERED = 32;
+
+
+/* ********  P R I V A T E   F I E L D S  ******** */
+
+
+    /**
+     * Maximum line length (76) of Base64 output.
+     */
+    private final static int MAX_LINE_LENGTH = 76;
+
+
+    /**
+     * The equals sign (=) as a byte.
+     */
+    private final static byte EQUALS_SIGN = (byte) '=';
+
+
+    /**
+     * The new line character (\n) as a byte.
+     */
+    private final static byte NEW_LINE = (byte) '\n';
+
+
+    /**
+     * Preferred encoding.
+     */
+    private final static String PREFERRED_ENCODING = "US-ASCII";
+
+
+    private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
+    private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
+
+
+/* ********  S T A N D A R D   B A S E 6 4   A L P H A B E T  ******** */
+
+    /**
+     * The 64 valid Base64 values.
+     */
+   /* Host platform me be something funny like EBCDIC, so we hardcode these values. */
+    private final static byte[] _STANDARD_ALPHABET = {
+            (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
+            (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
+            (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
+            (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
+            (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
+            (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
+            (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
+            (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
+            (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
+            (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/'
+    };
+
+
+    /**
+     * Translates a Base64 value to either its 6-bit reconstruction value
+     * or a negative number indicating some other meaning.
+     */
+    private final static byte[] _STANDARD_DECODABET = {
+            -9, -9, -9, -9, -9, -9, -9, -9, -9,                 // Decimal  0 -  8
+            -5, -5,                                      // Whitespace: Tab and Linefeed
+            -9, -9,                                      // Decimal 11 - 12
+            -5,                                         // Whitespace: Carriage Return
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 14 - 26
+            -9, -9, -9, -9, -9,                             // Decimal 27 - 31
+            -5,                                         // Whitespace: Space
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,              // Decimal 33 - 42
+            62,                                         // Plus sign at decimal 43
+            -9, -9, -9,                                   // Decimal 44 - 46
+            63,                                         // Slash at decimal 47
+            52, 53, 54, 55, 56, 57, 58, 59, 60, 61,              // Numbers zero through nine
+            -9, -9, -9,                                   // Decimal 58 - 60
+            -1,                                         // Equals sign at decimal 61
+            -9, -9, -9,                                      // Decimal 62 - 64
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,            // Letters 'A' through 'N'
+            14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,        // Letters 'O' through 'Z'
+            -9, -9, -9, -9, -9, -9,                          // Decimal 91 - 96
+            26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,     // Letters 'a' through 'm'
+            39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,     // Letters 'n' through 'z'
+            -9, -9, -9, -9, -9                              // Decimal 123 - 127
+            , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,       // Decimal 128 - 139
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 140 - 152
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 153 - 165
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 166 - 178
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 179 - 191
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 192 - 204
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 205 - 217
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 218 - 230
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 231 - 243
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9         // Decimal 244 - 255
+    };
+
+
+/* ********  U R L   S A F E   B A S E 6 4   A L P H A B E T  ******** */
+
+    /**
+     * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
+     * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
+     * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
+     */
+    private final static byte[] _URL_SAFE_ALPHABET = {
+            (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
+            (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
+            (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
+            (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
+            (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
+            (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
+            (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
+            (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
+            (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
+            (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '-', (byte) '_'
+    };
+
+    /**
+     * Used in decoding URL- and Filename-safe dialects of Base64.
+     */
+    private final static byte[] _URL_SAFE_DECODABET = {
+            -9, -9, -9, -9, -9, -9, -9, -9, -9,                 // Decimal  0 -  8
+            -5, -5,                                      // Whitespace: Tab and Linefeed
+            -9, -9,                                      // Decimal 11 - 12
+            -5,                                         // Whitespace: Carriage Return
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 14 - 26
+            -9, -9, -9, -9, -9,                             // Decimal 27 - 31
+            -5,                                         // Whitespace: Space
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,              // Decimal 33 - 42
+            -9,                                         // Plus sign at decimal 43
+            -9,                                         // Decimal 44
+            62,                                         // Minus sign at decimal 45
+            -9,                                         // Decimal 46
+            -9,                                         // Slash at decimal 47
+            52, 53, 54, 55, 56, 57, 58, 59, 60, 61,              // Numbers zero through nine
+            -9, -9, -9,                                   // Decimal 58 - 60
+            -1,                                         // Equals sign at decimal 61
+            -9, -9, -9,                                   // Decimal 62 - 64
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,            // Letters 'A' through 'N'
+            14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,        // Letters 'O' through 'Z'
+            -9, -9, -9, -9,                                // Decimal 91 - 94
+            63,                                         // Underscore at decimal 95
+            -9,                                         // Decimal 96
+            26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,     // Letters 'a' through 'm'
+            39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,     // Letters 'n' through 'z'
+            -9, -9, -9, -9, -9                              // Decimal 123 - 127
+            , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 128 - 139
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 140 - 152
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 153 - 165
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 166 - 178
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 179 - 191
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 192 - 204
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 205 - 217
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 218 - 230
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 231 - 243
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9         // Decimal 244 - 255
+    };
+
+
+/* ********  O R D E R E D   B A S E 6 4   A L P H A B E T  ******** */
+
+    /**
+     * I don't get the point of this technique, but someone requested it,
+     * and it is described here:
+     * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
+     */
+    private final static byte[] _ORDERED_ALPHABET = {
+            (byte) '-',
+            (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
+            (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
+            (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
+            (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
+            (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
+            (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
+            (byte) '_',
+            (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
+            (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
+            (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
+            (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z'
+    };
+
+    /**
+     * Used in decoding the "ordered" dialect of Base64.
+     */
+    private final static byte[] _ORDERED_DECODABET = {
+            -9, -9, -9, -9, -9, -9, -9, -9, -9,                 // Decimal  0 -  8
+            -5, -5,                                      // Whitespace: Tab and Linefeed
+            -9, -9,                                      // Decimal 11 - 12
+            -5,                                         // Whitespace: Carriage Return
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 14 - 26
+            -9, -9, -9, -9, -9,                             // Decimal 27 - 31
+            -5,                                         // Whitespace: Space
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,              // Decimal 33 - 42
+            -9,                                         // Plus sign at decimal 43
+            -9,                                         // Decimal 44
+            0,                                          // Minus sign at decimal 45
+            -9,                                         // Decimal 46
+            -9,                                         // Slash at decimal 47
+            1, 2, 3, 4, 5, 6, 7, 8, 9, 10,                       // Numbers zero through nine
+            -9, -9, -9,                                   // Decimal 58 - 60
+            -1,                                         // Equals sign at decimal 61
+            -9, -9, -9,                                   // Decimal 62 - 64
+            11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,     // Letters 'A' through 'M'
+            24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,     // Letters 'N' through 'Z'
+            -9, -9, -9, -9,                                // Decimal 91 - 94
+            37,                                         // Underscore at decimal 95
+            -9,                                         // Decimal 96
+            38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,     // Letters 'a' through 'm'
+            51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,     // Letters 'n' through 'z'
+            -9, -9, -9, -9, -9                                 // Decimal 123 - 127
+            , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 128 - 139
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 140 - 152
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 153 - 165
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 166 - 178
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 179 - 191
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 192 - 204
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 205 - 217
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 218 - 230
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,     // Decimal 231 - 243
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9         // Decimal 244 - 255
+    };
+
+
+/* ********  D E T E R M I N E   W H I C H   A L H A B E T  ******** */
+
+
+    /**
+     * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
+     * the options specified.
+     * It's possible, though silly, to specify ORDERED <b>and</b> URLSAFE
+     * in which case one of them will be picked, though there is
+     * no guarantee as to which one will be picked.
+     */
+    private final static byte[] getAlphabet(int options)
+    {
+        if ((options & URL_SAFE) == URL_SAFE)
+        {
+            return _URL_SAFE_ALPHABET;
+        }
+        else if ((options & ORDERED) == ORDERED)
+        {
+            return _ORDERED_ALPHABET;
+        }
+        else
+        {
+            return _STANDARD_ALPHABET;
+        }
+    }   // end getAlphabet
+
+
+    /**
+     * Returns one of the _SOMETHING_DECODABET byte arrays depending on
+     * the options specified.
+     * It's possible, though silly, to specify ORDERED and URL_SAFE
+     * in which case one of them will be picked, though there is
+     * no guarantee as to which one will be picked.
+     */
+    private final static byte[] getDecodabet(int options)
+    {
+        if ((options & URL_SAFE) == URL_SAFE)
+        {
+            return _URL_SAFE_DECODABET;
+        }
+        else if ((options & ORDERED) == ORDERED)
+        {
+            return _ORDERED_DECODABET;
+        }
+        else
+        {
+            return _STANDARD_DECODABET;
+        }
+    }   // end getAlphabet
+
+
+    /**
+     * Defeats instantiation.
+     */
+    private Base64()
+    {
+    }
+
+
+/* ********  E N C O D I N G   M E T H O D S  ******** */
+
+
+    /**
+     * Encodes up to the first three bytes of array <var>threeBytes</var>
+     * and returns a four-byte array in Base64 notation.
+     * The actual number of significant bytes in your array is
+     * given by <var>numSigBytes</var>.
+     * The array <var>threeBytes</var> needs only be as big as
+     * <var>numSigBytes</var>.
+     * Code can reuse a byte array by passing a four-byte array as <var>b4</var>.
+     *
+     * @param b4          A reusable byte array to reduce array instantiation
+     * @param threeBytes  the array to convert
+     * @param numSigBytes the number of significant bytes in your array
+     * @return four byte array in Base64 notation.
+     * @since 1.5.1
+     */
+    private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes, int options)
+    {
+        encode3to4(threeBytes, 0, numSigBytes, b4, 0, options);
+        return b4;
+    }   // end encode3to4
+
+
+    /**
+     * <p>Encodes up to three bytes of the array <var>source</var>
+     * and writes the resulting four Base64 bytes to <var>destination</var>.
+     * The source and destination arrays can be manipulated
+     * anywhere along their length by specifying
+     * <var>srcOffset</var> and <var>destOffset</var>.
+     * This method does not check to make sure your arrays
+     * are large enough to accomodate <var>srcOffset</var> + 3 for
+     * the <var>source</var> array or <var>destOffset</var> + 4 for
+     * the <var>destination</var> array.
+     * The actual number of significant bytes in your array is
+     * given by <var>numSigBytes</var>.</p>
+     * <p>This is the lowest level of the encoding methods with
+     * all possible parameters.</p>
+     *
+     * @param source      the array to convert
+     * @param srcOffset   the index where conversion begins
+     * @param numSigBytes the number of significant bytes in your array
+     * @param destination the array to hold the conversion
+     * @param destOffset  the index where output will be put
+     * @return the <var>destination</var> array
+     * @since 1.3
+     */
+    private static byte[] encode3to4(
+            byte[] source, int srcOffset, int numSigBytes,
+            byte[] destination, int destOffset, int options)
+    {
+
+        byte[] ALPHABET = getAlphabet(options);
+
+        //           1         2         3
+        // 01234567890123456789012345678901 Bit position
+        // --------000000001111111122222222 Array position from threeBytes
+        // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
+        //          >>18  >>12  >> 6  >> 0  Right shift necessary
+        //                0x3f  0x3f  0x3f  Additional AND
+
+        // Create buffer with zero-padding if there are only one or two
+        // significant bytes passed in the array.
+        // We have to shift left 24 in order to flush out the 1's that appear
+        // when Java treats a value as negative that is cast from a byte to an int.
+        int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
+                | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
+                | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
+
+        switch (numSigBytes)
+        {
+            case 3:
+                destination[destOffset] = ALPHABET[(inBuff >>> 18)];
+                destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
+                destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
+                destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
+                return destination;
+
+            case 2:
+                destination[destOffset] = ALPHABET[(inBuff >>> 18)];
+                destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
+                destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
+                destination[destOffset + 3] = EQUALS_SIGN;
+                return destination;
+
+            case 1:
+                destination[destOffset] = ALPHABET[(inBuff >>> 18)];
+                destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
+                destination[destOffset + 2] = EQUALS_SIGN;
+                destination[destOffset + 3] = EQUALS_SIGN;
+                return destination;
+
+            default:
+                return destination;
+        }   // end switch
+    }   // end encode3to4
+
+
+    /**
+     * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
+     * writing it to the <code>encoded</code> ByteBuffer.
+     * This is an experimental feature. Currently it does not
+     * pass along any options (such as {@link #DO_BREAK_LINES}
+     * or {@link #GZIP}.
+     *
+     * @param raw     input buffer
+     * @param encoded output buffer
+     * @since 2.3
+     */
+    public static void encode(java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded)
+    {
+        byte[] raw3 = new byte[3];
+        byte[] enc4 = new byte[4];
+
+        while (raw.hasRemaining())
+        {
+            int rem = Math.min(3, raw.remaining());
+            raw.get(raw3, 0, rem);
+            Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
+            encoded.put(enc4);
+        }   // end input remaining
+    }
+
+
+    /**
+     * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
+     * writing it to the <code>encoded</code> CharBuffer.
+     * This is an experimental feature. Currently it does not
+     * pass along any options (such as {@link #DO_BREAK_LINES}
+     * or {@link #GZIP}.
+     *
+     * @param raw     input buffer
+     * @param encoded output buffer
+     * @since 2.3
+     */
+    public static void encode(java.nio.ByteBuffer raw, java.nio.CharBuffer encoded)
+    {
+        byte[] raw3 = new byte[3];
+        byte[] enc4 = new byte[4];
+
+        while (raw.hasRemaining())
+        {
+            int rem = Math.min(3, raw.remaining());
+            raw.get(raw3, 0, rem);
+            Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
+            for (int i = 0; i < 4; i++)
+            {
+                encoded.put((char) (enc4[i] & 0xFF));
+            }
+        }   // end input remaining
+    }
+
+
+    /**
+     * Serializes an object and returns the Base64-encoded
+     * version of that serialized object.
+     * <p/>
+     * <p>As of v 2.3, if the object
+     * cannot be serialized or there is another error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned a null value, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     * <p/>
+     * The object is not GZip-compressed before being encoded.
+     *
+     * @param serializableObject The object to encode
+     * @return The Base64-encoded object
+     * @throws java.io.IOException  if there is an error
+     * @throws NullPointerException if serializedObject is null
+     * @since 1.4
+     */
+    public static String encodeObject(java.io.Serializable serializableObject)
+            throws java.io.IOException
+    {
+        return encodeObject(serializableObject, NO_OPTIONS);
+    }   // end encodeObject
+
+
+    /**
+     * Serializes an object and returns the Base64-encoded
+     * version of that serialized object.
+     * <p/>
+     * <p>As of v 2.3, if the object
+     * cannot be serialized or there is another error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned a null value, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     * <p/>
+     * The object is not GZip-compressed before being encoded.
+     * <p/>
+     * Example options:<pre>
+     *   GZIP: gzip-compresses object before encoding it.
+     *   DO_BREAK_LINES: break lines at 76 characters
+     * </pre>
+     * <p/>
+     * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
+     * <p/>
+     * Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
+     *
+     * @param serializableObject The object to encode
+     * @param options            Specified options
+     * @return The Base64-encoded object
+     * @throws java.io.IOException if there is an error
+     * @see Base64#GZIP
+     * @see Base64#DO_BREAK_LINES
+     * @since 2.0
+     */
+    public static String encodeObject(java.io.Serializable serializableObject, int options)
+            throws java.io.IOException
+    {
+
+        if (serializableObject == null)
+        {
+            throw new NullPointerException("Cannot serialize a null object.");
+        }   // end if: null
+
+        // Streams
+        java.io.ByteArrayOutputStream baos = null;
+        java.io.OutputStream b64os = null;
+        java.util.zip.GZIPOutputStream gzos = null;
+        java.io.ObjectOutputStream oos = null;
+
+
+        try
+        {
+            // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
+            baos = new java.io.ByteArrayOutputStream();
+            b64os = new Base64.OutputStream(baos, ENCODE | options);
+            if ((options & GZIP) != 0)
+            {
+                // Gzip
+                gzos = new java.util.zip.GZIPOutputStream(b64os);
+                oos = new java.io.ObjectOutputStream(gzos);
+            }
+            else
+            {
+                // Not gzipped
+                oos = new java.io.ObjectOutputStream(b64os);
+            }
+            oos.writeObject(serializableObject);
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            // Catch it and then throw it immediately so that
+            // the finally{} block is called for cleanup.
+            throw e;
+        }   // end catch
+        finally
+        {
+            try
+            { oos.close(); }
+            catch (Exception e)
+            {}
+            try
+            { gzos.close(); }
+            catch (Exception e)
+            {}
+            try
+            { b64os.close(); }
+            catch (Exception e)
+            {}
+            try
+            { baos.close(); }
+            catch (Exception e)
+            {}
+        }   // end finally
+
+        // Return value according to relevant encoding.
+        try
+        {
+            return new String(baos.toByteArray(), PREFERRED_ENCODING);
+        }   // end try
+        catch (java.io.UnsupportedEncodingException uue)
+        {
+            // Fall back to some Java default
+            return new String(baos.toByteArray());
+        }   // end catch
+
+    }   // end encode
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * Does not GZip-compress data.
+     *
+     * @param source The data to convert
+     * @return The data in Base64-encoded form
+     * @throws NullPointerException if source array is null
+     * @since 1.4
+     */
+    public static String encodeBytes(byte[] source)
+    {
+        // Since we're not going to have the GZIP encoding turned on,
+        // we're not going to have an java.io.IOException thrown, so
+        // we should not force the user to have to catch it.
+        String encoded = null;
+        try
+        {
+            encoded = encodeBytes(source, 0, source.length, NO_OPTIONS);
+        }
+        catch (java.io.IOException ex)
+        {
+            assert false : ex.getMessage();
+        }   // end catch
+        assert encoded != null;
+        return encoded;
+    }   // end encodeBytes
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * <p>
+     * Example options:<pre>
+     *   GZIP: gzip-compresses object before encoding it.
+     *   DO_BREAK_LINES: break lines at 76 characters
+     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+     * </pre>
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
+     * <p/>
+     * <p/>
+     * <p>As of v 2.3, if there is an error with the GZIP stream,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned a null value, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param source  The data to convert
+     * @param options Specified options
+     * @return The Base64-encoded data as a String
+     * @throws java.io.IOException  if there is an error
+     * @throws NullPointerException if source array is null
+     * @see Base64#GZIP
+     * @see Base64#DO_BREAK_LINES
+     * @since 2.0
+     */
+    public static String encodeBytes(byte[] source, int options) throws java.io.IOException
+    {
+        return encodeBytes(source, 0, source.length, options);
+    }   // end encodeBytes
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * Does not GZip-compress data.
+     * <p/>
+     * <p>As of v 2.3, if there is an error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned a null value, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param source The data to convert
+     * @param off    Offset in array where conversion should begin
+     * @param len    Length of data to convert
+     * @return The Base64-encoded data as a String
+     * @throws NullPointerException     if source array is null
+     * @throws IllegalArgumentException if source array, offset, or length are invalid
+     * @since 1.4
+     */
+    public static String encodeBytes(byte[] source, int off, int len)
+    {
+        // Since we're not going to have the GZIP encoding turned on,
+        // we're not going to have an java.io.IOException thrown, so
+        // we should not force the user to have to catch it.
+        String encoded = null;
+        try
+        {
+            encoded = encodeBytes(source, off, len, NO_OPTIONS);
+        }
+        catch (java.io.IOException ex)
+        {
+            assert false : ex.getMessage();
+        }   // end catch
+        assert encoded != null;
+        return encoded;
+    }   // end encodeBytes
+
+
+    /**
+     * Encodes a byte array into Base64 notation.
+     * <p>
+     * Example options:<pre>
+     *   GZIP: gzip-compresses object before encoding it.
+     *   DO_BREAK_LINES: break lines at 76 characters
+     *     <i>Note: Technically, this makes your encoding non-compliant.</i>
+     * </pre>
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
+     * <p>
+     * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
+     * <p/>
+     * <p/>
+     * <p>As of v 2.3, if there is an error with the GZIP stream,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned a null value, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param source  The data to convert
+     * @param off     Offset in array where conversion should begin
+     * @param len     Length of data to convert
+     * @param options Specified options
+     * @return The Base64-encoded data as a String
+     * @throws java.io.IOException      if there is an error
+     * @throws NullPointerException     if source array is null
+     * @throws IllegalArgumentException if source array, offset, or length are invalid
+     * @see Base64#GZIP
+     * @see Base64#DO_BREAK_LINES
+     * @since 2.0
+     */
+    public static String encodeBytes(byte[] source, int off, int len, int options) throws java.io.IOException
+    {
+        byte[] encoded = encodeBytesToBytes(source, off, len, options);
+
+        // Return value according to relevant encoding.
+        try
+        {
+            return new String(encoded, PREFERRED_ENCODING);
+        }   // end try
+        catch (java.io.UnsupportedEncodingException uue)
+        {
+            return new String(encoded);
+        }   // end catch
+
+    }   // end encodeBytes
+
+
+    /**
+     * Similar to {@link #encodeBytes(byte[])} but returns
+     * a byte array instead of instantiating a String. This is more efficient
+     * if you're working with I/O streams and have large data sets to encode.
+     *
+     * @param source The data to convert
+     * @return The Base64-encoded data as a byte[] (of ASCII characters)
+     * @throws NullPointerException if source array is null
+     * @since 2.3.1
+     */
+    public static byte[] encodeBytesToBytes(byte[] source)
+    {
+        byte[] encoded = null;
+        try
+        {
+            encoded = encodeBytesToBytes(source, 0, source.length, Base64.NO_OPTIONS);
+        }
+        catch (java.io.IOException ex)
+        {
+            assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
+        }
+        return encoded;
+    }
+
+
+    /**
+     * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns
+     * a byte array instead of instantiating a String. This is more efficient
+     * if you're working with I/O streams and have large data sets to encode.
+     *
+     * @param source  The data to convert
+     * @param off     Offset in array where conversion should begin
+     * @param len     Length of data to convert
+     * @param options Specified options
+     * @return The Base64-encoded data as a String
+     * @throws java.io.IOException      if there is an error
+     * @throws NullPointerException     if source array is null
+     * @throws IllegalArgumentException if source array, offset, or length are invalid
+     * @see Base64#GZIP
+     * @see Base64#DO_BREAK_LINES
+     * @since 2.3.1
+     */
+    public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options) throws java.io.IOException
+    {
+
+        if (source == null)
+        {
+            throw new NullPointerException("Cannot serialize a null array.");
+        }   // end if: null
+
+        if (off < 0)
+        {
+            throw new IllegalArgumentException("Cannot have negative offset: " + off);
+        }   // end if: off < 0
+
+        if (len < 0)
+        {
+            throw new IllegalArgumentException("Cannot have length offset: " + len);
+        }   // end if: len < 0
+
+        if (off + len > source.length)
+        {
+            throw new IllegalArgumentException(
+                    String.format("Cannot have offset of %d and length of %d with array of length %d", off, len, source.length));
+        }   // end if: off < 0
+
+
+        // Compress?
+        if ((options & GZIP) != 0)
+        {
+            java.io.ByteArrayOutputStream baos = null;
+            java.util.zip.GZIPOutputStream gzos = null;
+            Base64.OutputStream b64os = null;
+
+            try
+            {
+                // GZip -> Base64 -> ByteArray
+                baos = new java.io.ByteArrayOutputStream();
+                b64os = new Base64.OutputStream(baos, ENCODE | options);
+                gzos = new java.util.zip.GZIPOutputStream(b64os);
+
+                gzos.write(source, off, len);
+                gzos.close();
+            }   // end try
+            catch (java.io.IOException e)
+            {
+                // Catch it and then throw it immediately so that
+                // the finally{} block is called for cleanup.
+                throw e;
+            }   // end catch
+            finally
+            {
+                try
+                { gzos.close(); }
+                catch (Exception e)
+                {}
+                try
+                { b64os.close(); }
+                catch (Exception e)
+                {}
+                try
+                { baos.close(); }
+                catch (Exception e)
+                {}
+            }   // end finally
+
+            return baos.toByteArray();
+        }   // end if: compress
+
+        // Else, don't compress. Better not to use streams at all then.
+        else
+        {
+            boolean breakLines = (options & DO_BREAK_LINES) != 0;
+
+            //int    len43   = len * 4 / 3;
+            //byte[] outBuff = new byte[   ( len43 )                      // Main 4:3
+            //                           + ( (len % 3) > 0 ? 4 : 0 )      // Account for padding
+            //                           + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
+            // Try to determine more precisely how big the array needs to be.
+            // If we get it right, we don't have to do an array copy, and
+            // we save a bunch of memory.
+            int encLen = (len / 3) * 4 + (len % 3 > 0 ? 4 : 0); // Bytes needed for actual encoding
+            if (breakLines)
+            {
+                encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters
+            }
+            byte[] outBuff = new byte[encLen];
+
+
+            int d = 0;
+            int e = 0;
+            int len2 = len - 2;
+            int lineLength = 0;
+            for (; d < len2; d += 3, e += 4)
+            {
+                encode3to4(source, d + off, 3, outBuff, e, options);
+
+                lineLength += 4;
+                if (breakLines && lineLength >= MAX_LINE_LENGTH)
+                {
+                    outBuff[e + 4] = NEW_LINE;
+                    e++;
+                    lineLength = 0;
+                }   // end if: end of line
+            }   // en dfor: each piece of array
+
+            if (d < len)
+            {
+                encode3to4(source, d + off, len - d, outBuff, e, options);
+                e += 4;
+            }   // end if: some padding needed
+
+
+            // Only resize array if we didn't guess it right.
+            if (e <= outBuff.length - 1)
+            {
+                // If breaking lines and the last byte falls right at
+                // the line length (76 bytes per line), there will be
+                // one extra byte, and the array will need to be resized.
+                // Not too bad of an estimate on array size, I'd say.
+                byte[] finalOut = new byte[e];
+                System.arraycopy(outBuff, 0, finalOut, 0, e);
+                //System.err.println("Having to resize array from " + outBuff.length + " to " + e );
+                return finalOut;
+            }
+            else
+            {
+                //System.err.println("No need to resize array.");
+                return outBuff;
+            }
+
+        }   // end else: don't compress
+
+    }   // end encodeBytesToBytes
+
+
+/* ********  D E C O D I N G   M E T H O D S  ******** */
+
+
+    /**
+     * Decodes four bytes from array <var>source</var>
+     * and writes the resulting bytes (up to three of them)
+     * to <var>destination</var>.
+     * The source and destination arrays can be manipulated
+     * anywhere along their length by specifying
+     * <var>srcOffset</var> and <var>destOffset</var>.
+     * This method does not check to make sure your arrays
+     * are large enough to accomodate <var>srcOffset</var> + 4 for
+     * the <var>source</var> array or <var>destOffset</var> + 3 for
+     * the <var>destination</var> array.
+     * This method returns the actual number of bytes that
+     * were converted from the Base64 encoding.
+     * <p>This is the lowest level of the decoding methods with
+     * all possible parameters.</p>
+     *
+     * @param source      the array to convert
+     * @param srcOffset   the index where conversion begins
+     * @param destination the array to hold the conversion
+     * @param destOffset  the index where output will be put
+     * @param options     alphabet type is pulled from this (standard, url-safe, ordered)
+     * @return the number of decoded bytes converted
+     * @throws NullPointerException     if source or destination arrays are null
+     * @throws IllegalArgumentException if srcOffset or destOffset are invalid
+     *                                  or there is not enough room in the array.
+     * @since 1.3
+     */
+    private static int decode4to3(
+            byte[] source, int srcOffset,
+            byte[] destination, int destOffset, int options)
+    {
+
+        // Lots of error checking and exception throwing
+        if (source == null)
+        {
+            throw new NullPointerException("Source array was null.");
+        }   // end if
+        if (destination == null)
+        {
+            throw new NullPointerException("Destination array was null.");
+        }   // end if
+        if (srcOffset < 0 || srcOffset + 3 >= source.length)
+        {
+            throw new IllegalArgumentException(String.format(
+                    "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset));
+        }   // end if
+        if (destOffset < 0 || destOffset + 2 >= destination.length)
+        {
+            throw new IllegalArgumentException(String.format(
+                    "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset));
+        }   // end if
+
+
+        byte[] DECODABET = getDecodabet(options);
+
+        // Example: Dk==
+        if (source[srcOffset + 2] == EQUALS_SIGN)
+        {
+            // Two ways to do the same thing. Don't know which way I like best.
+            //int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] << 24 ) >>>  6 )
+            //              | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
+            int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
+                    | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
+
+            destination[destOffset] = (byte) (outBuff >>> 16);
+            return 1;
+        }
+
+        // Example: DkL=
+        else if (source[srcOffset + 3] == EQUALS_SIGN)
+        {
+            // Two ways to do the same thing. Don't know which way I like best.
+            //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
+            //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+            //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
+            int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
+                    | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
+                    | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
+
+            destination[destOffset] = (byte) (outBuff >>> 16);
+            destination[destOffset + 1] = (byte) (outBuff >>> 8);
+            return 2;
+        }
+
+        // Example: DkLE
+        else
+        {
+            // Two ways to do the same thing. Don't know which way I like best.
+            //int outBuff =   ( ( DECODABET[ source[ srcOffset     ] ] << 24 ) >>>  6 )
+            //              | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
+            //              | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
+            //              | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
+            int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
+                    | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
+                    | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6)
+                    | ((DECODABET[source[srcOffset + 3]] & 0xFF));
+
+
+            destination[destOffset] = (byte) (outBuff >> 16);
+            destination[destOffset + 1] = (byte) (outBuff >> 8);
+            destination[destOffset + 2] = (byte) (outBuff);
+
+            return 3;
+        }
+    }   // end decodeToBytes
+
+
+    /**
+     * Low-level access to decoding ASCII characters in
+     * the form of a byte array. <strong>Ignores GUNZIP option, if
+     * it's set.</strong> This is not generally a recommended method,
+     * although it is used internally as part of the decoding process.
+     * Special case: if len = 0, an empty array is returned. Still,
+     * if you need more speed and reduced memory footprint (and aren't
+     * gzipping), consider this method.
+     *
+     * @param source The Base64 encoded data
+     * @return decoded data
+     * @since 2.3.1
+     */
+    public static byte[] decode(byte[] source)
+            throws java.io.IOException
+    {
+        byte[] decoded = null;
+//        try {
+        decoded = decode(source, 0, source.length, Base64.NO_OPTIONS);
+//        } catch( java.io.IOException ex ) {
+//            assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
+//        }
+        return decoded;
+    }
+
+
+    /**
+     * Low-level access to decoding ASCII characters in
+     * the form of a byte array. <strong>Ignores GUNZIP option, if
+     * it's set.</strong> This is not generally a recommended method,
+     * although it is used internally as part of the decoding process.
+     * Special case: if len = 0, an empty array is returned. Still,
+     * if you need more speed and reduced memory footprint (and aren't
+     * gzipping), consider this method.
+     *
+     * @param source  The Base64 encoded data
+     * @param off     The offset of where to begin decoding
+     * @param len     The length of characters to decode
+     * @param options Can specify options such as alphabet type to use
+     * @return decoded data
+     * @throws java.io.IOException If bogus characters exist in source data
+     * @since 1.3
+     */
+    public static byte[] decode(byte[] source, int off, int len, int options)
+            throws java.io.IOException
+    {
+
+        // Lots of error checking and exception throwing
+        if (source == null)
+        {
+            throw new NullPointerException("Cannot decode null source array.");
+        }   // end if
+        if (off < 0 || off + len > source.length)
+        {
+            throw new IllegalArgumentException(String.format(
+                    "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len));
+        }   // end if
+
+        if (len == 0)
+        {
+            return new byte[0];
+        }
+        else if (len < 4)
+        {
+            throw new IllegalArgumentException(
+                    "Base64-encoded string must have at least four characters, but length specified was " + len);
+        }   // end if
+
+        byte[] DECODABET = getDecodabet(options);
+
+        int len34 = len * 3 / 4;       // Estimate on array size
+        byte[] outBuff = new byte[len34]; // Upper limit on size of output
+        int outBuffPosn = 0;             // Keep track of where we're writing
+
+        byte[] b4 = new byte[4];     // Four byte buffer from source, eliminating white space
+        int b4Posn = 0;               // Keep track of four byte input buffer
+        int i = 0;               // Source array counter
+        byte sbiDecode = 0;               // Special value from DECODABET
+
+        for (i = off; i < off + len; i++)
+        {  // Loop through source
+
+            sbiDecode = DECODABET[source[i] & 0xFF];
+
+            // White space, Equals sign, or legit Base64 character
+            // Note the values such as -5 and -9 in the
+            // DECODABETs at the top of the file.
+            if (sbiDecode >= WHITE_SPACE_ENC)
+            {
+                if (sbiDecode >= EQUALS_SIGN_ENC)
+                {
+                    b4[b4Posn++] = source[i];         // Save non-whitespace
+                    if (b4Posn > 3)
+                    {                  // Time to decode?
+                        outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);
+                        b4Posn = 0;
+
+                        // If that was the equals sign, break out of 'for' loop
+                        if (source[i] == EQUALS_SIGN)
+                        {
+                            break;
+                        }   // end if: equals sign
+                    }   // end if: quartet built
+                }   // end if: equals sign or better
+            }   // end if: white space, equals sign or better
+            else
+            {
+                // There's a bad input character in the Base64 stream.
+                throw new java.io.IOException(String.format(
+                        "Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i));
+            }   // end else:
+        }   // each input character
+
+        byte[] out = new byte[outBuffPosn];
+        System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
+        return out;
+    }   // end decode
+
+
+    /**
+     * Decodes data from Base64 notation, automatically
+     * detecting gzip-compressed data and decompressing it.
+     *
+     * @param s the string to decode
+     * @return the decoded data
+     * @throws java.io.IOException If there is a problem
+     * @since 1.4
+     */
+    public static byte[] decode(String s) throws java.io.IOException
+    {
+        return decode(s, NO_OPTIONS);
+    }
+
+
+    /**
+     * Decodes data from Base64 notation, automatically
+     * detecting gzip-compressed data and decompressing it.
+     *
+     * @param s       the string to decode
+     * @param options encode options such as URL_SAFE
+     * @return the decoded data
+     * @throws java.io.IOException  if there is an error
+     * @throws NullPointerException if <tt>s</tt> is null
+     * @since 1.4
+     */
+    public static byte[] decode(String s, int options) throws java.io.IOException
+    {
+
+        if (s == null)
+        {
+            throw new NullPointerException("Input string was null.");
+        }   // end if
+
+        byte[] bytes;
+        try
+        {
+            bytes = s.getBytes(PREFERRED_ENCODING);
+        }   // end try
+        catch (java.io.UnsupportedEncodingException uee)
+        {
+            bytes = s.getBytes();
+        }   // end catch
+        //</change>
+
+        // Decode
+        bytes = decode(bytes, 0, bytes.length, options);
+
+        // Check to see if it's gzip-compressed
+        // GZIP Magic Two-Byte Number: 0x8b1f (35615)
+        boolean dontGunzip = (options & DONT_GUNZIP) != 0;
+        if ((bytes != null) && (bytes.length >= 4) && (!dontGunzip))
+        {
+
+            int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
+            if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head)
+            {
+                java.io.ByteArrayInputStream bais = null;
+                java.util.zip.GZIPInputStream gzis = null;
+                java.io.ByteArrayOutputStream baos = null;
+                byte[] buffer = new byte[2048];
+                int length = 0;
+
+                try
+                {
+                    baos = new java.io.ByteArrayOutputStream();
+                    bais = new java.io.ByteArrayInputStream(bytes);
+                    gzis = new java.util.zip.GZIPInputStream(bais);
+
+                    while ((length = gzis.read(buffer)) >= 0)
+                    {
+                        baos.write(buffer, 0, length);
+                    }   // end while: reading input
+
+                    // No error? Get new bytes.
+                    bytes = baos.toByteArray();
+
+                }   // end try
+                catch (java.io.IOException e)
+                {
+                    e.printStackTrace();
+                    // Just return originally-decoded bytes
+                }   // end catch
+                finally
+                {
+                    try
+                    { baos.close(); }
+                    catch (Exception e)
+                    {}
+                    try
+                    { gzis.close(); }
+                    catch (Exception e)
+                    {}
+                    try
+                    { bais.close(); }
+                    catch (Exception e)
+                    {}
+                }   // end finally
+
+            }   // end if: gzipped
+        }   // end if: bytes.length >= 2
+
+        return bytes;
+    }   // end decode
+
+
+    /**
+     * Attempts to decode Base64 data and deserialize a Java
+     * Object within. Returns <tt>null</tt> if there was an error.
+     *
+     * @param encodedObject The Base64 data to decode
+     * @return The decoded and deserialized object
+     * @throws NullPointerException   if encodedObject is null
+     * @throws java.io.IOException    if there is a general error
+     * @throws ClassNotFoundException if the decoded object is of a
+     *                                class that cannot be found by the JVM
+     * @since 1.5
+     */
+    public static Object decodeToObject(String encodedObject)
+            throws java.io.IOException, java.lang.ClassNotFoundException
+    {
+        return decodeToObject(encodedObject, NO_OPTIONS, null);
+    }
+
+
+    /**
+     * Attempts to decode Base64 data and deserialize a Java
+     * Object within. Returns <tt>null</tt> if there was an error.
+     * If <tt>loader</tt> is not null, it will be the class loader
+     * used when deserializing.
+     *
+     * @param encodedObject The Base64 data to decode
+     * @param options       Various parameters related to decoding
+     * @param loader        Optional class loader to use in deserializing classes.
+     * @return The decoded and deserialized object
+     * @throws NullPointerException   if encodedObject is null
+     * @throws java.io.IOException    if there is a general error
+     * @throws ClassNotFoundException if the decoded object is of a
+     *                                class that cannot be found by the JVM
+     * @since 2.3.4
+     */
+    public static Object decodeToObject(
+            String encodedObject, int options, final ClassLoader loader)
+            throws java.io.IOException, java.lang.ClassNotFoundException
+    {
+
+        // Decode and gunzip if necessary
+        byte[] objBytes = decode(encodedObject, options);
+
+        java.io.ByteArrayInputStream bais = null;
+        java.io.ObjectInputStream ois = null;
+        Object obj = null;
+
+        try
+        {
+            bais = new java.io.ByteArrayInputStream(objBytes);
+
+            // If no custom class loader is provided, use Java's builtin OIS.
+            if (loader == null)
+            {
+                ois = new java.io.ObjectInputStream(bais);
+            }   // end if: no loader provided
+
+            // Else make a customized object input stream that uses
+            // the provided class loader.
+            else
+            {
+                ois = new java.io.ObjectInputStream(bais)
+                {
+                    @Override
+                    public Class<?> resolveClass(java.io.ObjectStreamClass streamClass)
+                            throws java.io.IOException, ClassNotFoundException
+                    {
+                        Class c = Class.forName(streamClass.getName(), false, loader);
+                        if (c == null)
+                        {
+                            return super.resolveClass(streamClass);
+                        }
+                        else
+                        {
+                            return c;   // Class loader knows of this class.
+                        }   // end else: not null
+                    }   // end resolveClass
+                };  // end ois
+            }   // end else: no custom class loader
+
+            obj = ois.readObject();
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e;    // Catch and throw in order to execute finally{}
+        }   // end catch
+        catch (java.lang.ClassNotFoundException e)
+        {
+            throw e;    // Catch and throw in order to execute finally{}
+        }   // end catch
+        finally
+        {
+            try
+            { bais.close(); }
+            catch (Exception e)
+            {}
+            try
+            { ois.close(); }
+            catch (Exception e)
+            {}
+        }   // end finally
+
+        return obj;
+    }   // end decodeObject
+
+
+    /**
+     * Convenience method for encoding data to a file.
+     * <p/>
+     * <p>As of v 2.3, if there is a error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned false, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param dataToEncode byte array of data to encode in base64 form
+     * @param filename     Filename for saving encoded data
+     * @throws java.io.IOException  if there is an error
+     * @throws NullPointerException if dataToEncode is null
+     * @since 2.1
+     */
+    public static void encodeToFile(byte[] dataToEncode, String filename)
+            throws java.io.IOException
+    {
+
+        if (dataToEncode == null)
+        {
+            throw new NullPointerException("Data to encode was null.");
+        }   // end iff
+
+        Base64.OutputStream bos = null;
+        try
+        {
+            bos = new Base64.OutputStream(
+                    new java.io.FileOutputStream(filename), Base64.ENCODE);
+            bos.write(dataToEncode);
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e; // Catch and throw to execute finally{} block
+        }   // end catch: java.io.IOException
+        finally
+        {
+            try
+            { bos.close(); }
+            catch (Exception e)
+            {}
+        }   // end finally
+
+    }   // end encodeToFile
+
+
+    /**
+     * Convenience method for decoding data to a file.
+     * <p/>
+     * <p>As of v 2.3, if there is a error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned false, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param dataToDecode Base64-encoded data as a string
+     * @param filename     Filename for saving decoded data
+     * @throws java.io.IOException if there is an error
+     * @since 2.1
+     */
+    public static void decodeToFile(String dataToDecode, String filename)
+            throws java.io.IOException
+    {
+
+        Base64.OutputStream bos = null;
+        try
+        {
+            bos = new Base64.OutputStream(
+                    new java.io.FileOutputStream(filename), Base64.DECODE);
+            bos.write(dataToDecode.getBytes(PREFERRED_ENCODING));
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e; // Catch and throw to execute finally{} block
+        }   // end catch: java.io.IOException
+        finally
+        {
+            try
+            { bos.close(); }
+            catch (Exception e)
+            {}
+        }   // end finally
+
+    }   // end decodeToFile
+
+
+    /**
+     * Convenience method for reading a base64-encoded
+     * file and decoding it.
+     * <p/>
+     * <p>As of v 2.3, if there is a error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned false, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param filename Filename for reading encoded data
+     * @return decoded byte array
+     * @throws java.io.IOException if there is an error
+     * @since 2.1
+     */
+    public static byte[] decodeFromFile(String filename)
+            throws java.io.IOException
+    {
+
+        byte[] decodedData = null;
+        Base64.InputStream bis = null;
+        try
+        {
+            // Set up some useful variables
+            java.io.File file = new java.io.File(filename);
+            byte[] buffer = null;
+            int length = 0;
+            int numBytes = 0;
+
+            // Check for size of file
+            if (file.length() > Integer.MAX_VALUE)
+            {
+                throw new java.io.IOException("File is too big for this convenience method (" + file.length() + " bytes).");
+            }   // end if: file too big for int index
+            buffer = new byte[(int) file.length()];
+
+            // Open a stream
+            bis = new Base64.InputStream(
+                    new java.io.BufferedInputStream(
+                            new java.io.FileInputStream(file)), Base64.DECODE);
+
+            // Read until done
+            while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
+            {
+                length += numBytes;
+            }   // end while
+
+            // Save in a variable to return
+            decodedData = new byte[length];
+            System.arraycopy(buffer, 0, decodedData, 0, length);
+
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e; // Catch and release to execute finally{}
+        }   // end catch: java.io.IOException
+        finally
+        {
+            try
+            { bis.close(); }
+            catch (Exception e)
+            {}
+        }   // end finally
+
+        return decodedData;
+    }   // end decodeFromFile
+
+
+    /**
+     * Convenience method for reading a binary file
+     * and base64-encoding it.
+     * <p/>
+     * <p>As of v 2.3, if there is a error,
+     * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
+     * In earlier versions, it just returned false, but
+     * in retrospect that's a pretty poor way to handle it.</p>
+     *
+     * @param filename Filename for reading binary data
+     * @return base64-encoded string
+     * @throws java.io.IOException if there is an error
+     * @since 2.1
+     */
+    public static String encodeFromFile(String filename)
+            throws java.io.IOException
+    {
+
+        String encodedData = null;
+        Base64.InputStream bis = null;
+        try
+        {
+            // Set up some useful variables
+            java.io.File file = new java.io.File(filename);
+            byte[] buffer = new byte[Math.max((int) (file.length() * 1.4 + 1), 40)]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5)
+            int length = 0;
+            int numBytes = 0;
+
+            // Open a stream
+            bis = new Base64.InputStream(
+                    new java.io.BufferedInputStream(
+                            new java.io.FileInputStream(file)), Base64.ENCODE);
+
+            // Read until done
+            while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
+            {
+                length += numBytes;
+            }   // end while
+
+            // Save in a variable to return
+            encodedData = new String(buffer, 0, length, Base64.PREFERRED_ENCODING);
+
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e; // Catch and release to execute finally{}
+        }   // end catch: java.io.IOException
+        finally
+        {
+            try
+            { bis.close(); }
+            catch (Exception e)
+            {}
+        }   // end finally
+
+        return encodedData;
+    }   // end encodeFromFile
+
+    /**
+     * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
+     *
+     * @param infile  Input file
+     * @param outfile Output file
+     * @throws java.io.IOException if there is an error
+     * @since 2.2
+     */
+    public static void encodeFileToFile(String infile, String outfile)
+            throws java.io.IOException
+    {
+
+        String encoded = Base64.encodeFromFile(infile);
+        java.io.OutputStream out = null;
+        try
+        {
+            out = new java.io.BufferedOutputStream(
+                    new java.io.FileOutputStream(outfile));
+            out.write(encoded.getBytes("US-ASCII")); // Strict, 7-bit output.
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e; // Catch and release to execute finally{}
+        }   // end catch
+        finally
+        {
+            try
+            { out.close(); }
+            catch (Exception ex)
+            {}
+        }   // end finally
+    }   // end encodeFileToFile
+
+
+    /**
+     * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
+     *
+     * @param infile  Input file
+     * @param outfile Output file
+     * @throws java.io.IOException if there is an error
+     * @since 2.2
+     */
+    public static void decodeFileToFile(String infile, String outfile)
+            throws java.io.IOException
+    {
+
+        byte[] decoded = Base64.decodeFromFile(infile);
+        java.io.OutputStream out = null;
+        try
+        {
+            out = new java.io.BufferedOutputStream(
+                    new java.io.FileOutputStream(outfile));
+            out.write(decoded);
+        }   // end try
+        catch (java.io.IOException e)
+        {
+            throw e; // Catch and release to execute finally{}
+        }   // end catch
+        finally
+        {
+            try
+            { out.close(); }
+            catch (Exception ex)
+            {}
+        }   // end finally
+    }   // end decodeFileToFile
+
+
+   /* ********  I N N E R   C L A S S   I N P U T S T R E A M  ******** */
+
+
+    /**
+     * A {@link Base64.InputStream} will read data from another
+     * <tt>java.io.InputStream</tt>, given in the constructor,
+     * and encode/decode to/from Base64 notation on the fly.
+     *
+     * @see Base64
+     * @since 1.3
+     */
+    public static class InputStream extends java.io.FilterInputStream
+    {
+
+        private boolean encode;         // Encoding or decoding
+        private int position;       // Current position in the buffer
+        private byte[] buffer;         // Small buffer holding converted data
+        private int bufferLength;   // Length of buffer (3 or 4)
+        private int numSigBytes;    // Number of meaningful bytes in the buffer
+        private int lineLength;
+        private boolean breakLines;     // Break lines at less than 80 characters
+        private int options;        // Record options used to create the stream.
+        private byte[] decodabet;      // Local copies to avoid extra method calls
+
+
+        /**
+         * Constructs a {@link Base64.InputStream} in DECODE mode.
+         *
+         * @param in the <tt>java.io.InputStream</tt> from which to read data.
+         * @since 1.3
+         */
+        public InputStream(java.io.InputStream in)
+        {
+            this(in, DECODE);
+        }   // end constructor
+
+
+        /**
+         * Constructs a {@link Base64.InputStream} in
+         * either ENCODE or DECODE mode.
+         * <p/>
+         * Valid options:<pre>
+         *   ENCODE or DECODE: Encode or Decode as data is read.
+         *   DO_BREAK_LINES: break lines at 76 characters
+         *     (only meaningful when encoding)</i>
+         * </pre>
+         * <p/>
+         * Example: <code>new Base64.InputStream( in, Base64.DECODE )</code>
+         *
+         * @param in      the <tt>java.io.InputStream</tt> from which to read data.
+         * @param options Specified options
+         * @see Base64#ENCODE
+         * @see Base64#DECODE
+         * @see Base64#DO_BREAK_LINES
+         * @since 2.0
+         */
+        public InputStream(java.io.InputStream in, int options)
+        {
+
+            super(in);
+            this.options = options; // Record for later
+            this.breakLines = (options & DO_BREAK_LINES) > 0;
+            this.encode = (options & ENCODE) > 0;
+            this.bufferLength = encode ? 4 : 3;
+            this.buffer = new byte[bufferLength];
+            this.position = -1;
+            this.lineLength = 0;
+            this.decodabet = getDecodabet(options);
+        }   // end constructor
+
+        /**
+         * Reads enough of the input stream to convert
+         * to/from Base64 and returns the next byte.
+         *
+         * @return next byte
+         * @since 1.3
+         */
+        @Override
+        public int read() throws java.io.IOException
+        {
+
+            // Do we need to get data?
+            if (position < 0)
+            {
+                if (encode)
+                {
+                    byte[] b3 = new byte[3];
+                    int numBinaryBytes = 0;
+                    for (int i = 0; i < 3; i++)
+                    {
+                        int b = in.read();
+
+                        // If end of stream, b is -1.
+                        if (b >= 0)
+                        {
+                            b3[i] = (byte) b;
+                            numBinaryBytes++;
+                        }
+                        else
+                        {
+                            break; // out of for loop
+                        }   // end else: end of stream
+
+                    }   // end for: each needed input byte
+
+                    if (numBinaryBytes > 0)
+                    {
+                        encode3to4(b3, 0, numBinaryBytes, buffer, 0, options);
+                        position = 0;
+                        numSigBytes = 4;
+                    }   // end if: got data
+                    else
+                    {
+                        return -1;  // Must be end of stream
+                    }   // end else
+                }   // end if: encoding
+
+                // Else decoding
+                else
+                {
+                    byte[] b4 = new byte[4];
+                    int i = 0;
+                    for (i = 0; i < 4; i++)
+                    {
+                        // Read four "meaningful" bytes:
+                        int b = 0;
+                        do
+                        { b = in.read(); }
+                        while (b >= 0 && decodabet[b & 0x7f] <= WHITE_SPACE_ENC);
+
+                        if (b < 0)
+                        {
+                            break; // Reads a -1 if end of stream
+                        }   // end if: end of stream
+
+                        b4[i] = (byte) b;
+                    }   // end for: each needed input byte
+
+                    if (i == 4)
+                    {
+                        numSigBytes = decode4to3(b4, 0, buffer, 0, options);
+                        position = 0;
+                    }   // end if: got four characters
+                    else if (i == 0)
+                    {
+                        return -1;
+                    }   // end else if: also padded correctly
+                    else
+                    {
+                        // Must have broken out from above.
+                        throw new java.io.IOException("Improperly padded Base64 input.");
+                    }   // end
+
+                }   // end else: decode
+            }   // end else: get data
+
+            // Got data?
+            if (position >= 0)
+            {
+                // End of relevant data?
+                if ( /*!encode &&*/ position >= numSigBytes)
+                {
+                    return -1;
+                }   // end if: got data
+
+                if (encode && breakLines && lineLength >= MAX_LINE_LENGTH)
+                {
+                    lineLength = 0;
+                    return '\n';
+                }   // end if
+                else
+                {
+                    lineLength++;   // This isn't important when decoding
+                    // but throwing an extra "if" seems
+                    // just as wasteful.
+
+                    int b = buffer[position++];
+
+                    if (position >= bufferLength)
+                    {
+                        position = -1;
+                    }   // end if: end
+
+                    return b & 0xFF; // This is how you "cast" a byte that's
+                    // intended to be unsigned.
+                }   // end else
+            }   // end if: position >= 0
+
+            // Else error
+            else
+            {
+                throw new java.io.IOException("Error in Base64 code reading stream.");
+            }   // end else
+        }   // end read
+
+
+        /**
+         * Calls {@link #read()} repeatedly until the end of stream
+         * is reached or <var>len</var> bytes are read.
+         * Returns number of bytes read into array or -1 if
+         * end of stream is encountered.
+         *
+         * @param dest array to hold values
+         * @param off  offset for array
+         * @param len  max number of bytes to read into array
+         * @return bytes read into array or -1 if end of stream is encountered.
+         * @since 1.3
+         */
+        @Override
+        public int read(byte[] dest, int off, int len)
+                throws java.io.IOException
+        {
+            int i;
+            int b;
+            for (i = 0; i < len; i++)
+            {
+                b = read();
+
+                if (b >= 0)
+                {
+                    dest[off + i] = (byte) b;
+                }
+                else if (i == 0)
+                {
+                    return -1;
+                }
+                else
+                {
+                    break; // Out of 'for' loop
+                } // Out of 'for' loop
+            }   // end for: each byte read
+            return i;
+        }   // end read
+
+    }   // end inner class InputStream
+
+
+   /* ********  I N N E R   C L A S S   O U T P U T S T R E A M  ******** */
+
+
+    /**
+     * A {@link Base64.OutputStream} will write data to another
+     * <tt>java.io.OutputStream</tt>, given in the constructor,
+     * and encode/decode to/from Base64 notation on the fly.
+     *
+     * @see Base64
+     * @since 1.3
+     */
+    public static class OutputStream extends java.io.FilterOutputStream
+    {
+
+        private boolean encode;
+        private int position;
+        private byte[] buffer;
+        private int bufferLength;
+        private int lineLength;
+        private boolean breakLines;
+        private byte[] b4;         // Scratch used in a few places
+        private boolean suspendEncoding;
+        private int options;    // Record for later
+        private byte[] decodabet;  // Local copies to avoid extra method calls
+
+        /**
+         * Constructs a {@link Base64.OutputStream} in ENCODE mode.
+         *
+         * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
+         * @since 1.3
+         */
+        public OutputStream(java.io.OutputStream out)
+        {
+            this(out, ENCODE);
+        }   // end constructor
+
+
+        /**
+         * Constructs a {@link Base64.OutputStream} in
+         * either ENCODE or DECODE mode.
+         * <p/>
+         * Valid options:<pre>
+         *   ENCODE or DECODE: Encode or Decode as data is read.
+         *   DO_BREAK_LINES: don't break lines at 76 characters
+         *     (only meaningful when encoding)</i>
+         * </pre>
+         * <p/>
+         * Example: <code>new Base64.OutputStream( out, Base64.ENCODE )</code>
+         *
+         * @param out     the <tt>java.io.OutputStream</tt> to which data will be written.
+         * @param options Specified options.
+         * @see Base64#ENCODE
+         * @see Base64#DECODE
+         * @see Base64#DO_BREAK_LINES
+         * @since 1.3
+         */
+        public OutputStream(java.io.OutputStream out, int options)
+        {
+            super(out);
+            this.breakLines = (options & DO_BREAK_LINES) != 0;
+            this.encode = (options & ENCODE) != 0;
+            this.bufferLength = encode ? 3 : 4;
+            this.buffer = new byte[bufferLength];
+            this.position = 0;
+            this.lineLength = 0;
+            this.suspendEncoding = false;
+            this.b4 = new byte[4];
+            this.options = options;
+            this.decodabet = getDecodabet(options);
+        }   // end constructor
+
+
+        /**
+         * Writes the byte to the output stream after
+         * converting to/from Base64 notation.
+         * When encoding, bytes are buffered three
+         * at a time before the output stream actually
+         * gets a write() call.
+         * When decoding, bytes are buffered four
+         * at a time.
+         *
+         * @param theByte the byte to write
+         * @since 1.3
+         */
+        @Override
+        public void write(int theByte)
+                throws java.io.IOException
+        {
+            // Encoding suspended?
+            if (suspendEncoding)
+            {
+                this.out.write(theByte);
+                return;
+            }   // end if: supsended
+
+            // Encode?
+            if (encode)
+            {
+                buffer[position++] = (byte) theByte;
+                if (position >= bufferLength)
+                { // Enough to encode.
+
+                    this.out.write(encode3to4(b4, buffer, bufferLength, options));
+
+                    lineLength += 4;
+                    if (breakLines && lineLength >= MAX_LINE_LENGTH)
+                    {
+                        this.out.write(NEW_LINE);
+                        lineLength = 0;
+                    }   // end if: end of line
+
+                    position = 0;
+                }   // end if: enough to output
+            }   // end if: encoding
+
+            // Else, Decoding
+            else
+            {
+                // Meaningful Base64 character?
+                if (decodabet[theByte & 0x7f] > WHITE_SPACE_ENC)
+                {
+                    buffer[position++] = (byte) theByte;
+                    if (position >= bufferLength)
+                    { // Enough to output.
+
+                        int len = Base64.decode4to3(buffer, 0, b4, 0, options);
+                        out.write(b4, 0, len);
+                        position = 0;
+                    }   // end if: enough to output
+                }   // end if: meaningful base64 character
+                else if (decodabet[theByte & 0x7f] != WHITE_SPACE_ENC)
+                {
+                    throw new java.io.IOException("Invalid character in Base64 data.");
+                }   // end else: not white space either
+            }   // end else: decoding
+        }   // end write
+
+
+        /**
+         * Calls {@link #write(int)} repeatedly until <var>len</var>
+         * bytes are written.
+         *
+         * @param theBytes array from which to read bytes
+         * @param off      offset for array
+         * @param len      max number of bytes to read into array
+         * @since 1.3
+         */
+        @Override
+        public void write(byte[] theBytes, int off, int len)
+                throws java.io.IOException
+        {
+            // Encoding suspended?
+            if (suspendEncoding)
+            {
+                this.out.write(theBytes, off, len);
+                return;
+            }   // end if: supsended
+
+            for (int i = 0; i < len; i++)
+            {
+                write(theBytes[off + i]);
+            }   // end for: each byte written
+
+        }   // end write
+
+
+        /**
+         * Method added by PHIL. [Thanks, PHIL. -Rob]
+         * This pads the buffer without closing the stream.
+         *
+         * @throws java.io.IOException if there's an error.
+         */
+        public void flushBase64() throws java.io.IOException
+        {
+            if (position > 0)
+            {
+                if (encode)
+                {
+                    out.write(encode3to4(b4, buffer, position, options));
+                    position = 0;
+                }   // end if: encoding
+                else
+                {
+                    throw new java.io.IOException("Base64 input not properly padded.");
+                }   // end else: decoding
+            }   // end if: buffer partially full
+
+        }   // end flush
+
+
+        /**
+         * Flushes and closes (I think, in the superclass) the stream.
+         *
+         * @since 1.3
+         */
+        @Override
+        public void close() throws java.io.IOException
+        {
+            // 1. Ensure that pending characters are written
+            flushBase64();
+
+            // 2. Actually close the stream
+            // Base class both flushes and closes.
+            super.close();
+
+            buffer = null;
+            out = null;
+        }   // end close
+
+
+        /**
+         * Suspends encoding of the stream.
+         * May be helpful if you need to embed a piece of
+         * base64-encoded data in a stream.
+         *
+         * @throws java.io.IOException if there's an error flushing
+         * @since 1.5.1
+         */
+        public void suspendEncoding() throws java.io.IOException
+        {
+            flushBase64();
+            this.suspendEncoding = true;
+        }   // end suspendEncoding
+
+
+        /**
+         * Resumes encoding of the stream.
+         * May be helpful if you need to embed a piece of
+         * base64-encoded data in a stream.
+         *
+         * @since 1.5.1
+         */
+        public void resumeEncoding()
+        {
+            this.suspendEncoding = false;
+        }   // end resumeEncoding
+
+
+    }   // end inner class OutputStream
+
+
+}   // end class Base64
diff --git a/model/api/src/main/java/org/keycloak/models/utils/SHAPasswordEncoder.java b/model/api/src/main/java/org/keycloak/models/utils/SHAPasswordEncoder.java
new file mode 100755
index 0000000..a9fec22
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/utils/SHAPasswordEncoder.java
@@ -0,0 +1,58 @@
+package org.keycloak.models.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/**
+ * <p>
+ * Password that uses SHA to encode passwords. You can always change the SHA strength by specifying a valid
+ * integer when creating a new instance.
+ * </p>
+ * <p>Passwords are returned with a Base64 encoding.</p>
+ *
+ * @author <a href="mailto:psilva@redhat.com">Pedro Silva</a>
+ *
+ */
+public class SHAPasswordEncoder {
+
+    private int strength;
+
+    public SHAPasswordEncoder(int strength) {
+        this.strength = strength;
+    }
+
+    public String encode(String rawPassword) {
+        MessageDigest messageDigest = getMessageDigest();
+
+        String encodedPassword = null;
+
+        try {
+            byte[] digest = messageDigest.digest(rawPassword.getBytes("UTF-8"));
+            encodedPassword = Base64.encodeBytes(digest);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Credential could not be encoded");
+        }
+
+        return encodedPassword;
+    }
+
+    public boolean verify(String rawPassword, String encodedPassword) {
+        return encode(rawPassword).equals(encodedPassword);
+    }
+
+    protected final MessageDigest getMessageDigest() throws IllegalArgumentException {
+        String algorithm = "SHA-" + this.strength;
+
+        try {
+            return MessageDigest.getInstance(algorithm);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("invalid credential encoding algorithm");
+        }
+    }
+
+    public int getStrength() {
+        return this.strength;
+    }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/TimeBasedOTP.java b/model/api/src/main/java/org/keycloak/models/utils/TimeBasedOTP.java
new file mode 100755
index 0000000..d27718b
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/utils/TimeBasedOTP.java
@@ -0,0 +1,216 @@
+package org.keycloak.models.utils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.math.BigInteger;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * TOTP: Time-based One-time Password Algorithm Based on http://tools.ietf.org/html/draft-mraihi-totp-timebased-06
+ *
+ * @author anil saldhana
+ * @since Sep 20, 2010
+ */
+public class TimeBasedOTP {
+
+    public static final String HMAC_SHA1 = "HmacSHA1";
+    public static final String HMAC_SHA256 = "HmacSHA256";
+    public static final String HMAC_SHA512 = "HmacSHA512";
+
+    public static final String DEFAULT_ALGORITHM = HMAC_SHA1;
+    public static final int DEFAULT_NUMBER_DIGITS = 6;
+    public static final int DEFAULT_INTERVAL_SECONDS = 30;
+    public static final int DEFAULT_DELAY_WINDOW = 1;
+
+    // 0 1 2 3 4 5 6 7 8
+    private static final int[] DIGITS_POWER = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
+
+    private Clock clock;
+    private final String algorithm;
+    private final int numberDigits;
+    private final int delayWindow;
+
+    public TimeBasedOTP() {
+        this(DEFAULT_ALGORITHM, DEFAULT_NUMBER_DIGITS, DEFAULT_INTERVAL_SECONDS, DEFAULT_DELAY_WINDOW);
+    }
+
+    /**
+     * @param algorithm the encryption algorithm
+     * @param numberDigits the number of digits for tokens
+     * @param timeIntervalInSeconds the number of seconds a token is valid
+     * @param delayWindow the number of previous intervals that should be used to validate tokens.
+     */
+    public TimeBasedOTP(String algorithm, int numberDigits, int timeIntervalInSeconds, int delayWindow) {
+        this.algorithm = algorithm;
+        this.numberDigits = numberDigits;
+        this.clock = new Clock(timeIntervalInSeconds);
+        this.delayWindow = delayWindow;
+    }
+
+    /**
+     * <p>Generates a token.</p>
+     *
+     * @param secretKey the secret key to derive the token from.
+     */
+    public String generate(String secretKey) {
+        long T = this.clock.getCurrentInterval();
+
+        String steps = Long.toHexString(T).toUpperCase();
+
+        // Just get a 16 digit string
+        while (steps.length() < 16)
+            steps = "0" + steps;
+
+        return generateTOTP(secretKey, steps, this.numberDigits, this.algorithm);
+    }
+
+    /**
+     * This method generates an TOTP value for the given set of parameters.
+     *
+     * @param key          the shared secret, HEX encoded
+     * @param time         a value that reflects a time
+     * @param returnDigits number of digits to return
+     * @param crypto       the crypto function to use
+     * @return A numeric String in base 10 that includes {@link truncationDigits} digits
+     * @throws java.security.GeneralSecurityException
+     *
+     */
+    public String generateTOTP(String key, String time, int returnDigits, String crypto) {
+        String result = null;
+        byte[] hash;
+
+        // Using the counter
+        // First 8 bytes are for the movingFactor
+        // Complaint with base RFC 4226 (HOTP)
+        while (time.length() < 16)
+            time = "0" + time;
+
+        // Get the HEX in a Byte[]
+        byte[] msg = hexStr2Bytes(time);
+
+        // Adding one byte to get the right conversion
+        // byte[] k = hexStr2Bytes(key);
+        byte[] k = key.getBytes();
+
+        hash = hmac_sha1(crypto, k, msg);
+
+        // put selected bytes into result int
+        int offset = hash[hash.length - 1] & 0xf;
+
+        int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8)
+                | (hash[offset + 3] & 0xff);
+
+        int otp = binary % DIGITS_POWER[returnDigits];
+
+        result = Integer.toString(otp);
+
+        while (result.length() < returnDigits) {
+            result = "0" + result;
+        }
+        return result;
+    }
+
+    /**
+     * <p>Validates a token using a secret key.</p>
+     *
+     * @param token  OTP string to validate
+     * @param secret Shared secret
+     * @return
+     */
+    public boolean validate(String token, byte[] secret) {
+        long currentInterval = this.clock.getCurrentInterval();
+
+        for (int i = this.delayWindow; i >= 0; --i) {
+            String steps = Long.toHexString(currentInterval - i).toUpperCase();
+
+            // Just get a 16 digit string
+            while (steps.length() < 16)
+                steps = "0" + steps;
+
+            String candidate = generateTOTP(new String(secret), steps, this.numberDigits, this.algorithm);
+
+            if (candidate.equals(token)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public void setCalendar(Calendar calendar) {
+        this.clock.setCalendar(calendar);
+    }
+
+    /**
+     * This method uses the JCE to provide the crypto algorithm. HMAC computes a Hashed Message Authentication Code with the
+     * crypto hash algorithm as a parameter.
+     *
+     * @param crypto   the crypto algorithm (HmacSHA1, HmacSHA256, HmacSHA512)
+     * @param keyBytes the bytes to use for the HMAC key
+     * @param text     the message or text to be authenticated.
+     * @throws java.security.NoSuchAlgorithmException
+     *
+     * @throws java.security.InvalidKeyException
+     *
+     */
+    private byte[] hmac_sha1(String crypto, byte[] keyBytes, byte[] text) {
+        byte[] value;
+
+        try {
+            Mac hmac = Mac.getInstance(crypto);
+            SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
+
+            hmac.init(macKey);
+
+            value = hmac.doFinal(text);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return value;
+    }
+
+    /**
+     * This method converts HEX string to Byte[]
+     *
+     * @param hex the HEX string
+     * @return A byte array
+     */
+    private byte[] hexStr2Bytes(String hex) {
+        // Adding one byte to get the right conversion
+        // values starting with "0" can be converted
+        byte[] bArray = new BigInteger("10" + hex, 16).toByteArray();
+
+        // Copy all the REAL bytes, not the "first"
+        byte[] ret = new byte[bArray.length - 1];
+        for (int i = 0; i < ret.length; i++)
+            ret[i] = bArray[i + 1];
+        return ret;
+    }
+
+    private class Clock {
+
+        private final int interval;
+        private Calendar calendar;
+
+        public Clock(int interval) {
+            this.interval = interval;
+        }
+
+        public long getCurrentInterval() {
+            Calendar currentCalendar = this.calendar;
+
+            if (currentCalendar == null) {
+                currentCalendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
+            }
+
+            return (currentCalendar.getTimeInMillis() / 1000) / this.interval;
+        }
+
+        public void setCalendar(Calendar calendar) {
+            this.calendar = calendar;
+        }
+    }
+}
\ No newline at end of file
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
new file mode 100755
index 0000000..00ed540
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
@@ -0,0 +1,332 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity;
+import org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity;
+import org.keycloak.models.jpa.entities.RoleEntity;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ApplicationAdapter implements ApplicationModel {
+
+    protected EntityManager em;
+    protected ApplicationEntity application;
+
+    public ApplicationAdapter(EntityManager em, ApplicationEntity application) {
+        this.em = em;
+        this.application = application;
+    }
+
+    @Override
+    public void updateApplication() {
+        em.flush();
+    }
+
+    @Override
+    public UserModel getApplicationUser() {
+        return new UserAdapter(application.getApplicationUser());
+    }
+
+    @Override
+    public String getId() {
+        return application.getId();
+    }
+
+    @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 String getBaseUrl() {
+        return null;
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+    }
+
+    @Override
+    public RoleModel getRole(String name) {
+        Collection<RoleEntity> roles = application.getRoles();
+        if (roles == null) return null;
+        for (RoleEntity role : roles) {
+            if (role.getName().equals(name)) {
+                return new RoleAdapter(role);
+            }
+        }
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public RoleModel addRole(String name) {
+        RoleModel role = getRole(name);
+        if (role != null) return role;
+        RoleEntity entity = new RoleEntity();
+        entity.setName(name);
+        em.persist(entity);
+        application.getRoles().add(entity);
+        em.flush();
+        return new RoleAdapter(entity);
+    }
+
+    @Override
+    public List<RoleModel> getRoles() {
+        ArrayList<RoleModel> list = new ArrayList<RoleModel>();
+        Collection<RoleEntity> roles = application.getRoles();
+        if (roles == null) return list;
+        for (RoleEntity entity : roles) {
+            list.add(new RoleAdapter(entity));
+        }
+        return list;
+    }
+
+    @Override
+    public RoleModel getRoleById(String id) {
+        RoleEntity entity = em.find(RoleEntity.class, id);
+        if (entity == null) return null;
+        return new RoleAdapter(entity);
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, RoleModel role) {
+        TypedQuery<ApplicationUserRoleMappingEntity> query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
+        return query.getResultList().size() > 0;
+    }
+
+    protected TypedQuery<ApplicationUserRoleMappingEntity> getApplicationUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) {
+        TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userHasApplicationRole", ApplicationUserRoleMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("role", ((RoleAdapter)role).getRole());
+        query.setParameter("application", application);
+        return query;
+    }
+
+    @Override
+    public void grantRole(UserModel user, RoleModel role) {
+        if (hasRole(user, role)) return;
+        ApplicationUserRoleMappingEntity entity = new ApplicationUserRoleMappingEntity();
+        entity.setApplication(application);
+        entity.setUser(((UserAdapter) user).getUser());
+        entity.setRole(((RoleAdapter)role).getRole());
+        em.persist(entity);
+        em.flush();
+    }
+
+    @Override
+    public List<RoleModel> getRoleMappings(UserModel user) {
+        TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("application", application);
+        List<ApplicationUserRoleMappingEntity> entities = query.getResultList();
+        List<RoleModel> roles = new ArrayList<RoleModel>();
+        for (ApplicationUserRoleMappingEntity entity : entities) {
+            roles.add(new RoleAdapter(entity.getRole()));
+        }
+        return roles;
+    }
+
+    @Override
+    public Set<String> getRoleMappingValues(UserModel user) {
+        TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("application", application);
+        List<ApplicationUserRoleMappingEntity> entities = query.getResultList();
+        Set<String> roles = new HashSet<String>();
+        for (ApplicationUserRoleMappingEntity entity : entities) {
+            roles.add(entity.getRole().getName());
+        }
+        return roles;
+    }
+
+    @Override
+    public void deleteRoleMapping(UserModel user, RoleModel role) {
+        TypedQuery<ApplicationUserRoleMappingEntity> query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
+        List<ApplicationUserRoleMappingEntity> results = query.getResultList();
+        if (results.size() == 0) return;
+        for (ApplicationUserRoleMappingEntity entity : results) {
+            em.remove(entity);
+        }
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, String roleName) {
+        RoleModel role = getRole(roleName);
+        if (role == null) return false;
+        return hasRole(user, role);
+    }
+
+    @Override
+    public void addScopeMapping(UserModel agent, String roleName) {
+        RoleModel role = getRole(roleName);
+        if (role == null) throw new RuntimeException("role does not exist");
+        addScopeMapping(agent, role);
+    }
+
+    @Override
+    public Set<String> getScopeMappingValues(UserModel agent) {
+        TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)agent).getUser());
+        query.setParameter("application", application);
+        List<ApplicationScopeMappingEntity> entities = query.getResultList();
+        Set<String> roles = new HashSet<String>();
+        for (ApplicationScopeMappingEntity entity : entities) {
+            roles.add(entity.getRole().getName());
+        }
+        return roles;
+    }
+
+    @Override
+    public List<RoleModel> getScopeMappings(UserModel agent) {
+        TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)agent).getUser());
+        query.setParameter("application", application);
+        List<ApplicationScopeMappingEntity> entities = query.getResultList();
+        List<RoleModel> roles = new ArrayList<RoleModel>();
+        for (ApplicationScopeMappingEntity entity : entities) {
+            roles.add(new RoleAdapter(entity.getRole()));
+        }
+        return roles;
+    }
+
+    @Override
+    public void addScopeMapping(UserModel agent, RoleModel role) {
+        if (hasScope(agent, role)) return;
+        ApplicationScopeMappingEntity entity = new ApplicationScopeMappingEntity();
+        entity.setApplication(application);
+        entity.setUser(((UserAdapter) agent).getUser());
+        entity.setRole(((RoleAdapter)role).getRole());
+        em.persist(entity);
+        em.flush();
+    }
+
+    @Override
+    public void deleteScopeMapping(UserModel user, RoleModel role) {
+        TypedQuery<ApplicationScopeMappingEntity> query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
+        List<ApplicationScopeMappingEntity> results = query.getResultList();
+        if (results.size() == 0) return;
+        for (ApplicationScopeMappingEntity entity : results) {
+            em.remove(entity);
+        }
+    }
+
+    public boolean hasScope(UserModel user, RoleModel role) {
+        TypedQuery<ApplicationScopeMappingEntity> query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
+        return query.getResultList().size() > 0;
+    }
+
+
+    protected TypedQuery<ApplicationScopeMappingEntity> getApplicationScopeMappingQuery(UserAdapter user, RoleAdapter role) {
+        TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userHasApplicationScope", ApplicationScopeMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("role", ((RoleAdapter)role).getRole());
+        query.setParameter("application", application);
+        return query;
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        Collection<RoleEntity> entities = application.getDefaultRoles();
+        List<String> roles = new ArrayList<String>();
+        if (entities == null) return roles;
+        for (RoleEntity entity : entities) {
+            roles.add(entity.getName());
+        }
+        return roles;
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        RoleModel role = getRole(name);
+        if (role == null) {
+            role = addRole(name);
+        }
+        Collection<RoleEntity> entities = application.getDefaultRoles();
+        for (RoleEntity entity : entities) {
+            if (entity.getId().equals(role.getId())) {
+                return;
+            }
+        }
+        entities.add(((RoleAdapter) role).getRole());
+        em.flush();
+    }
+
+    public static boolean contains(String str, String[] array) {
+        for (String s : array) {
+            if (str.equals(s)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        Collection<RoleEntity> entities = application.getDefaultRoles();
+        Set<String> already = new HashSet<String>();
+        List<RoleEntity> remove = new ArrayList<RoleEntity>();
+        for (RoleEntity rel : entities) {
+            if (!contains(rel.getName(), defaultRoles)) {
+                remove.add(rel);
+            } else {
+                already.add(rel.getName());
+            }
+        }
+        for (RoleEntity entity : remove) {
+            entities.remove(entity);
+        }
+        em.flush();
+        for (String roleName : defaultRoles) {
+            if (!already.contains(roleName)) {
+                addDefaultRole(roleName);
+            }
+        }
+        em.flush();
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationScopeMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationScopeMappingEntity.java
new file mode 100755
index 0000000..557c65d
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationScopeMappingEntity.java
@@ -0,0 +1,29 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@NamedQueries({
+        @NamedQuery(name="userHasApplicationScope", query="select m from ApplicationScopeMappingEntity m where m.user = :user and m.role = :role and m.application = :application"),
+        @NamedQuery(name="userApplicationScopeMappings", query="select m from ApplicationScopeMappingEntity m where m.user = :user and m.application = :application")
+})
+@Entity
+public class ApplicationScopeMappingEntity extends UserRoleMappingEntity {
+
+    @ManyToOne
+    protected ApplicationEntity application;
+
+    public ApplicationEntity getApplication() {
+        return application;
+    }
+
+    public void setApplication(ApplicationEntity application) {
+        this.application = application;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java
new file mode 100755
index 0000000..2b2461d
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java
@@ -0,0 +1,29 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@NamedQueries({
+        @NamedQuery(name="userHasApplicationRole", query="select m from ApplicationUserRoleMappingEntity m where m.user = :user and m.role = :role and m.application = :application"),
+        @NamedQuery(name="userApplicationMappings", query="select m from ApplicationUserRoleMappingEntity m where m.user = :user and m.application = :application")
+})
+@Entity
+public class ApplicationUserRoleMappingEntity extends UserRoleMappingEntity {
+
+    @ManyToOne
+    protected ApplicationEntity application;
+
+    public ApplicationEntity getApplication() {
+        return application;
+    }
+
+    public void setApplication(ApplicationEntity application) {
+        this.application = application;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
new file mode 100755
index 0000000..4b13fd6
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
@@ -0,0 +1,69 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@NamedQueries({
+        @NamedQuery(name="credentialByUserAndType", query="select cred from CredentialEntity cred where cred.user = :user and cred.type = :type")
+})
+@Entity
+public class CredentialEntity {
+    @Id
+    @GeneratedValue
+    protected String id;
+
+    protected String type;
+    protected String value;
+    protected String device;
+
+    @ManyToOne
+    protected UserEntity user;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getDevice() {
+        return device;
+    }
+
+    public void setDevice(String device) {
+        this.device = device;
+    }
+
+    public UserEntity getUser() {
+        return user;
+    }
+
+    public void setUser(UserEntity user) {
+        this.user = user;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
new file mode 100755
index 0000000..28e158d
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
@@ -0,0 +1,62 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@NamedQueries({
+        @NamedQuery(name="findOAuthClientByUser", query="select o from OAuthClientEntity o where o.agent.loginName=:name and o.realm = :realm"),
+        @NamedQuery(name="findOAuthClientByRealm", query="select o from OAuthClientEntity o where o.realm = :realm")
+
+})
+@Entity
+public class OAuthClientEntity {
+    @Id
+    @GeneratedValue
+    private String id;
+
+    private String name;
+
+    @OneToOne(fetch = FetchType.EAGER)
+    private UserEntity agent;
+
+    @ManyToOne
+    protected RealmEntity realm;
+
+    public String getId() {
+        return id;
+    }
+
+    public UserEntity getAgent() {
+        return agent;
+    }
+
+    public void setAgent(UserEntity agent) {
+        this.agent = agent;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public RealmEntity getRealm() {
+        return realm;
+    }
+
+    public void setRealm(RealmEntity realm) {
+        this.realm = realm;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index 4a8ea65..d82c68e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -1,43 +1,272 @@
 package org.keycloak.models.jpa.entities;
 
 
-import javax.persistence.*;
+import javax.persistence.CascadeType;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinTable;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.OneToMany;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
+@Entity
 public class RealmEntity {
     @Id
     protected String id;
 
-    protected String realmName;
+    protected String name;
     protected boolean enabled;
     protected boolean sslNotRequired;
     protected boolean cookieLoginAllowed;
     protected boolean registrationAllowed;
+    protected boolean verifyEmail;
+    protected boolean resetPasswordAllowed;
+    protected boolean social;
+    protected boolean automaticRegistrationAfterSocialLogin;
+
     protected int tokenLifespan;
     protected int accessCodeLifespan;
+    protected int accessCodeLifespanUserAction;
+
     @Column(length = 2048)
     protected String publicKeyPem;
     @Column(length = 2048)
     protected String privateKeyPem;
-    protected String[] defaultRoles;
-    @Lob
-    protected HashMap<String, String> smtpConfig;
-    @Lob
-    protected HashMap<String, String> socialConfig;
 
     @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
-    Collection<RequiredCredentailEntity> requiredCredentials;
+    @JoinTable(name="USER_REQUIRED_CREDENTIALS")
+    Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
+
+    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
+    @JoinTable(name="APPLICATION_REQUIRED_CREDENTIALS")
+    Collection<RequiredCredentialEntity> requiredApplicationCredentials = new ArrayList<RequiredCredentialEntity>();
+
+    @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
+    @JoinTable(name="OAUTH_CLIENT_REQUIRED_CREDENTIALS")
+    Collection<RequiredCredentialEntity> requiredOAuthClientCredentials = new ArrayList<RequiredCredentialEntity>();
+
     @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
-    Collection<ResourceEntity> resources;
+    Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
+
     @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
-    Collection<RoleEntity> roles;
+    @JoinTable(name="REALM_ROLES")
+    Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
+
+    @ElementCollection
+    @MapKeyColumn(name="name")
+    @Column(name="value")
+    @CollectionTable
+    protected Map<String, String> smtpConfig = new HashMap<String, String>();
+
+    @ElementCollection
+    @MapKeyColumn(name="name")
+    @Column(name="value")
+    @CollectionTable
+    protected Map<String, String> socialConfig = new HashMap<String, String>();
+
+    @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
+    @JoinTable(name="REALM_DEFAULT_ROLES")
+    Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public boolean isSslNotRequired() {
+        return sslNotRequired;
+    }
+
+    public void setSslNotRequired(boolean sslNotRequired) {
+        this.sslNotRequired = sslNotRequired;
+    }
+
+    public boolean isCookieLoginAllowed() {
+        return cookieLoginAllowed;
+    }
+
+    public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
+        this.cookieLoginAllowed = cookieLoginAllowed;
+    }
+
+    public boolean isRegistrationAllowed() {
+        return registrationAllowed;
+    }
+
+    public void setRegistrationAllowed(boolean registrationAllowed) {
+        this.registrationAllowed = registrationAllowed;
+    }
+
+    public boolean isVerifyEmail() {
+        return verifyEmail;
+    }
+
+    public void setVerifyEmail(boolean verifyEmail) {
+        this.verifyEmail = verifyEmail;
+    }
+
+    public boolean isResetPasswordAllowed() {
+        return resetPasswordAllowed;
+    }
+
+    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+        this.resetPasswordAllowed = resetPasswordAllowed;
+    }
+
+    public boolean isSocial() {
+        return social;
+    }
+
+    public void setSocial(boolean social) {
+        this.social = social;
+    }
+
+    public boolean isAutomaticRegistrationAfterSocialLogin() {
+        return automaticRegistrationAfterSocialLogin;
+    }
+
+    public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
+        this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin;
+    }
+
+    public int getTokenLifespan() {
+        return tokenLifespan;
+    }
+
+    public void setTokenLifespan(int tokenLifespan) {
+        this.tokenLifespan = tokenLifespan;
+    }
+
+    public int getAccessCodeLifespan() {
+        return accessCodeLifespan;
+    }
+
+    public void setAccessCodeLifespan(int accessCodeLifespan) {
+        this.accessCodeLifespan = accessCodeLifespan;
+    }
+
+    public int getAccessCodeLifespanUserAction() {
+        return accessCodeLifespanUserAction;
+    }
+
+    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+        this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
+    }
+
+    public String getPublicKeyPem() {
+        return publicKeyPem;
+    }
+
+    public void setPublicKeyPem(String publicKeyPem) {
+        this.publicKeyPem = publicKeyPem;
+    }
+
+    public String getPrivateKeyPem() {
+        return privateKeyPem;
+    }
+
+    public void setPrivateKeyPem(String privateKeyPem) {
+        this.privateKeyPem = privateKeyPem;
+    }
+
+    public Collection<RequiredCredentialEntity> getRequiredCredentials() {
+        return requiredCredentials;
+    }
+
+    public void setRequiredCredentials(Collection<RequiredCredentialEntity> requiredCredentials) {
+        this.requiredCredentials = requiredCredentials;
+    }
+
+    public Collection<RequiredCredentialEntity> getRequiredApplicationCredentials() {
+        return requiredApplicationCredentials;
+    }
+
+    public void setRequiredApplicationCredentials(Collection<RequiredCredentialEntity> requiredApplicationCredentials) {
+        this.requiredApplicationCredentials = requiredApplicationCredentials;
+    }
+
+    public Collection<RequiredCredentialEntity> getRequiredOAuthClientCredentials() {
+        return requiredOAuthClientCredentials;
+    }
+
+    public void setRequiredOAuthClientCredentials(Collection<RequiredCredentialEntity> requiredOAuthClientCredentials) {
+        this.requiredOAuthClientCredentials = requiredOAuthClientCredentials;
+    }
+
+    public Collection<ApplicationEntity> getApplications() {
+        return applications;
+    }
+
+    public void setApplications(Collection<ApplicationEntity> applications) {
+        this.applications = applications;
+    }
+
+    public Collection<RoleEntity> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(Collection<RoleEntity> roles) {
+        this.roles = roles;
+    }
+
+    public void addRole(RoleEntity role) {
+        if (roles == null) {
+            roles = new ArrayList<RoleEntity>();
+        }
+        roles.add(role);
+    }
+
+    public Map<String, String> getSmtpConfig() {
+        return smtpConfig;
+    }
+
+    public void setSmtpConfig(Map<String, String> smtpConfig) {
+        this.smtpConfig = smtpConfig;
+    }
 
+    public Map<String, String> getSocialConfig() {
+        return socialConfig;
+    }
 
+    public void setSocialConfig(Map<String, String> socialConfig) {
+        this.socialConfig = socialConfig;
+    }
 
+    public Collection<RoleEntity> getDefaultRoles() {
+        return defaultRoles;
+    }
 
+    public void setDefaultRoles(Collection<RoleEntity> defaultRoles) {
+        this.defaultRoles = defaultRoles;
+    }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmScopeMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmScopeMappingEntity.java
new file mode 100755
index 0000000..5800e9f
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmScopeMappingEntity.java
@@ -0,0 +1,29 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@NamedQueries({
+        @NamedQuery(name="userHasRealmScope", query="select m from RealmScopeMappingEntity m where m.user = :user and m.role = :role and m.realm = :realm"),
+        @NamedQuery(name="userRealmScopeMappings", query="select m from RealmScopeMappingEntity m where m.user = :user and m.realm = :realm")
+})
+@Entity
+public class RealmScopeMappingEntity extends UserRoleMappingEntity {
+
+    @ManyToOne
+    protected RealmEntity realm;
+
+    public RealmEntity getRealm() {
+        return realm;
+    }
+
+    public void setRealm(RealmEntity realm) {
+        this.realm = realm;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java
new file mode 100755
index 0000000..305ce8d
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java
@@ -0,0 +1,29 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@NamedQueries({
+        @NamedQuery(name="userHasRealmRole", query="select m from RealmUserRoleMappingEntity m where m.user = :user and m.role = :role and m.realm = :realm"),
+        @NamedQuery(name="userRealmMappings", query="select m from RealmUserRoleMappingEntity m where m.user = :user and m.realm = :realm")
+})
+@Entity
+public class RealmUserRoleMappingEntity extends UserRoleMappingEntity {
+
+    @ManyToOne
+    protected RealmEntity realm;
+
+    public RealmEntity getRealm() {
+        return realm;
+    }
+
+    public void setRealm(RealmEntity realm) {
+        this.realm = realm;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
new file mode 100755
index 0000000..40c11c9
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
@@ -0,0 +1,61 @@
+package org.keycloak.models.jpa.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+@Entity
+public class RequiredCredentialEntity {
+    @Id
+    @GeneratedValue
+    protected String id;
+
+    protected String type;
+    protected boolean input;
+    protected boolean secret;
+    protected String formLabel;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public boolean isInput() {
+        return input;
+    }
+
+    public void setInput(boolean input) {
+        this.input = input;
+    }
+
+    public boolean isSecret() {
+        return secret;
+    }
+
+    public void setSecret(boolean secret) {
+        this.secret = secret;
+    }
+
+    public String getFormLabel() {
+        return formLabel;
+    }
+
+    public void setFormLabel(String formLabel) {
+        this.formLabel = formLabel;
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
index 94bdf88..6b8fc5a 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
@@ -1,20 +1,72 @@
 package org.keycloak.models.jpa.entities;
 
+import org.keycloak.models.UserModel;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
+@NamedQueries({
+        @NamedQuery(name="getRealmUserByLoginName", query="select u from UserEntity u where u.loginName = :loginName and u.realm = :realm"),
+        @NamedQuery(name="getRealmUserByEmail", query="select u from UserEntity u where u.email = :email and u.realm = :realm"),
+        @NamedQuery(name="getRealmUserByLastName", query="select u from UserEntity u where u.lastName = :lastName and u.realm = :realm"),
+        @NamedQuery(name="getRealmUserByFirstLastName", query="select u from UserEntity u where u.firstName = :first and u.lastName = :last and u.realm = :realm")
+})
 @Entity
 public class UserEntity {
     @Id
     @GeneratedValue
-    private String id;
+    protected String id;
+
+    protected String loginName;
+    protected String firstName;
+    protected String lastName;
+    protected String email;
+    protected boolean enabled;
+    protected boolean totp;
+    protected boolean emailVerified;
+
+    @ManyToOne
+    protected RealmEntity realm;
+
+    @ElementCollection
+    @MapKeyColumn(name="name")
+    @Column(name="value")
+    @CollectionTable
+    protected Map<String, String> attributes = new HashMap<String, String>();
+
+    @ElementCollection
+    @CollectionTable
+    protected Set<UserModel.RequiredAction> requiredActions = new HashSet<UserModel.RequiredAction>();
+
+    @ElementCollection
+    @CollectionTable
+    protected Set<String> webOrigins = new HashSet<String>();
+
+    @ElementCollection
+    @CollectionTable
+    protected Set<String> redirectUris = new HashSet<String>();
 
-    private String loginName;
+    @OneToMany
+    protected Collection<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
 
     public String getId() {
         return id;
@@ -31,4 +83,100 @@ public class UserEntity {
     public void setLoginName(String loginName) {
         this.loginName = loginName;
     }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public boolean isTotp() {
+        return totp;
+    }
+
+    public void setTotp(boolean totp) {
+        this.totp = totp;
+    }
+
+    public boolean isEmailVerified() {
+        return emailVerified;
+    }
+
+    public void setEmailVerified(boolean emailVerified) {
+        this.emailVerified = emailVerified;
+    }
+
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Map<String, String> attributes) {
+        this.attributes = attributes;
+    }
+
+    public Set<UserModel.RequiredAction> getRequiredActions() {
+        return requiredActions;
+    }
+
+    public void setRequiredActions(Set<UserModel.RequiredAction> requiredActions) {
+        this.requiredActions = requiredActions;
+    }
+
+    public Set<String> getWebOrigins() {
+        return webOrigins;
+    }
+
+    public void setWebOrigins(Set<String> webOrigins) {
+        this.webOrigins = webOrigins;
+    }
+
+    public Set<String> getRedirectUris() {
+        return redirectUris;
+    }
+
+    public void setRedirectUris(Set<String> redirectUris) {
+        this.redirectUris = redirectUris;
+    }
+
+    public RealmEntity getRealm() {
+        return realm;
+    }
+
+    public void setRealm(RealmEntity realm) {
+        this.realm = realm;
+    }
+
+    public Collection<CredentialEntity> getCredentials() {
+        return credentials;
+    }
+
+    public void setCredentials(Collection<CredentialEntity> credentials) {
+        this.credentials = credentials;
+    }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
index 51099df..2befc8d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
@@ -1,24 +1,23 @@
 package org.keycloak.models.jpa.entities;
 
-import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-@Entity
-public class UserRoleMappingEntity {
+@MappedSuperclass
+public abstract class UserRoleMappingEntity {
     @Id
     @GeneratedValue
-    private long id;
-
+    protected long id;
     @ManyToOne
-    private UserEntity user;
+    protected UserEntity user;
     @ManyToOne
-    private RoleEntity role;
+    protected RoleEntity role;
 
     public long getId() {
         return id;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
new file mode 100755
index 0000000..13d26d3
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
@@ -0,0 +1,74 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.jpa.entities.RealmEntity;
+import org.keycloak.models.utils.KeycloakSessionUtils;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JpaKeycloakSession implements KeycloakSession {
+    protected EntityManager em;
+
+    public JpaKeycloakSession(EntityManager em) {
+        this.em = em;
+    }
+
+    @Override
+    public KeycloakTransaction getTransaction() {
+        return new JpaKeycloakTransaction(em);
+    }
+
+    @Override
+    public RealmModel createRealm(String name) {
+        return createRealm(KeycloakSessionUtils.generateId(), name);
+    }
+
+    @Override
+    public RealmModel createRealm(String id, String name) {
+        RealmEntity realm = new RealmEntity();
+        realm.setName(name);
+        realm.setId(id);
+        em.persist(realm);
+        em.flush();
+        return new RealmAdapter(em, realm);
+    }
+
+    @Override
+    public RealmModel getRealm(String id) {
+        RealmEntity realm = em.find(RealmEntity.class, id);
+        if (realm == null) return null;
+        return new RealmAdapter(em, realm);
+    }
+
+    @Override
+    public List<RealmModel> getRealms(UserModel admin) {
+        TypedQuery<RealmEntity> query = em.createQuery("select r from RealmEntity r", RealmEntity.class);
+        List<RealmEntity> entities = query.getResultList();
+        List<RealmModel> realms = new ArrayList<RealmModel>();
+        for (RealmEntity entity : entities) {
+            realms.add(new RealmAdapter(em, entity));
+        }
+        return realms;
+    }
+
+    @Override
+    public void deleteRealm(RealmModel realm) {
+        throw new RuntimeException("Not Implemented Yet");
+    }
+
+    @Override
+    public void close() {
+        if (em.getTransaction().isActive()) em.getTransaction().rollback();
+        if (em.isOpen()) em.close();
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java
new file mode 100755
index 0000000..67ba543
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java
@@ -0,0 +1,28 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+import javax.persistence.EntityManagerFactory;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JpaKeycloakSessionFactory implements KeycloakSessionFactory {
+    protected EntityManagerFactory factory;
+
+    public JpaKeycloakSessionFactory(EntityManagerFactory factory) {
+        this.factory = factory;
+    }
+
+    @Override
+    public KeycloakSession createSession() {
+        return new JpaKeycloakSession(factory.createEntityManager());
+    }
+
+    @Override
+    public void close() {
+        factory.close();
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
new file mode 100755
index 0000000..6e7f3f3
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
@@ -0,0 +1,48 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.KeycloakTransaction;
+
+import javax.persistence.EntityManager;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JpaKeycloakTransaction implements KeycloakTransaction {
+
+    protected EntityManager em;
+
+    public JpaKeycloakTransaction(EntityManager em) {
+        this.em = em;
+    }
+
+    @Override
+    public void begin() {
+        em.getTransaction().begin();
+    }
+
+    @Override
+    public void commit() {
+        em.getTransaction().commit();
+    }
+
+    @Override
+    public void rollback() {
+        em.getTransaction().rollback();
+    }
+
+    @Override
+    public void setRollbackOnly() {
+        em.getTransaction().setRollbackOnly();
+    }
+
+    @Override
+    public boolean getRollbackOnly() {
+        return  em.getTransaction().getRollbackOnly();
+    }
+
+    @Override
+    public boolean isActive() {
+        return em.getTransaction().isActive();
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
new file mode 100755
index 0000000..1c5f743
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
@@ -0,0 +1,20 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.ModelProvider;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class JpaModelProvider implements ModelProvider {
+    @Override
+    public KeycloakSessionFactory createFactory() {
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store");
+        return new JpaKeycloakSessionFactory(emf);
+
+    }
+}
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
new file mode 100755
index 0000000..fd2afcc
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
@@ -0,0 +1,32 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.jpa.entities.OAuthClientEntity;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OAuthClientAdapter implements OAuthClientModel {
+    protected OAuthClientEntity entity;
+
+    public OAuthClientAdapter(OAuthClientEntity entity) {
+        this.entity = entity;
+    }
+
+    public OAuthClientEntity getEntity() {
+        return entity;
+    }
+
+    @Override
+    public String getId() {
+        return entity.getId();
+    }
+
+    @Override
+    public UserModel getOAuthAgent() {
+        return new UserAdapter(entity.getAgent());
+    }
+
+}
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
new file mode 100755
index 0000000..8eb89d5
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -0,0 +1,955 @@
+package org.keycloak.models.jpa;
+
+import org.bouncycastle.openssl.PEMWriter;
+import org.keycloak.PemUtils;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.OAuthClientModel;
+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.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.CredentialEntity;
+import org.keycloak.models.jpa.entities.OAuthClientEntity;
+import org.keycloak.models.jpa.entities.RealmEntity;
+import org.keycloak.models.jpa.entities.RealmScopeMappingEntity;
+import org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity;
+import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
+import org.keycloak.models.jpa.entities.RoleEntity;
+import org.keycloak.models.jpa.entities.SocialLinkEntity;
+import org.keycloak.models.jpa.entities.UserEntity;
+import org.keycloak.models.utils.SHAPasswordEncoder;
+import org.keycloak.models.utils.TimeBasedOTP;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class RealmAdapter implements RealmModel {
+    protected RealmEntity realm;
+    protected EntityManager em;
+    protected volatile transient PublicKey publicKey;
+    protected volatile transient PrivateKey privateKey;
+
+    public RealmAdapter(EntityManager em, RealmEntity realm) {
+        this.em = em;
+        this.realm = realm;
+    }
+
+    @Override
+    public String getId() {
+        return realm.getId();
+    }
+
+    @Override
+    public String getName() {
+        return realm.getName();
+    }
+
+    @Override
+    public void setName(String name) {
+        realm.setName(name);
+        em.flush();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return realm.isEnabled();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        realm.setEnabled(enabled);
+        em.flush();
+    }
+
+    @Override
+    public boolean isSslNotRequired() {
+        return realm.isSslNotRequired();
+    }
+
+    @Override
+    public void setSslNotRequired(boolean sslNotRequired) {
+        realm.setSslNotRequired(sslNotRequired);
+        em.flush();
+    }
+
+    @Override
+    public boolean isCookieLoginAllowed() {
+        return realm.isCookieLoginAllowed();
+    }
+
+    @Override
+    public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
+        realm.setCookieLoginAllowed(cookieLoginAllowed);
+        em.flush();
+    }
+
+    @Override
+    public boolean isRegistrationAllowed() {
+        return realm.isRegistrationAllowed();
+    }
+
+    @Override
+    public void setRegistrationAllowed(boolean registrationAllowed) {
+        realm.setRegistrationAllowed(registrationAllowed);
+        em.flush();
+    }
+
+    @Override
+    public boolean isVerifyEmail() {
+        return realm.isVerifyEmail();
+    }
+
+    @Override
+    public void setVerifyEmail(boolean verifyEmail) {
+        realm.setVerifyEmail(verifyEmail);
+        em.flush();
+    }
+
+    @Override
+    public boolean isResetPasswordAllowed() {
+        return realm.isResetPasswordAllowed();
+    }
+
+    @Override
+    public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+        realm.setResetPasswordAllowed(resetPasswordAllowed);
+        em.flush();
+    }
+
+    @Override
+    public int getTokenLifespan() {
+        return realm.getTokenLifespan();
+    }
+
+    @Override
+    public void setTokenLifespan(int tokenLifespan) {
+        realm.setTokenLifespan(tokenLifespan);
+        em.flush();
+    }
+
+    @Override
+    public int getAccessCodeLifespan() {
+        return realm.getAccessCodeLifespan();
+    }
+
+    @Override
+    public void setAccessCodeLifespan(int accessCodeLifespan) {
+        realm.setAccessCodeLifespan(accessCodeLifespan);
+        em.flush();
+    }
+
+    @Override
+    public int getAccessCodeLifespanUserAction() {
+        return realm.getAccessCodeLifespanUserAction();
+    }
+
+    @Override
+    public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+        realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
+        em.flush();
+    }
+
+    @Override
+    public String getPublicKeyPem() {
+        return realm.getPublicKeyPem();
+    }
+
+    @Override
+    public void setPublicKeyPem(String publicKeyPem) {
+        realm.setPublicKeyPem(publicKeyPem);
+        em.flush();
+    }
+
+    @Override
+    public String getPrivateKeyPem() {
+        return realm.getPrivateKeyPem();
+    }
+
+    @Override
+    public void setPrivateKeyPem(String privateKeyPem) {
+        realm.setPrivateKeyPem(privateKeyPem);
+        em.flush();
+    }
+
+    @Override
+    public PublicKey getPublicKey() {
+        if (publicKey != null) return publicKey;
+        String pem = getPublicKeyPem();
+        if (pem != null) {
+            try {
+                publicKey = PemUtils.decodePublicKey(pem);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return publicKey;
+    }
+
+    @Override
+    public void setPublicKey(PublicKey publicKey) {
+        this.publicKey = publicKey;
+        StringWriter writer = new StringWriter();
+        PEMWriter pemWriter = new PEMWriter(writer);
+        try {
+            pemWriter.writeObject(publicKey);
+            pemWriter.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        String s = writer.toString();
+        setPublicKeyPem(PemUtils.removeBeginEnd(s));
+    }
+
+    @Override
+    public PrivateKey getPrivateKey() {
+        if (privateKey != null) return privateKey;
+        String pem = getPrivateKeyPem();
+        if (pem != null) {
+            try {
+                privateKey = PemUtils.decodePrivateKey(pem);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return privateKey;
+    }
+
+    @Override
+    public void setPrivateKey(PrivateKey privateKey) {
+        this.privateKey = privateKey;
+        StringWriter writer = new StringWriter();
+        PEMWriter pemWriter = new PEMWriter(writer);
+        try {
+            pemWriter.writeObject(privateKey);
+            pemWriter.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        String s = writer.toString();
+        setPrivateKeyPem(PemUtils.removeBeginEnd(s));
+    }
+
+    protected RequiredCredentialModel initRequiredCredentialModel(String type) {
+        RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
+        if (model == null) {
+            throw new RuntimeException("Unknown credential type " + type);
+        }
+        return model;
+    }
+
+    @Override
+    public void addRequiredCredential(String type) {
+        RequiredCredentialModel model = initRequiredCredentialModel(type);
+        addRequiredCredential(model);
+        em.flush();
+    }
+
+    public void addRequiredCredential(RequiredCredentialModel model) {
+        RequiredCredentialEntity entity = new RequiredCredentialEntity();
+        entity.setInput(model.isInput());
+        entity.setSecret(model.isSecret());
+        entity.setType(model.getType());
+        entity.setFormLabel(model.getFormLabel());
+        em.persist(entity);
+        realm.getRequiredCredentials().add(entity);
+        em.flush();
+    }
+
+    @Override
+    public void updateRequiredCredentials(Set<String> creds) {
+        Collection<RequiredCredentialEntity> relationships = realm.getRequiredCredentials();
+        if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
+
+        Set<String> already = new HashSet<String>();
+        List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
+        for (RequiredCredentialEntity rel : relationships) {
+            if (!creds.contains(rel.getType())) {
+                remove.add(rel);
+            } else {
+                already.add(rel.getType());
+            }
+        }
+        for (RequiredCredentialEntity entity : remove) {
+            relationships.remove(entity);
+            em.remove(entity);
+        }
+        for (String cred : creds) {
+            if (!already.contains(cred)) {
+                addRequiredCredential(cred);
+            }
+        }
+        em.flush();
+    }
+
+
+    @Override
+    public List<RequiredCredentialModel> getRequiredCredentials() {
+        List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
+        Collection<RequiredCredentialEntity> entities = realm.getRequiredCredentials();
+        if (entities == null) return requiredCredentialModels;
+        for (RequiredCredentialEntity entity : entities) {
+            RequiredCredentialModel model = new RequiredCredentialModel();
+            model.setFormLabel(entity.getFormLabel());
+            model.setType(entity.getType());
+            model.setSecret(entity.isSecret());
+            model.setInput(entity.isInput());
+            requiredCredentialModels.add(model);
+        }
+        return requiredCredentialModels;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<RequiredCredentialModel> getRequiredApplicationCredentials() {
+        List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
+        Collection<RequiredCredentialEntity> entities = realm.getRequiredApplicationCredentials();
+        if (entities == null) return requiredCredentialModels;
+        for (RequiredCredentialEntity entity : entities) {
+            RequiredCredentialModel model = new RequiredCredentialModel();
+            model.setFormLabel(entity.getFormLabel());
+            model.setType(entity.getType());
+            model.setSecret(entity.isSecret());
+            model.setInput(entity.isInput());
+            requiredCredentialModels.add(model);
+        }
+        return requiredCredentialModels;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<RequiredCredentialModel> getRequiredOAuthClientCredentials() {
+        List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
+        Collection<RequiredCredentialEntity> entities = realm.getRequiredOAuthClientCredentials();
+        if (entities == null) return requiredCredentialModels;
+        for (RequiredCredentialEntity entity : entities) {
+            RequiredCredentialModel model = new RequiredCredentialModel();
+            model.setFormLabel(entity.getFormLabel());
+            model.setType(entity.getType());
+            model.setSecret(entity.isSecret());
+            model.setInput(entity.isInput());
+            requiredCredentialModels.add(model);
+        }
+        return requiredCredentialModels;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void addRequiredOAuthClientCredential(RequiredCredentialModel model) {
+        RequiredCredentialEntity entity = new RequiredCredentialEntity();
+        entity.setInput(model.isInput());
+        entity.setSecret(model.isSecret());
+        entity.setType(model.getType());
+        entity.setFormLabel(model.getFormLabel());
+        em.persist(entity);
+        realm.getRequiredOAuthClientCredentials().add(entity);
+        em.flush();
+    }
+
+    @Override
+    public void addRequiredOAuthClientCredential(String type) {
+        RequiredCredentialModel model = initRequiredCredentialModel(type);
+        addRequiredOAuthClientCredential(model);
+        em.flush();
+    }
+
+    public void addRequiredResourceCredential(RequiredCredentialModel model) {
+        RequiredCredentialEntity entity = new RequiredCredentialEntity();
+        entity.setInput(model.isInput());
+        entity.setSecret(model.isSecret());
+        entity.setType(model.getType());
+        entity.setFormLabel(model.getFormLabel());
+        em.persist(entity);
+        realm.getRequiredApplicationCredentials().add(entity);
+        em.flush();
+    }
+
+    @Override
+    public void addRequiredResourceCredential(String type) {
+        RequiredCredentialModel model = initRequiredCredentialModel(type);
+        addRequiredResourceCredential(model);
+        em.flush();
+    }
+
+    @Override
+    public void updateRequiredOAuthClientCredentials(Set<String> creds) {
+        Collection<RequiredCredentialEntity> relationships = realm.getRequiredOAuthClientCredentials();
+        if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
+
+        Set<String> already = new HashSet<String>();
+        List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
+        for (RequiredCredentialEntity rel : relationships) {
+            if (!creds.contains(rel.getType())) {
+                remove.add(rel);
+            } else {
+                already.add(rel.getType());
+            }
+        }
+        for (RequiredCredentialEntity entity : remove) {
+            relationships.remove(entity);
+            em.remove(entity);
+        }
+        for (String cred : creds) {
+            if (!already.contains(cred)) {
+                addRequiredOAuthClientCredential(cred);
+            }
+        }
+        em.flush();
+    }
+
+    @Override
+    public void updateRequiredApplicationCredentials(Set<String> creds) {
+        Collection<RequiredCredentialEntity> relationships = realm.getRequiredApplicationCredentials();
+        if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
+
+        Set<String> already = new HashSet<String>();
+        List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
+        for (RequiredCredentialEntity rel : relationships) {
+            if (!creds.contains(rel.getType())) {
+                remove.add(rel);
+            } else {
+                already.add(rel.getType());
+            }
+        }
+        for (RequiredCredentialEntity entity : remove) {
+            relationships.remove(entity);
+            em.remove(entity);
+        }
+        for (String cred : creds) {
+            if (!already.contains(cred)) {
+                addRequiredResourceCredential(cred);
+            }
+        }
+        em.flush();
+    }
+
+    @Override
+    public UserModel getUser(String name) {
+        TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByLoginName", UserEntity.class);
+        query.setParameter("loginName", name);
+        query.setParameter("realm", realm);
+        List<UserEntity> results = query.getResultList();
+        if (results.size() == 0) return null;
+        return new UserAdapter(results.get(0));
+    }
+
+    @Override
+    public UserModel addUser(String username) {
+        UserEntity entity = new UserEntity();
+        entity.setLoginName(username);
+        entity.setRealm(realm);
+        em.persist(entity);
+        em.flush();
+        return new UserAdapter(entity);
+    }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        Collection<RoleEntity> entities = realm.getDefaultRoles();
+        List<String> roles = new ArrayList<String>();
+        if (entities == null) return roles;
+        for (RoleEntity entity : entities) {
+            roles.add(entity.getName());
+        }
+        return roles;
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        RoleModel role = getRole(name);
+        if (role == null) {
+            role = addRole(name);
+        }
+        Collection<RoleEntity> entities = realm.getDefaultRoles();
+        for (RoleEntity entity : entities) {
+            if (entity.getId().equals(role.getId())) {
+                return;
+            }
+        }
+        entities.add(((RoleAdapter) role).getRole());
+        em.flush();
+    }
+
+    public static boolean contains(String str, String[] array) {
+        for (String s : array) {
+            if (str.equals(s)) return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        Collection<RoleEntity> entities = realm.getDefaultRoles();
+        Set<String> already = new HashSet<String>();
+        List<RoleEntity> remove = new ArrayList<RoleEntity>();
+        for (RoleEntity rel : entities) {
+            if (!contains(rel.getName(), defaultRoles)) {
+                remove.add(rel);
+            } else {
+                already.add(rel.getName());
+            }
+        }
+        for (RoleEntity entity : remove) {
+            entities.remove(entity);
+        }
+        em.flush();
+        for (String roleName : defaultRoles) {
+            if (!already.contains(roleName)) {
+                addDefaultRole(roleName);
+            }
+        }
+        em.flush();
+    }
+
+    @Override
+    public Map<String, ApplicationModel> getApplicationNameMap() {
+        Map<String, ApplicationModel> map = new HashMap<String, ApplicationModel>();
+        for (ApplicationModel app : getApplications()) {
+            map.put(app.getName(), app);
+        }
+        return map;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<ApplicationModel> getApplications() {
+        List<ApplicationModel> list = new ArrayList<ApplicationModel>();
+        if (realm.getApplications() == null) return list;
+        for (ApplicationEntity entity : realm.getApplications()) {
+            list.add(new ApplicationAdapter(em, entity));
+        }
+        return list;
+    }
+
+    @Override
+    public ApplicationModel addApplication(String name) {
+        ApplicationEntity applicationData = new ApplicationEntity();
+        UserEntity user = new UserEntity();
+        user.setLoginName(name);
+        user.setRealm(realm);
+        user.setEnabled(true);
+        em.persist(user);
+        applicationData.setApplicationUser(user);
+        applicationData.setName(name);
+        applicationData.setEnabled(true);
+        realm.getApplications().add(applicationData);
+        em.persist(applicationData);
+        em.flush();
+        ApplicationModel resource = new ApplicationAdapter(em, applicationData);
+        resource.addRole("*");
+        resource.addScopeMapping(new UserAdapter(user), "*");
+        em.flush();
+        return resource;
+    }
+
+    @Override
+    public ApplicationModel getApplicationById(String id) {
+        ApplicationEntity app = em.find(ApplicationEntity.class, id);
+        if (app == null) return null;
+        return new ApplicationAdapter(em, app);
+    }
+
+    @Override
+    public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
+        TypedQuery<UserEntity> query = em.createNamedQuery("findUserByLinkAndRealm", UserEntity.class);
+        query.setParameter("realm", realm);
+        query.setParameter("socialProvider", socialLink.getSocialProvider());
+        query.setParameter("socialUsername", socialLink.getSocialUsername());
+        List<UserEntity> results = query.getResultList();
+        if (results.isEmpty()) {
+            return null;
+        } else if (results.size() > 1) {
+            throw new IllegalStateException("More results found for socialProvider=" + socialLink.getSocialProvider() +
+                    ", socialUsername=" + socialLink.getSocialUsername() + ", results=" + results);
+        } else {
+            UserEntity user = results.get(0);
+            return new UserAdapter(user);
+        }
+    }
+
+    @Override
+    public Set<SocialLinkModel> getSocialLinks(UserModel user) {
+        TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByUser", SocialLinkEntity.class);
+        query.setParameter("user", ((UserAdapter) user).getUser());
+        List<SocialLinkEntity> results = query.getResultList();
+        Set<SocialLinkModel> set = new HashSet<SocialLinkModel>();
+        for (SocialLinkEntity entity : results) {
+            set.add(new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUsername()));
+        }
+        return set;
+    }
+
+    @Override
+    public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
+        SocialLinkEntity entity = new SocialLinkEntity();
+        entity.setRealm(realm);
+        entity.setSocialProvider(socialLink.getSocialProvider());
+        entity.setSocialUsername(socialLink.getSocialUsername());
+        entity.setUser(((UserAdapter) user).getUser());
+        em.persist(entity);
+        em.flush();
+    }
+
+    @Override
+    public void removeSocialLink(UserModel user, SocialLinkModel socialLink) {
+        TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByAll", SocialLinkEntity.class);
+        query.setParameter("realm", realm);
+        query.setParameter("user", ((UserAdapter) user).getUser());
+        query.setParameter("socialProvider", socialLink.getSocialProvider());
+        query.setParameter("socialUsername", socialLink.getSocialUsername());
+        List<SocialLinkEntity> results = query.getResultList();
+        for (SocialLinkEntity entity : results) em.remove(entity);
+        em.flush();
+    }
+
+    @Override
+    public boolean isSocial() {
+        return realm.isSocial();
+    }
+
+    @Override
+    public void setSocial(boolean social) {
+        realm.setSocial(social);
+        em.flush();
+    }
+
+    @Override
+    public boolean isAutomaticRegistrationAfterSocialLogin() {
+        return realm.isAutomaticRegistrationAfterSocialLogin();
+    }
+
+    @Override
+    public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
+        realm.setAutomaticRegistrationAfterSocialLogin(automaticRegistrationAfterSocialLogin);
+        em.flush();
+    }
+
+    @Override
+    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
+        StringBuilder builder = new StringBuilder("select u from UserEntity u");
+        boolean first = true;
+        for (Map.Entry<String, String> entry : attributes.entrySet()) {
+            String attribute = null;
+            if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
+                attribute = "loginName";
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
+                attribute = "firstName";
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
+                attribute = "lastName";
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
+                attribute = "email";
+            }
+            if (attribute == null) continue;
+            if (first) {
+                first = false;
+                builder.append(" where ");
+            } else {
+                builder.append(" and ");
+            }
+            builder.append(attribute).append("='").append(entry.getValue()).append("'");
+        }
+        TypedQuery<UserEntity> query = em.createQuery(builder.toString(), UserEntity.class);
+        List<UserEntity> results = query.getResultList();
+        List<UserModel> users = new ArrayList<UserModel>();
+        for (UserEntity entity : results) users.add(new UserAdapter(entity));
+        return users;
+    }
+
+    @Override
+    public OAuthClientModel addOAuthClient(String name) {
+        OAuthClientEntity data = new OAuthClientEntity();
+        UserEntity user = new UserEntity();
+        user.setLoginName(name);
+        user.setRealm(realm);
+        user.setEnabled(true);
+        em.persist(user);
+        data.setAgent(user);
+        data.setName(name);
+        data.setRealm(realm);
+        em.persist(data);
+        em.flush();
+        return new OAuthClientAdapter(data);
+    }
+
+    @Override
+    public OAuthClientModel getOAuthClient(String name) {
+        TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByUser", OAuthClientEntity.class);
+        query.setParameter("name", name);
+        query.setParameter("realm", realm);
+        List<OAuthClientEntity> entities = query.getResultList();
+        if (entities.size() == 0) return null;
+        return new OAuthClientAdapter(entities.get(0));
+     }
+
+    @Override
+    public List<OAuthClientModel> getOAuthClients() {
+        TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByRealm", OAuthClientEntity.class);
+        query.setParameter("realm", realm);
+        List<OAuthClientEntity> entities = query.getResultList();
+        List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
+        for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(entity));
+        return list;
+    }
+
+    @Override
+    public Map<String, String> getSmtpConfig() {
+        return realm.getSmtpConfig();
+    }
+
+    @Override
+    public void setSmtpConfig(Map<String, String> smtpConfig) {
+        realm.setSmtpConfig(smtpConfig);
+        em.flush();
+    }
+
+    @Override
+    public Map<String, String> getSocialConfig() {
+        return realm.getSocialConfig();
+    }
+
+    @Override
+    public void setSocialConfig(Map<String, String> socialConfig) {
+        realm.setSocialConfig(socialConfig);
+        em.flush();
+    }
+
+    @Override
+    public RoleModel getRole(String name) {
+        Collection<RoleEntity> roles = realm.getRoles();
+        if (roles == null) return null;
+        for (RoleEntity role : roles) {
+            if (role.getName().equals(name)) {
+                return new RoleAdapter(role);
+            }
+        }
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public RoleModel addRole(String name) {
+        RoleModel role = getRole(name);
+        if (role != null) return role;
+        RoleEntity entity = new RoleEntity();
+        entity.setName(name);
+        em.persist(entity);
+        realm.getRoles().add(entity);
+        em.flush();
+        return new RoleAdapter(entity);
+    }
+
+    @Override
+    public List<RoleModel> getRoles() {
+        ArrayList<RoleModel> list = new ArrayList<RoleModel>();
+        Collection<RoleEntity> roles = realm.getRoles();
+        if (roles == null) return list;
+        for (RoleEntity entity : roles) {
+            list.add(new RoleAdapter(entity));
+        }
+        return list;
+    }
+
+    @Override
+    public RoleModel getRoleById(String id) {
+        RoleEntity entity = em.find(RoleEntity.class, id);
+        if (entity == null) return null;
+        return new RoleAdapter(entity);
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, RoleModel role) {
+        TypedQuery<RealmUserRoleMappingEntity> query = getRealmUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
+        return query.getResultList().size() > 0;
+    }
+
+    protected TypedQuery<RealmUserRoleMappingEntity> getRealmUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) {
+        TypedQuery<RealmUserRoleMappingEntity> query = em.createNamedQuery("userHasRealmRole", RealmUserRoleMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("role", ((RoleAdapter)role).getRole());
+        query.setParameter("realm", realm);
+        return query;
+    }
+
+    @Override
+    public void grantRole(UserModel user, RoleModel role) {
+        if (hasRole(user, role)) return;
+        RealmUserRoleMappingEntity entity = new RealmUserRoleMappingEntity();
+        entity.setRealm(realm);
+        entity.setUser(((UserAdapter) user).getUser());
+        entity.setRole(((RoleAdapter)role).getRole());
+        em.persist(entity);
+        em.flush();
+    }
+
+    @Override
+    public List<RoleModel> getRoleMappings(UserModel user) {
+        TypedQuery<RealmUserRoleMappingEntity> query = em.createNamedQuery("userRealmMappings", RealmUserRoleMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("realm", realm);
+        List<RealmUserRoleMappingEntity> entities = query.getResultList();
+        List<RoleModel> roles = new ArrayList<RoleModel>();
+        for (RealmUserRoleMappingEntity entity : entities) {
+            roles.add(new RoleAdapter(entity.getRole()));
+        }
+        return roles;
+    }
+
+    @Override
+    public Set<String> getRoleMappingValues(UserModel user) {
+        TypedQuery<RealmUserRoleMappingEntity> query = em.createNamedQuery("userRealmMappings", RealmUserRoleMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("realm", realm);
+        List<RealmUserRoleMappingEntity> entities = query.getResultList();
+        Set<String> roles = new HashSet<String>();
+        for (RealmUserRoleMappingEntity entity : entities) {
+            roles.add(entity.getRole().getName());
+        }
+        return roles;
+    }
+
+    @Override
+    public void deleteRoleMapping(UserModel user, RoleModel role) {
+        TypedQuery<RealmUserRoleMappingEntity> query = getRealmUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
+        List<RealmUserRoleMappingEntity> results = query.getResultList();
+        if (results.size() == 0) return;
+        for (RealmUserRoleMappingEntity entity : results) {
+            em.remove(entity);
+        }
+        em.flush();
+    }
+
+    @Override
+    public boolean hasRole(UserModel user, String roleName) {
+        RoleModel role = getRole(roleName);
+        if (role == null) return false;
+        return hasRole(user, role);
+    }
+
+    @Override
+    public void addScopeMapping(UserModel agent, String roleName) {
+        RoleModel role = getRole(roleName);
+        if (role == null) throw new RuntimeException("role does not exist");
+        addScopeMapping(agent, role);
+        em.flush();
+    }
+
+    @Override
+    public Set<String> getScopeMappingValues(UserModel agent) {
+        TypedQuery<RealmScopeMappingEntity> query = em.createNamedQuery("userRealmScopeMappings", RealmScopeMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)agent).getUser());
+        query.setParameter("realm", realm);
+        List<RealmScopeMappingEntity> entities = query.getResultList();
+        Set<String> roles = new HashSet<String>();
+        for (RealmScopeMappingEntity entity : entities) {
+            roles.add(entity.getRole().getName());
+        }
+        return roles;
+    }
+
+    @Override
+    public List<RoleModel> getScopeMappings(UserModel agent) {
+        TypedQuery<RealmScopeMappingEntity> query = em.createNamedQuery("userRealmScopeMappings", RealmScopeMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)agent).getUser());
+        query.setParameter("realm", realm);
+        List<RealmScopeMappingEntity> entities = query.getResultList();
+        List<RoleModel> roles = new ArrayList<RoleModel>();
+        for (RealmScopeMappingEntity entity : entities) {
+            roles.add(new RoleAdapter(entity.getRole()));
+        }
+        return roles;
+    }
+
+    @Override
+    public void addScopeMapping(UserModel agent, RoleModel role) {
+        if (hasScope(agent, role)) return;
+        RealmScopeMappingEntity entity = new RealmScopeMappingEntity();
+        entity.setRealm(realm);
+        entity.setUser(((UserAdapter) agent).getUser());
+        entity.setRole(((RoleAdapter)role).getRole());
+        em.persist(entity);
+        em.flush();
+    }
+
+    @Override
+    public void deleteScopeMapping(UserModel user, RoleModel role) {
+        TypedQuery<RealmScopeMappingEntity> query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
+        List<RealmScopeMappingEntity> results = query.getResultList();
+        if (results.size() == 0) return;
+        for (RealmScopeMappingEntity entity : results) {
+            em.remove(entity);
+        }
+    }
+
+    public boolean hasScope(UserModel user, RoleModel role) {
+        TypedQuery<RealmScopeMappingEntity> query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
+        return query.getResultList().size() > 0;
+    }
+
+
+    protected TypedQuery<RealmScopeMappingEntity> getRealmScopeMappingQuery(UserAdapter user, RoleAdapter role) {
+        TypedQuery<RealmScopeMappingEntity> query = em.createNamedQuery("userHasRealmScope", RealmScopeMappingEntity.class);
+        query.setParameter("user", ((UserAdapter)user).getUser());
+        query.setParameter("role", ((RoleAdapter)role).getRole());
+        query.setParameter("realm", realm);
+        return query;
+    }
+
+    @Override
+    public boolean validatePassword(UserModel user, String password) {
+        for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+            if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
+                return new SHAPasswordEncoder(512).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());
+            credentialEntity.setUser(userEntity);
+            em.persist(credentialEntity);
+            userEntity.getCredentials().add(credentialEntity);
+        }
+        if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
+            credentialEntity.setValue(new SHAPasswordEncoder(512).encode(cred.getValue()));
+        } else {
+            credentialEntity.setValue(cred.getValue());
+        }
+        credentialEntity.setDevice(cred.getDevice());
+        em.flush();
+    }
+
+}
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
new file mode 100755
index 0000000..5785dec
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
@@ -0,0 +1,49 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.jpa.entities.RoleEntity;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class RoleAdapter implements RoleModel {
+    protected RoleEntity role;
+
+    public RoleAdapter(RoleEntity role) {
+        this.role = role;
+    }
+
+    public RoleEntity getRole() {
+        return role;
+    }
+
+    public void setRole(RoleEntity role) {
+        this.role = role;
+    }
+
+    @Override
+    public String getName() {
+        return role.getName();
+    }
+
+    @Override
+    public String getDescription() {
+        return role.getDescription();
+    }
+
+    @Override
+    public void setDescription(String description) {
+        role.setDescription(description);
+    }
+
+    @Override
+    public String getId() {
+        return role.getId();
+    }
+
+    @Override
+    public void setName(String name) {
+        role.setName(name);
+    }
+}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
new file mode 100755
index 0000000..9f822d8
--- /dev/null
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -0,0 +1,185 @@
+package org.keycloak.models.jpa;
+
+import org.keycloak.models.UserModel;
+import org.keycloak.models.jpa.entities.UserEntity;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class UserAdapter implements UserModel {
+
+    protected UserEntity user;
+
+    public UserAdapter(UserEntity user) {
+        this.user = user;
+    }
+
+    public UserEntity getUser() {
+        return user;
+    }
+
+    @Override
+    public String getLoginName() {
+        return user.getLoginName();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return user.isEnabled();
+    }
+
+    @Override
+    public boolean isTotp() {
+        return user.isTotp();
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        user.setEnabled(enabled);
+    }
+
+    @Override
+    public void setAttribute(String name, String value) {
+        Map<String, String> attributes = user.getAttributes();
+        if (attributes == null) {
+            attributes = new HashMap<String, String>();
+        }
+        attributes.put(name, value);
+        user.setAttributes(attributes);
+    }
+
+    @Override
+    public void removeAttribute(String name) {
+        Map<String, String> attributes = user.getAttributes();
+        if (attributes == null) {
+            attributes = new HashMap<String, String>();
+        }
+        attributes.remove(name);
+        user.setAttributes(attributes);
+    }
+
+    @Override
+    public String getAttribute(String name) {
+        if (user.getAttributes() == null) return null;
+        return user.getAttributes().get(name);
+    }
+
+    @Override
+    public Map<String, String> getAttributes() {
+        Map<String, String> result = new HashMap<String, String>();
+        result.putAll(user.getAttributes());
+        return result;
+    }
+
+    @Override
+    public Set<RequiredAction> getRequiredActions() {
+        Set<RequiredAction> result = new HashSet<RequiredAction>();
+        result.addAll(user.getRequiredActions());
+        return result;
+    }
+
+    @Override
+    public void addRequiredAction(RequiredAction action) {
+        user.getRequiredActions().add(action);
+    }
+
+    @Override
+    public void removeRequiredAction(RequiredAction action) {
+        user.getRequiredActions().remove(action);
+    }
+
+    @Override
+    public Set<String> getWebOrigins() {
+        Set<String> result = new HashSet<String>();
+        result.addAll(user.getWebOrigins());
+        return result;
+    }
+
+    @Override
+    public void setWebOrigins(Set<String> webOrigins) {
+        user.setWebOrigins(webOrigins);
+    }
+
+    @Override
+    public void addWebOrigin(String webOrigin) {
+        user.getWebOrigins().add(webOrigin);
+    }
+
+    @Override
+    public void removeWebOrigin(String webOrigin) {
+        user.getWebOrigins().remove(webOrigin);
+    }
+
+    @Override
+    public Set<String> getRedirectUris() {
+        Set<String> result = new HashSet<String>();
+        result.addAll(user.getRedirectUris());
+        return result;
+    }
+
+    @Override
+    public void setRedirectUris(Set<String> redirectUris) {
+        user.setRedirectUris(redirectUris);
+    }
+
+    @Override
+    public void addRedirectUri(String redirectUri) {
+        user.getRedirectUris().add(redirectUri);
+    }
+
+    @Override
+    public void removeRedirectUri(String redirectUri) {
+        user.getRedirectUris().remove(redirectUri);
+    }
+
+    @Override
+    public String getFirstName() {
+        return user.getFirstName();
+    }
+
+    @Override
+    public void setFirstName(String firstName) {
+        user.setFirstName(firstName);
+    }
+
+    @Override
+    public String getLastName() {
+        return user.getLastName();
+    }
+
+    @Override
+    public void setLastName(String lastName) {
+        user.setLastName(lastName);
+    }
+
+    @Override
+    public String getEmail() {
+        return user.getEmail();
+    }
+
+    @Override
+    public void setEmail(String email) {
+        user.setEmail(email);
+    }
+
+    @Override
+    public boolean isEmailVerified() {
+        return user.isEmailVerified();
+    }
+
+    @Override
+    public void setEmailVerified(boolean verified) {
+        user.setEmailVerified(verified);
+    }
+
+    @Override
+    public void setTotp(boolean totp) {
+        user.setTotp(totp);
+    }
+}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/api/NoSQL.java b/model/mongo/src/main/java/org/keycloak/models/mongo/api/NoSQL.java
old mode 100644
new mode 100755
index 3bc62a5..0a63606
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/api/NoSQL.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/api/NoSQL.java
@@ -1,10 +1,9 @@
 package org.keycloak.models.mongo.api;
 
-import java.util.List;
-
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
-import org.picketlink.common.properties.Property;
+
+import java.util.List;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/TypeConverter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/TypeConverter.java
old mode 100644
new mode 100755
index a7c12c0..e097930
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/TypeConverter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/TypeConverter.java
@@ -3,8 +3,6 @@ package org.keycloak.models.mongo.api.types;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.picketlink.common.reflection.Reflections;
-
 /**
  * Registry of converters, which allow to convert application object to database objects. TypeConverter is main entry point to be used by application.
  * Application can create instance of TypeConverter and then register required Converter objects.
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBImpl.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBImpl.java
old mode 100644
new mode 100755
index 09ca78e..6bacedb
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBImpl.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBImpl.java
@@ -1,12 +1,5 @@
 package org.keycloak.models.mongo.impl;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
 import com.mongodb.BasicDBList;
 import com.mongodb.BasicDBObject;
 import com.mongodb.DB;
@@ -24,10 +17,10 @@ import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
 import org.keycloak.models.mongo.api.types.Converter;
 import org.keycloak.models.mongo.api.types.TypeConverter;
-import org.keycloak.models.mongo.impl.types.EnumToStringConverter;
-import org.keycloak.models.mongo.impl.types.ListConverter;
 import org.keycloak.models.mongo.impl.types.BasicDBListConverter;
 import org.keycloak.models.mongo.impl.types.BasicDBObjectConverter;
+import org.keycloak.models.mongo.impl.types.EnumToStringConverter;
+import org.keycloak.models.mongo.impl.types.ListConverter;
 import org.keycloak.models.mongo.impl.types.NoSQLObjectConverter;
 import org.keycloak.models.mongo.impl.types.SimpleConverter;
 import org.keycloak.models.mongo.impl.types.StringToEnumConverter;
@@ -35,6 +28,13 @@ 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.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>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBQueryBuilder.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBQueryBuilder.java
old mode 100644
new mode 100755
index f56c799..2d1f61d
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBQueryBuilder.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBQueryBuilder.java
@@ -1,13 +1,13 @@
 package org.keycloak.models.mongo.impl;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
 import com.mongodb.BasicDBObject;
 import org.bson.types.ObjectId;
 import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
 
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/ObjectInfo.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/ObjectInfo.java
old mode 100644
new mode 100755
index ae548a6..b511626
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/ObjectInfo.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/ObjectInfo.java
@@ -1,14 +1,14 @@
 package org.keycloak.models.mongo.impl;
 
+import org.keycloak.models.mongo.api.NoSQLObject;
+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;
 
-import org.keycloak.models.mongo.api.NoSQLObject;
-import org.picketlink.common.properties.Property;
-
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListConverter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListConverter.java
old mode 100644
new mode 100755
index 896257f..04824ba
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListConverter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListConverter.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.mongo.impl.types;
 
-import java.util.ArrayList;
-
 import com.mongodb.BasicDBList;
 import com.mongodb.BasicDBObject;
 import org.keycloak.models.mongo.api.types.Converter;
 import org.keycloak.models.mongo.api.types.TypeConverter;
 
+import java.util.ArrayList;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListConverter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListConverter.java
old mode 100644
new mode 100755
index 8b72ca2..49fb627
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListConverter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListConverter.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.mongo.impl.types;
 
-import java.util.List;
-
 import com.mongodb.BasicDBList;
 import com.mongodb.BasicDBObject;
 import org.keycloak.models.mongo.api.types.Converter;
 import org.keycloak.models.mongo.api.types.TypeConverter;
 
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/NoSQLObjectConverter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/NoSQLObjectConverter.java
old mode 100644
new mode 100755
index f7be7ae..35596a9
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/NoSQLObjectConverter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/NoSQLObjectConverter.java
@@ -1,8 +1,5 @@
 package org.keycloak.models.mongo.impl.types;
 
-import java.util.Collection;
-import java.util.Map;
-
 import com.mongodb.BasicDBObject;
 import org.keycloak.models.mongo.api.AttributedNoSQLObject;
 import org.keycloak.models.mongo.api.NoSQLObject;
@@ -12,6 +9,9 @@ import org.keycloak.models.mongo.impl.MongoDBImpl;
 import org.keycloak.models.mongo.impl.ObjectInfo;
 import org.picketlink.common.properties.Property;
 
+import java.util.Collection;
+import java.util.Map;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
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
old mode 100644
new mode 100755
index 49bcd31..c1a4dd2
--- 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,10 +1,5 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
@@ -14,6 +9,11 @@ import org.keycloak.models.mongo.keycloak.data.ApplicationData;
 import org.keycloak.models.mongo.keycloak.data.RoleData;
 import org.keycloak.models.mongo.keycloak.data.UserData;
 
+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>
  */
@@ -281,4 +281,19 @@ public class ApplicationAdapter implements ApplicationModel {
         }
         return result;
     }
+
+    @Override
+    public List<String> getDefaultRoles() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void addDefaultRole(String name) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void updateDefaultRoles(String[] defaultRoles) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoDBSessionFactory.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoDBSessionFactory.java
old mode 100644
new mode 100755
index b1ac509..f964605
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoDBSessionFactory.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoDBSessionFactory.java
@@ -1,7 +1,5 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import java.net.UnknownHostException;
-
 import com.mongodb.DB;
 import com.mongodb.MongoClient;
 import org.jboss.logging.Logger;
@@ -9,6 +7,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.mongo.api.NoSQLObject;
+import org.keycloak.models.mongo.impl.MongoDBImpl;
 import org.keycloak.models.mongo.keycloak.data.ApplicationData;
 import org.keycloak.models.mongo.keycloak.data.OAuthClientData;
 import org.keycloak.models.mongo.keycloak.data.RealmData;
@@ -16,10 +15,11 @@ import org.keycloak.models.mongo.keycloak.data.RequiredCredentialData;
 import org.keycloak.models.mongo.keycloak.data.RoleData;
 import org.keycloak.models.mongo.keycloak.data.SocialLinkData;
 import org.keycloak.models.mongo.keycloak.data.UserData;
-import org.keycloak.models.mongo.impl.MongoDBImpl;
 import org.keycloak.models.mongo.keycloak.data.credentials.OTPData;
 import org.keycloak.models.mongo.keycloak.data.credentials.PasswordData;
 
+import java.net.UnknownHostException;
+
 /**
  * NoSQL implementation based on MongoDB
  *
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/NoSQLSession.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/NoSQLSession.java
old mode 100644
new mode 100755
index 2bc413d..bbd5ea4
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/NoSQLSession.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/NoSQLSession.java
@@ -1,17 +1,17 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import java.util.ArrayList;
-import java.util.List;
-
 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.NoSQL;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.keycloak.data.RealmData;
-import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.utils.KeycloakSessionUtils;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
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
old mode 100644
new mode 100755
index 34f455e..d522db9
--- 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
@@ -41,14 +41,4 @@ public class OAuthClientAdapter implements OAuthClientModel {
         return oauthAgent;
     }
 
-    @Override
-    public String getBaseUrl() {
-        return delegate.getBaseUrl();
-    }
-
-    @Override
-    public void setBaseUrl(String base) {
-        delegate.setBaseUrl(base);
-        noSQL.saveObject(delegate);
-    }
 }
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
old mode 100644
new mode 100755
index 837f985..391334a
--- 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,16 +1,5 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import org.bouncycastle.openssl.PEMWriter;
 import org.keycloak.PemUtils;
 import org.keycloak.models.ApplicationModel;
@@ -21,21 +10,31 @@ 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.query.NoSQLQueryBuilder;
-import org.keycloak.models.mongo.keycloak.data.OAuthClientData;
-import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
+import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
 import org.keycloak.models.mongo.keycloak.credentials.PasswordCredentialHandler;
 import org.keycloak.models.mongo.keycloak.credentials.TOTPCredentialHandler;
 import org.keycloak.models.mongo.keycloak.data.ApplicationData;
+import org.keycloak.models.mongo.keycloak.data.OAuthClientData;
 import org.keycloak.models.mongo.keycloak.data.RealmData;
 import org.keycloak.models.mongo.keycloak.data.RequiredCredentialData;
 import org.keycloak.models.mongo.keycloak.data.RoleData;
 import org.keycloak.models.mongo.keycloak.data.SocialLinkData;
 import org.keycloak.models.mongo.keycloak.data.UserData;
+import org.keycloak.representations.idm.CredentialRepresentation;
 import org.picketlink.idm.credential.Credentials;
-import org.picketlink.idm.model.sample.User;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -597,20 +596,6 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public boolean isRealmAdmin(UserModel agent) {
-        List<String> realmAdmins = realm.getRealmAdmins();
-        String userId = ((UserAdapter)agent).getUser().getId();
-        return realmAdmins.contains(userId);
-    }
-
-    @Override
-    public void addRealmAdmin(UserModel agent) {
-        UserData userData = ((UserAdapter)agent).getUser();
-
-        noSQL.pushItemToList(realm, "realmAdmins", userData.getId());
-    }
-
-    @Override
     public RoleModel getRoleById(String id) {
         RoleData role = noSQL.loadObject(RoleData.class, id);
         if (role == null) {
@@ -859,4 +844,24 @@ public class RealmAdapter implements RealmModel {
         }
         return userModels;
     }
+
+    @Override
+    public Map<String, String> getSmtpConfig() {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public void setSmtpConfig(Map<String, String> smtpConfig) {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public Map<String, String> getSocialConfig() {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public void setSocialConfig(Map<String, String> socialConfig) {
+        throw new RuntimeException("Not implemented");
+    }
 }
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
old mode 100644
new mode 100755
index c047361..3b20848
--- 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,15 +1,15 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
+import org.keycloak.models.UserModel;
+import org.keycloak.models.mongo.api.NoSQL;
+import org.keycloak.models.mongo.keycloak.data.UserData;
+
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.keycloak.models.UserModel;
-import org.keycloak.models.mongo.api.NoSQL;
-import org.keycloak.models.mongo.keycloak.data.UserData;
-
 /**
  * Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl)
  *
@@ -149,4 +149,44 @@ public class UserAdapter implements UserModel {
         user.setTotp(totp);
         noSQL.saveObject(user);
     }
+
+    @Override
+    public Set<String> getWebOrigins() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void setWebOrigins(Set<String> webOrigins) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void addWebOrigin(String webOrigin) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void removeWebOrigin(String webOrigin) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public Set<String> getRedirectUris() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void setRedirectUris(Set<String> redirectUris) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void addRedirectUri(String redirectUri) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void removeRedirectUri(String redirectUri) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/PasswordCredentialHandler.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/PasswordCredentialHandler.java
old mode 100644
new mode 100755
index 719760a..b6a3eb1
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/PasswordCredentialHandler.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/PasswordCredentialHandler.java
@@ -1,9 +1,5 @@
 package org.keycloak.models.mongo.keycloak.credentials;
 
-import java.util.Date;
-import java.util.Map;
-import java.util.UUID;
-
 import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.keycloak.data.UserData;
@@ -12,6 +8,10 @@ import org.picketlink.idm.credential.Credentials;
 import org.picketlink.idm.credential.encoder.PasswordEncoder;
 import org.picketlink.idm.credential.encoder.SHAPasswordEncoder;
 
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
 /**
  * Defacto forked from {@link org.picketlink.idm.credential.handler.PasswordCredentialHandler}
  *
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/TOTPCredentialHandler.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/TOTPCredentialHandler.java
old mode 100644
new mode 100755
index b8f02e7..45a76f7
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/TOTPCredentialHandler.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/TOTPCredentialHandler.java
@@ -1,8 +1,5 @@
 package org.keycloak.models.mongo.keycloak.credentials;
 
-import java.util.Date;
-import java.util.Map;
-
 import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.keycloak.data.UserData;
@@ -10,11 +7,11 @@ import org.keycloak.models.mongo.keycloak.data.credentials.OTPData;
 import org.picketlink.idm.credential.Credentials;
 import org.picketlink.idm.credential.util.TimeBasedOTP;
 
+import java.util.Date;
+import java.util.Map;
+
 import static org.picketlink.common.util.StringUtil.isNullOrEmpty;
-import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_ALGORITHM;
-import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_DELAY_WINDOW;
-import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_INTERVAL_SECONDS;
-import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_NUMBER_DIGITS;
+import static org.picketlink.idm.credential.util.TimeBasedOTP.*;
 
 /**
  * Defacto forked from {@link org.picketlink.idm.credential.handler.TOTPCredentialHandler}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/OTPData.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/OTPData.java
old mode 100644
new mode 100755
index 8ab31a6..6983f83
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/OTPData.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/OTPData.java
@@ -1,11 +1,11 @@
 package org.keycloak.models.mongo.keycloak.data.credentials;
 
-import java.util.Date;
-
 import org.keycloak.models.mongo.api.AbstractNoSQLObject;
 import org.keycloak.models.mongo.api.NoSQLCollection;
 import org.keycloak.models.mongo.api.NoSQLField;
 
+import java.util.Date;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/PasswordData.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/PasswordData.java
old mode 100644
new mode 100755
index 7480e1f..6ac585f
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/PasswordData.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/PasswordData.java
@@ -1,11 +1,11 @@
 package org.keycloak.models.mongo.keycloak.data.credentials;
 
-import java.util.Date;
-
 import org.keycloak.models.mongo.api.AbstractNoSQLObject;
 import org.keycloak.models.mongo.api.NoSQLCollection;
 import org.keycloak.models.mongo.api.NoSQLField;
 
+import java.util.Date;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RealmData.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RealmData.java
old mode 100644
new mode 100755
index 5247d60..d9aa0ae
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RealmData.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RealmData.java
@@ -1,7 +1,5 @@
 package org.keycloak.models.mongo.keycloak.data;
 
-import java.util.List;
-
 import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.mongo.api.NoSQLCollection;
 import org.keycloak.models.mongo.api.NoSQLField;
@@ -9,6 +7,8 @@ import org.keycloak.models.mongo.api.NoSQLId;
 import org.keycloak.models.mongo.api.NoSQLObject;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RoleData.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RoleData.java
old mode 100644
new mode 100755
index 29bc1f8..9bd14d2
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RoleData.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RoleData.java
@@ -1,7 +1,5 @@
 package org.keycloak.models.mongo.keycloak.data;
 
-import java.util.List;
-
 import org.jboss.logging.Logger;
 import org.keycloak.models.mongo.api.NoSQL;
 import org.keycloak.models.mongo.api.NoSQLCollection;
@@ -10,6 +8,8 @@ import org.keycloak.models.mongo.api.NoSQLId;
 import org.keycloak.models.mongo.api.NoSQLObject;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/UserData.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/UserData.java
old mode 100644
new mode 100755
index cfeb67d..c57bca3
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/UserData.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/UserData.java
@@ -1,7 +1,5 @@
 package org.keycloak.models.mongo.keycloak.data;
 
-import java.util.List;
-
 import org.jboss.logging.Logger;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.mongo.api.AbstractAttributedNoSQLObject;
@@ -12,6 +10,8 @@ import org.keycloak.models.mongo.api.NoSQLId;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.keycloak.data.credentials.PasswordData;
 
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java
new file mode 100755
index 0000000..87c62af
--- /dev/null
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/MongoModelProvider.java
@@ -0,0 +1,15 @@
+package org.keycloak.models.mongo.keycloak;
+
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.ModelProvider;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class MongoModelProvider implements ModelProvider {
+    @Override
+    public KeycloakSessionFactory createFactory() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+}
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
old mode 100644
new mode 100755
index 8f6b6f8..386ca31
--- 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,10 +1,10 @@
 package org.keycloak.models.mongo.test;
 
-import java.util.List;
-
 import org.keycloak.models.mongo.api.AbstractNoSQLObject;
 import org.keycloak.models.mongo.api.NoSQLField;
 
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java
old mode 100644
new mode 100755
index 262ade8..3b8651a
--- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java
+++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java
@@ -1,10 +1,5 @@
 package org.keycloak.models.mongo.test;
 
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import com.mongodb.DB;
 import com.mongodb.MongoClient;
 import org.junit.After;
@@ -15,6 +10,11 @@ import org.keycloak.models.mongo.api.NoSQLObject;
 import org.keycloak.models.mongo.api.query.NoSQLQuery;
 import org.keycloak.models.mongo.impl.MongoDBImpl;
 
+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>
  */
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
old mode 100644
new mode 100755
index ab2ded3..7f8d0d9
--- 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,12 +1,12 @@
 package org.keycloak.models.mongo.test;
 
-import java.util.List;
-
 import org.keycloak.models.mongo.api.AbstractNoSQLObject;
 import org.keycloak.models.mongo.api.NoSQLCollection;
 import org.keycloak.models.mongo.api.NoSQLField;
 import org.keycloak.models.mongo.api.NoSQLId;
 
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java
index 24e1f03..06e0736 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java
@@ -3,8 +3,7 @@ package org.keycloak.models.picketlink.mappings;
 import org.picketlink.idm.model.AbstractPartition;
 import org.picketlink.idm.model.annotation.AttributeProperty;
 
-import java.io.Serializable;
-import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -26,8 +25,8 @@ public class RealmData extends AbstractPartition {
     private String publicKeyPem;
     private String privateKeyPem;
     private String[] defaultRoles;
-    private HashMap<String, String> smtpConfig;
-    private HashMap<String, String> socialConfig;
+    private Map<String, String> smtpConfig;
+    private Map<String, String> socialConfig;
 
     public RealmData() {
         super(null);
@@ -170,20 +169,20 @@ public class RealmData extends AbstractPartition {
     }
 
     @AttributeProperty
-    public HashMap<String, String> getSmtpConfig() {
+    public Map<String, String> getSmtpConfig() {
         return smtpConfig;
     }
 
-    public void setSmtpConfig(HashMap<String, String> smtpConfig) {
+    public void setSmtpConfig(Map<String, String> smtpConfig) {
         this.smtpConfig = smtpConfig;
     }
 
     @AttributeProperty
-    public HashMap<String, String> getSocialConfig() {
+    public Map<String, String> getSocialConfig() {
         return socialConfig;
     }
 
-    public void setSocialConfig(HashMap<String, String> socialConfig) {
+    public void setSocialConfig(Map<String, String> socialConfig) {
         this.socialConfig = socialConfig;
     }
 }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java
index 74a3f09..4be31e6 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java
@@ -5,7 +5,11 @@ import org.picketlink.idm.jpa.annotations.OwnerReference;
 import org.picketlink.idm.jpa.annotations.entity.IdentityManaged;
 import org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity;
 
-import javax.persistence.*;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.OneToOne;
 import java.io.Serializable;
 import java.util.HashMap;
 
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java
index 310b4ce..474a0b5 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java
@@ -31,14 +31,4 @@ public class OAuthClientAdapter implements OAuthClientModel {
        return new UserAdapter(delegate.getOauthAgent(), idm);
     }
 
-    @Override
-    public String getBaseUrl() {
-        return delegate.getBaseUrl();
-    }
-
-    @Override
-    public void setBaseUrl(String base) {
-        delegate.setBaseUrl(base);
-        relationshipManager.update(delegate);
-    }
 }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkKeycloakSession.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkKeycloakSession.java
index 7d17339..fcaf72e 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkKeycloakSession.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkKeycloakSession.java
@@ -5,7 +5,6 @@ import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.picketlink.mappings.RealmData;
-import org.keycloak.models.picketlink.relationships.RealmAdminRelationship;
 import org.keycloak.models.picketlink.relationships.RealmListingRelationship;
 import org.keycloak.models.utils.KeycloakSessionUtils;
 import org.picketlink.idm.PartitionManager;
@@ -15,7 +14,6 @@ import org.picketlink.idm.query.RelationshipQuery;
 import javax.persistence.EntityManager;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java
new file mode 100755
index 0000000..67f4d7a
--- /dev/null
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/PicketlinkModelProvider.java
@@ -0,0 +1,77 @@
+package org.keycloak.models.picketlink;
+
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.ModelProvider;
+import org.keycloak.models.picketlink.mappings.ApplicationEntity;
+import org.keycloak.models.picketlink.mappings.RealmEntity;
+import org.picketlink.idm.PartitionManager;
+import org.picketlink.idm.config.IdentityConfigurationBuilder;
+import org.picketlink.idm.internal.DefaultPartitionManager;
+import org.picketlink.idm.jpa.internal.JPAContextInitializer;
+import org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity;
+import org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class PicketlinkModelProvider implements ModelProvider {
+    @Override
+    public KeycloakSessionFactory createFactory() {
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory("picketlink-keycloak-identity-store");
+        return new PicketlinkKeycloakSessionFactory(emf, buildPartitionManager());
+    }
+
+    public static PartitionManager buildPartitionManager() {
+        IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
+
+        builder
+                .named("KEYCLOAK_JPA_CONFIG")
+                .stores()
+                .jpa()
+                .mappedEntity(
+                        AttributedTypeEntity.class,
+                        AccountTypeEntity.class,
+                        RoleTypeEntity.class,
+                        GroupTypeEntity.class,
+                        IdentityTypeEntity.class,
+                        RelationshipTypeEntity.class,
+                        RelationshipIdentityTypeEntity.class,
+                        PartitionTypeEntity.class,
+                        PasswordCredentialTypeEntity.class,
+                        DigestCredentialTypeEntity.class,
+                        X509CredentialTypeEntity.class,
+                        OTPCredentialTypeEntity.class,
+                        AttributeTypeEntity.class,
+                        RealmEntity.class,
+                        ApplicationEntity.class
+                )
+                .supportGlobalRelationship(org.picketlink.idm.model.Relationship.class)
+                .addContextInitializer(new JPAContextInitializer(null) {
+                    @Override
+                    public EntityManager getEntityManager() {
+                        return PicketlinkKeycloakSession.currentEntityManager.get();
+                    }
+                })
+                .supportAllFeatures();
+
+        DefaultPartitionManager partitionManager = new DefaultPartitionManager(builder.buildAll());
+        return partitionManager;
+    }
+
+}
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
index 58c44b4..3279abf 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
@@ -2,11 +2,25 @@ package org.keycloak.models.picketlink;
 
 import org.bouncycastle.openssl.PEMWriter;
 import org.keycloak.PemUtils;
-import org.keycloak.models.*;
-import org.keycloak.models.picketlink.mappings.RealmData;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.IdGenerator;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.OAuthClientModel;
+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.picketlink.mappings.ApplicationData;
-import org.keycloak.models.picketlink.relationships.*;
+import org.keycloak.models.picketlink.mappings.RealmData;
+import org.keycloak.models.picketlink.relationships.ApplicationRelationship;
+import org.keycloak.models.picketlink.relationships.OAuthClientRelationship;
+import org.keycloak.models.picketlink.relationships.OAuthClientRequiredCredentialRelationship;
 import org.keycloak.models.picketlink.relationships.RequiredApplicationCredentialRelationship;
+import org.keycloak.models.picketlink.relationships.RequiredCredentialRelationship;
+import org.keycloak.models.picketlink.relationships.ScopeRelationship;
+import org.keycloak.models.picketlink.relationships.SocialLinkRelationship;
 import org.picketlink.idm.IdentityManager;
 import org.picketlink.idm.PartitionManager;
 import org.picketlink.idm.RelationshipManager;
@@ -595,7 +609,6 @@ public class RealmAdapter implements RealmModel {
         idm.add(resourceUser);
         applicationData.setResourceUser(resourceUser);
         applicationData.setResourceName(name);
-        applicationData.setResourceUser(resourceUser);
         partitionManager.add(applicationData);
         ApplicationRelationship resourceRelationship = new ApplicationRelationship();
         resourceRelationship.setRealm(realm.getName());
@@ -749,12 +762,14 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public List<String> getDefaultRoles() {
-        if (realm.getDefaultRoles() != null) {
-            return Arrays.asList(realm.getDefaultRoles());
-        }
-        else {
-            return Collections.emptyList();
+        if (realm.getDefaultRoles() == null) return Collections.emptyList();
+        List<String> list = new ArrayList<String>();
+        for (String role : realm.getDefaultRoles()) {
+            RoleModel model = getRole(role);
+            if (model == null) throw new RuntimeException("default role missing");
+            list.add(role);
         }
+        return list;
     }
 
     @Override
@@ -865,23 +880,23 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
-    public HashMap<String, String> getSmtpConfig() {
+    public Map<String, String> getSmtpConfig() {
         return realm.getSmtpConfig();
     }
 
     @Override
-    public void setSmtpConfig(HashMap<String, String> smtpConfig) {
+    public void setSmtpConfig(Map<String, String> smtpConfig) {
         realm.setSmtpConfig(smtpConfig);
         updateRealm();
     }
 
     @Override
-    public HashMap<String, String> getSocialConfig() {
+    public Map<String, String> getSocialConfig() {
         return realm.getSocialConfig();
     }
 
     @Override
-    public void setSocialConfig(HashMap<String, String> socialConfig) {
+    public void setSocialConfig(Map<String, String> socialConfig) {
         realm.setSocialConfig(socialConfig);
         updateRealm();
     }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/RealmListingRelationship.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/RealmListingRelationship.java
index 26636e6..bb4856a 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/RealmListingRelationship.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/RealmListingRelationship.java
@@ -3,9 +3,7 @@ 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.sample.User;
 import org.picketlink.idm.query.AttributeParameter;
-import org.picketlink.idm.query.RelationshipQueryParameter;
 
 /**
  * Picketlink doesn't allow you to query for all partitions, thus this stupid relationship...
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/UserAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/UserAdapter.java
index e44c92a..2555f74 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/UserAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/UserAdapter.java
@@ -1,17 +1,16 @@
 package org.keycloak.models.picketlink;
 
+import org.keycloak.models.UserModel;
+import org.picketlink.idm.IdentityManager;
+import org.picketlink.idm.model.Attribute;
+import org.picketlink.idm.model.sample.User;
+
 import java.io.Serializable;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-import org.keycloak.models.UserModel;
-import org.picketlink.idm.IdentityManager;
-import org.picketlink.idm.model.Attribute;
-import org.picketlink.idm.model.sample.User;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $

model/pom.xml 2(+1 -1)

diff --git a/model/pom.xml b/model/pom.xml
index 7e2fca5..26992ca 100755
--- a/model/pom.xml
+++ b/model/pom.xml
@@ -37,6 +37,6 @@
         <module>api</module>
         <module>picketlink</module>
         <module>jpa</module>
-        <!--<module>mongo</module>-->
+        <!-- <module>mongo</module> -->
     </modules>
 </project>

pom.xml 4(+2 -2)

diff --git a/pom.xml b/pom.xml
index c050cc9..7351a4c 100755
--- a/pom.xml
+++ b/pom.xml
@@ -9,8 +9,8 @@
     <packaging>pom</packaging>
 
     <properties>
-        <resteasy.version>3.0.4.Final</resteasy.version>
-        <undertow.version>1.0.0.Beta12</undertow.version>
+        <resteasy.version>3.0.5.Final</resteasy.version>
+        <undertow.version>1.0.0.Beta21</undertow.version>
         <picketlink.version>2.5.0.Beta6</picketlink.version>
         <mongo.driver.version>2.11.2</mongo.driver.version>
         <jboss.logging.version>3.1.1.GA</jboss.logging.version>

services/pom.xml 6(+6 -0)

diff --git a/services/pom.xml b/services/pom.xml
index 52d2ab8..1df957c 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -33,6 +33,12 @@
             <groupId>org.keycloak</groupId>
             <artifactId>keycloak-model-picketlink</artifactId>
             <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-jpa</artifactId>
+            <version>${project.version}</version>
         </dependency>
 
         <!--<dependency>
diff --git a/services/src/main/java/org/keycloak/services/email/EmailSender.java b/services/src/main/java/org/keycloak/services/email/EmailSender.java
index 960410c..185ca83 100755
--- a/services/src/main/java/org/keycloak/services/email/EmailSender.java
+++ b/services/src/main/java/org/keycloak/services/email/EmailSender.java
@@ -21,28 +21,25 @@
  */
 package org.keycloak.services.email;
 
-import java.net.URI;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
+import org.jboss.resteasy.logging.Logger;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.services.managers.AccessCodeEntry;
+import org.keycloak.services.resources.flows.Urls;
 
 import javax.mail.Message;
 import javax.mail.MessagingException;
 import javax.mail.Session;
 import javax.mail.Transport;
-import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
-
-import org.jboss.resteasy.logging.Logger;
-import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.services.resources.AccountService;
-import org.keycloak.services.resources.flows.Urls;
+import java.net.URI;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
index d662661..cb2bc5a 100755
--- a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
+++ b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
@@ -5,7 +5,12 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.KeycloakTransaction;
 
-import javax.servlet.*;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import java.io.IOException;
 
 /**
diff --git a/services/src/main/java/org/keycloak/services/FormService.java b/services/src/main/java/org/keycloak/services/FormService.java
index 210fad6..9a357a3 100755
--- a/services/src/main/java/org/keycloak/services/FormService.java
+++ b/services/src/main/java/org/keycloak/services/FormService.java
@@ -21,21 +21,20 @@
  */
 package org.keycloak.services;
 
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.imageio.spi.ServiceRegistry;
-import javax.ws.rs.core.MultivaluedMap;
-
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.services.resources.flows.FormFlows;
 import org.keycloak.social.SocialProvider;
 
+import javax.imageio.spi.ServiceRegistry;
+import javax.ws.rs.core.MultivaluedMap;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 /**
  * @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
  */
@@ -95,7 +94,7 @@ public interface FormService {
             this.message = message;
 
             socialProviders = new LinkedList<SocialProvider>();
-            HashMap<String, String> socialConfig = realm.getSocialConfig();
+            Map<String, String> socialConfig = realm.getSocialConfig();
             if (socialConfig != null) {
                 for (Iterator<SocialProvider> itr = ServiceRegistry.lookupProviders(org.keycloak.social.SocialProvider.class); itr.hasNext(); ) {
                     SocialProvider p = itr.next();
diff --git a/services/src/main/java/org/keycloak/services/listeners/MongoRunnerListener.java b/services/src/main/java/org/keycloak/services/listeners/MongoRunnerListener.java
old mode 100644
new mode 100755
index f0df0a6..a1f6788
--- a/services/src/main/java/org/keycloak/services/listeners/MongoRunnerListener.java
+++ b/services/src/main/java/org/keycloak/services/listeners/MongoRunnerListener.java
@@ -1,8 +1,5 @@
 package org.keycloak.services.listeners;
 
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
 import de.flapdoodle.embed.mongo.MongodExecutable;
 import de.flapdoodle.embed.mongo.MongodProcess;
 import de.flapdoodle.embed.mongo.MongodStarter;
@@ -12,6 +9,9 @@ import de.flapdoodle.embed.process.runtime.Network;
 import org.jboss.resteasy.logging.Logger;
 import org.keycloak.services.utils.PropertiesManager;
 
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
index 9dceed8..07bebe3 100755
--- a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
+++ b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
@@ -1,10 +1,10 @@
 package org.keycloak.services.managers;
 
 import org.keycloak.models.RealmModel;
-import org.keycloak.representations.SkeletonKeyToken;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.representations.SkeletonKeyToken;
 
 import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index 9d36f8f..3754164 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -1,6 +1,12 @@
 package org.keycloak.services.managers;
 
-import org.keycloak.models.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 
 import java.util.UUID;
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index fc854a3..67a8286 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -1,14 +1,23 @@
 package org.keycloak.services.managers;
 
+import org.jboss.resteasy.logging.Logger;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.ScopeMappingRepresentation;
+import org.keycloak.representations.idm.UserRoleMappingRepresentation;
+
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
-import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
-import org.keycloak.representations.idm.*;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -69,12 +78,15 @@ public class ApplicationManager {
         if (resourceRep.getRoleMappings() != null) {
             for (UserRoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
                 UserModel user = realm.getUser(mapping.getUsername());
+                if (user == null) {
+                    throw new RuntimeException("User not found");
+                }
                 for (String roleString : mapping.getRoles()) {
                     RoleModel role = applicationModel.getRole(roleString.trim());
                     if (role == null) {
                         role = applicationModel.addRole(roleString.trim());
                     }
-                    realm.grantRole(user, role);
+                    applicationModel.grantRole(user, role);
                 }
             }
         }
@@ -142,7 +154,7 @@ public class ApplicationManager {
         }
 
         if (!applicationModel.getDefaultRoles().isEmpty()) {
-            rep.setDefaultRoles((String[]) applicationModel.getDefaultRoles().toArray());
+            rep.setDefaultRoles(applicationModel.getDefaultRoles().toArray(new String[0]));
         }
 
         return rep;
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index bc50831..a3434b3 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -8,17 +8,21 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.RSATokenVerifier;
 import org.keycloak.VerificationException;
 import org.keycloak.models.Constants;
-import org.keycloak.representations.SkeletonKeyToken;
-import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.SkeletonKeyToken;
+import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.resources.AccountService;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.SaasService;
 
 import javax.ws.rs.NotAuthorizedException;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.UriInfo;
 import java.net.URI;
 import java.util.HashSet;
 import java.util.List;
diff --git a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
index 0b10d61..7840566 100755
--- a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -26,19 +26,16 @@ public class OAuthClientManager {
 
     public OAuthClientModel create(OAuthClientRepresentation rep) {
         OAuthClientModel model = create(rep.getName());
-        model.setBaseUrl(rep.getBaseUrl());
         model.getOAuthAgent().setEnabled(rep.isEnabled());
         return model;
     }
 
     public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
-        model.setBaseUrl(rep.getBaseUrl());
     }
 
     public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
         OAuthClientRepresentation rep = new OAuthClientRepresentation();
         rep.setId(model.getId());
-        rep.setBaseUrl(model.getBaseUrl());
         rep.setName(model.getOAuthAgent().getLoginName());
         rep.setEnabled(model.getOAuthAgent().isEnabled());
         return rep;
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 017a08c..8cd43a0 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -1,14 +1,36 @@
 package org.keycloak.services.managers;
 
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
-import org.keycloak.representations.idm.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.ScopeMappingRepresentation;
+import org.keycloak.representations.idm.SocialLinkRepresentation;
+import org.keycloak.representations.idm.SocialMappingRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.representations.idm.UserRoleMappingRepresentation;
 
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.NoSuchAlgorithmException;
-import java.util.*;
+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.UUID;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -88,7 +110,7 @@ public class RealmManager {
             realm.updateRequiredApplicationCredentials(rep.getRequiredApplicationCredentials());
         }
         if (rep.getDefaultRoles() != null) {
-            realm.updateDefaultRoles(rep.getDefaultRoles());
+            realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()]));
         }
 
         if (rep.getAccountManagement() != null && rep.getAccountManagement()) {
@@ -431,7 +453,9 @@ public class RealmManager {
 
         List<String> defaultRoles = realm.getDefaultRoles();
         if (!defaultRoles.isEmpty()) {
-            rep.setDefaultRoles((String[]) realm.getDefaultRoles().toArray());
+            List<String> roleStrings = new ArrayList<String>();
+            roleStrings.addAll(defaultRoles);
+            rep.setDefaultRoles(roleStrings);
         }
 
         List<RequiredCredentialModel> requiredCredentialModels = realm.getRequiredCredentials();
diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
index 5425cd8..cee3047 100755
--- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
@@ -4,9 +4,9 @@ import org.jboss.resteasy.client.jaxrs.ResteasyClient;
 import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
 import org.jboss.resteasy.logging.Logger;
 import org.keycloak.TokenIdGenerator;
-import org.keycloak.representations.idm.admin.LogoutAction;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.representations.idm.admin.LogoutAction;
 
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Form;
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index e7cb2ff..1fe7768 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -4,14 +4,21 @@ import org.jboss.resteasy.jose.Base64Url;
 import org.jboss.resteasy.jose.jws.JWSBuilder;
 import org.jboss.resteasy.jwt.JsonSerialization;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.SkeletonKeyScope;
 import org.keycloak.representations.SkeletonKeyToken;
 
 import javax.ws.rs.core.MultivaluedMap;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
-import java.util.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -45,7 +52,6 @@ public class TokenManager {
         List<RoleModel> realmRolesRequested = code.getRealmRolesRequested();
         MultivaluedMap<String, RoleModel> resourceRolesRequested = code.getResourceRolesRequested();
         Set<String> realmMapping = realm.getRoleMappingValues(user);
-        realmMapping.addAll(realm.getDefaultRoles());
 
         if (realmMapping != null && realmMapping.size() > 0 && (scopeMap == null || scopeMap.containsKey("realm"))) {
             Set<String> scope = realm.getScopeMappingValues(client);
@@ -69,8 +75,6 @@ public class TokenManager {
         }
         for (ApplicationModel resource : realm.getApplications()) {
             Set<String> mapping = resource.getRoleMappingValues(user);
-            mapping.addAll(resource.getDefaultRoles());
-
             if (mapping != null && mapping.size() > 0 && (scopeMap == null || scopeMap.containsKey(resource.getName()))) {
                 Set<String> scope = resource.getScopeMappingValues(client);
                 if (scope.size() > 0) {
@@ -188,7 +192,6 @@ public class TokenManager {
         }
 
         Set<String> realmMapping = realm.getRoleMappingValues(user);
-        realmMapping.addAll(realm.getDefaultRoles());
 
         if (realmMapping != null && realmMapping.size() > 0) {
             SkeletonKeyToken.Access access = new SkeletonKeyToken.Access();
@@ -200,8 +203,6 @@ public class TokenManager {
         if (resources != null) {
             for (ApplicationModel resource : resources) {
                 Set<String> mapping = resource.getRoleMappingValues(user);
-                mapping.addAll(resource.getDefaultRoles());
-
                 if (mapping == null) continue;
                 SkeletonKeyToken.Access access = token.addAccess(resource.getName())
                         .verifyCaller(resource.isSurrogateAuthRequired());
diff --git a/services/src/main/java/org/keycloak/services/managers/UserManager.java b/services/src/main/java/org/keycloak/services/managers/UserManager.java
index 4d7a7ec..1ce544a 100755
--- a/services/src/main/java/org/keycloak/services/managers/UserManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/UserManager.java
@@ -1,10 +1,10 @@
 package org.keycloak.services.managers;
 
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
 
 import java.util.Map;
 
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 799b101..584ef1c 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -28,6 +28,7 @@ import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.AbstractOAuthClient;
 import org.keycloak.jaxrs.JaxrsOAuthClient;
 import org.keycloak.models.*;
+import org.keycloak.models.utils.TimeBasedOTP;
 import org.keycloak.representations.SkeletonKeyToken;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AccessCodeEntry;
@@ -40,7 +41,6 @@ import org.keycloak.services.resources.flows.FormFlows;
 import org.keycloak.services.resources.flows.Pages;
 import org.keycloak.services.resources.flows.Urls;
 import org.keycloak.services.validation.Validation;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.*;
@@ -373,7 +373,8 @@ public class AccountService {
         UserModel client = auth.getClient();
         if (realm.hasRole(client, Constants.APPLICATION_ROLE)) {
             // Tokens from cookies don't have roles
-            if (hasRole(client, Constants.ACCOUNT_MANAGE_ROLE) || (role != null && hasRole(client, role))) {
+            UserModel user = auth.getUser();
+            if (hasRole(user, Constants.ACCOUNT_MANAGE_ROLE) || (role != null && hasRole(user, role))) {
                 return true;
             }
         }
@@ -389,9 +390,6 @@ public class AccountService {
     }
 
     private boolean hasRole(UserModel user, String role) {
-        if (application.getDefaultRoles().contains(role)) {
-            return true;
-        }
         return application.hasRole(user, role);
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index 9177495..7a1e229 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -2,17 +2,24 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
-import org.keycloak.representations.idm.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.ApplicationManager;
 import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.*;
+import java.util.List;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index 40e3ca7..29cc957 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -2,15 +2,20 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.services.managers.ApplicationManager;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.services.managers.ApplicationManager;
+import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.container.ResourceContext;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index f588ab2..f7a2286 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -2,15 +2,20 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
-import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
-import org.keycloak.services.managers.ApplicationManager;
 import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import java.util.List;
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index 2873767..408a48f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -2,18 +2,19 @@ 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.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
-import org.keycloak.services.managers.ApplicationManager;
 import org.keycloak.services.managers.OAuthClientManager;
-import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
-import javax.ws.rs.container.ResourceContext;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 8b552d8..ec4ae9b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -2,18 +2,19 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
 import javax.ws.rs.container.ResourceContext;
 import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index c7e0262..fb4bfeb 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -2,16 +2,27 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.SaasService;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.container.ResourceContext;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index 0c02a78..c0c0a5f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -5,7 +5,15 @@ import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.representations.idm.RoleRepresentation;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.InternalServerErrorException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
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 d093e16..f3f91ef 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
@@ -1,13 +1,24 @@
 package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
-import org.keycloak.models.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
 import org.keycloak.representations.idm.MappingsRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
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 600c2ad..029d4c9 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
@@ -2,11 +2,30 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.models.*;
-import org.keycloak.representations.idm.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.MappingsRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.InternalServerErrorException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.container.ResourceContext;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
diff --git a/services/src/main/java/org/keycloak/services/resources/Cors.java b/services/src/main/java/org/keycloak/services/resources/Cors.java
old mode 100644
new mode 100755
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Flows.java b/services/src/main/java/org/keycloak/services/resources/flows/Flows.java
index c8711ea..41aa04f 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Flows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Flows.java
@@ -22,9 +22,9 @@
 package org.keycloak.services.resources.flows;
 
 import org.jboss.resteasy.spi.HttpRequest;
+import org.keycloak.models.RealmModel;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.TokenManager;
-import org.keycloak.models.RealmModel;
 
 import javax.ws.rs.core.UriInfo;
 
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
index 68df5a9..3dcd6b5 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
@@ -21,21 +21,16 @@
  */
 package org.keycloak.services.resources.flows;
 
-import java.net.URI;
-import java.util.Iterator;
-import java.util.List;
-
 import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.ResteasyUriInfo;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.services.FormService;
 import org.keycloak.services.email.EmailSender;
 import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.services.messages.Messages;
-import org.picketlink.idm.model.sample.Realm;
 
 import javax.imageio.spi.ServiceRegistry;
 import javax.ws.rs.core.MediaType;
@@ -43,6 +38,9 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -51,7 +49,6 @@ public class FormFlows {
 
     public static final String DATA = "KEYCLOAK_FORMS_DATA";
     public static final String ERROR_MESSAGE = "KEYCLOAK_FORMS_ERROR_MESSAGE";
-    public static final String REALM = Realm.class.getName();
     public static final String USER = UserModel.class.getName();
     public static final String SOCIAL_REGISTRATION = "socialRegistration";
     public static final String CODE = "code";
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
index cc12de2..b178df9 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
@@ -21,24 +21,23 @@
  */
 package org.keycloak.services.resources.flows;
 
-import java.util.HashSet;
-import java.util.Set;
-
 import org.jboss.resteasy.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.models.Constants;
-import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.managers.TokenManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.services.managers.AccessCodeEntry;
+import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.managers.TokenManager;
 import org.keycloak.services.resources.TokenService;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -68,7 +67,8 @@ public class OAuthFlows {
     }
 
     public Response redirectAccessCode(AccessCodeEntry accessCode, String state, String redirect) {
-        Set<String> redirectUris = accessCode.getClient().getRedirectUris();
+        UserModel client = realm.getUser(accessCode.getClient().getLoginName());
+        Set<String> redirectUris = client.getRedirectUris();
         if (!redirectUris.isEmpty() && !redirectUris.contains(redirect)) {
             return forwardToSecurityFailure("Invalid redirect_uri " + redirect);
         }
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index b9f457a..a2061aa 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -21,7 +21,12 @@
  */
 package org.keycloak.services.resources.flows;
 
-import org.keycloak.services.resources.*;
+import org.keycloak.services.resources.AccountService;
+import org.keycloak.services.resources.RealmsResource;
+import org.keycloak.services.resources.RequiredActionsService;
+import org.keycloak.services.resources.SaasService;
+import org.keycloak.services.resources.SocialResource;
+import org.keycloak.services.resources.TokenService;
 
 import javax.ws.rs.core.UriBuilder;
 import java.net.URI;
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 96e922d..867c2c1 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -1,28 +1,16 @@
 package org.keycloak.services.resources;
 
 import org.keycloak.SkeletonKeyContextResolver;
-import org.keycloak.services.managers.TokenManager;
 import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.picketlink.PicketlinkKeycloakSession;
-import org.keycloak.models.picketlink.PicketlinkKeycloakSessionFactory;
-import org.keycloak.models.picketlink.mappings.ApplicationEntity;
-import org.keycloak.models.picketlink.mappings.RealmEntity;
-import org.keycloak.services.utils.PropertiesManager;
+import org.keycloak.models.ModelProvider;
 import org.keycloak.services.managers.SocialRequestManager;
-import org.picketlink.idm.PartitionManager;
-import org.picketlink.idm.config.IdentityConfigurationBuilder;
-import org.picketlink.idm.internal.DefaultPartitionManager;
-import org.picketlink.idm.jpa.internal.JPAContextInitializer;
-import org.picketlink.idm.jpa.model.sample.simple.*;
+import org.keycloak.services.managers.TokenManager;
+import org.keycloak.services.utils.PropertiesManager;
 
 import javax.annotation.PreDestroy;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
 import javax.servlet.ServletContext;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Context;
-
 import java.lang.reflect.Constructor;
 import java.util.HashSet;
 import java.util.Set;
@@ -62,14 +50,32 @@ public class KeycloakApplication extends Application {
             return buildMongoDBSessionFactory();
         } else if (PropertiesManager.isPicketlinkSessionFactory()) {
             return buildPicketlinkSessionFactory();
+        } else if (PropertiesManager.isJpaSessionFactory()) {
+            return buildJpaSessionFactory();
         } else {
             throw new IllegalStateException("Unknown session factory type: " + PropertiesManager.getSessionFactoryType());
         }
     }
 
+    private static KeycloakSessionFactory buildJpaSessionFactory() {
+        ModelProvider provider = null;
+        try {
+            provider = (ModelProvider)Class.forName("org.keycloak.models.jpa.JpaModelProvider").newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return provider.createFactory();
+    }
+
+
     private static KeycloakSessionFactory buildPicketlinkSessionFactory() {
-        EntityManagerFactory emf = Persistence.createEntityManagerFactory("keycloak-identity-store");
-        return new PicketlinkKeycloakSessionFactory(emf, buildPartitionManager());
+        ModelProvider provider = null;
+        try {
+            provider = (ModelProvider)Class.forName("org.keycloak.models.picketlink.PicketlinkModelProvider").newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return provider.createFactory();
     }
 
     private static KeycloakSessionFactory buildMongoDBSessionFactory() {
@@ -97,46 +103,7 @@ public class KeycloakApplication extends Application {
         factory.close();
     }
 
-    public PartitionManager createPartitionManager() {
-        return buildPartitionManager();
-    }
 
-    public static PartitionManager buildPartitionManager() {
-        IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
-
-        builder
-                .named("KEYCLOAK_JPA_CONFIG")
-                .stores()
-                .jpa()
-                .mappedEntity(
-                        AttributedTypeEntity.class,
-                        AccountTypeEntity.class,
-                        RoleTypeEntity.class,
-                        GroupTypeEntity.class,
-                        IdentityTypeEntity.class,
-                        RelationshipTypeEntity.class,
-                        RelationshipIdentityTypeEntity.class,
-                        PartitionTypeEntity.class,
-                        PasswordCredentialTypeEntity.class,
-                        DigestCredentialTypeEntity.class,
-                        X509CredentialTypeEntity.class,
-                        OTPCredentialTypeEntity.class,
-                        AttributeTypeEntity.class,
-                        RealmEntity.class,
-                        ApplicationEntity.class
-                )
-                .supportGlobalRelationship(org.picketlink.idm.model.Relationship.class)
-                .addContextInitializer(new JPAContextInitializer(null) {
-                    @Override
-                    public EntityManager getEntityManager() {
-                        return PicketlinkKeycloakSession.currentEntityManager.get();
-                    }
-                })
-                .supportAllFeatures();
-
-        DefaultPartitionManager partitionManager = new DefaultPartitionManager(builder.buildAll());
-        return partitionManager;
-    }
 
 
     @Override
diff --git a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
index 03b7d5f..01094b4 100755
--- a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
@@ -2,8 +2,8 @@ package org.keycloak.services.resources;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.representations.idm.PublishedRealmRepresentation;
 import org.keycloak.models.RealmModel;
+import org.keycloak.representations.idm.PublishedRealmRepresentation;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
diff --git a/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java b/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java
old mode 100644
new mode 100755
index 9d02111..3ae4b67
--- a/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/QRCodeResource.java
@@ -7,7 +7,11 @@ import com.google.zxing.common.BitMatrix;
 import com.google.zxing.qrcode.QRCodeWriter;
 
 import javax.servlet.ServletException;
-import javax.ws.rs.*;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.StreamingOutput;
 import java.io.IOException;
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index 0e1bc0f..f96f343 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -3,10 +3,10 @@ package org.keycloak.services.resources;
 import org.jboss.resteasy.logging.Logger;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.Constants;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.managers.TokenManager;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.managers.TokenManager;
 
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.Path;
diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
index 40f0ed8..3199c01 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -29,6 +29,7 @@ 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.email.EmailSender;
 import org.keycloak.services.managers.AccessCodeEntry;
@@ -38,13 +39,17 @@ import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.FormFlows;
 import org.keycloak.services.validation.Validation;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.Providers;
 import java.util.HashSet;
 import java.util.Set;
diff --git a/services/src/main/java/org/keycloak/services/resources/SaasService.java b/services/src/main/java/org/keycloak/services/resources/SaasService.java
index 534307c..ef936df 100755
--- a/services/src/main/java/org/keycloak/services/resources/SaasService.java
+++ b/services/src/main/java/org/keycloak/services/resources/SaasService.java
@@ -9,8 +9,12 @@ import org.jboss.resteasy.spi.HttpResponse;
 import org.jboss.resteasy.spi.NotImplementedYetException;
 import org.keycloak.AbstractOAuthClient;
 import org.keycloak.jaxrs.JaxrsOAuthClient;
-import org.keycloak.models.*;
-import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.services.managers.AccessCodeEntry;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
@@ -21,13 +25,27 @@ import org.keycloak.services.resources.admin.RealmsAdminResource;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.OAuthFlows;
 
-import javax.ws.rs.*;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.ForbiddenException;
+import javax.ws.rs.GET;
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.container.ResourceContext;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.Providers;
 import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -246,6 +264,7 @@ public class SaasService {
     @GET
     @NoCache
     public Response loginPage() {
+        logger.debug("loginPage ********************** <---");
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = getAdminstrationRealm(realmManager);
         authManager.expireSaasIdentityCookie(uriInfo);
@@ -271,7 +290,7 @@ public class SaasService {
 
                                   ) {
         try {
-            logger.debug("loginRedirect ********************** <---");
+            logger.info("loginRedirect ********************** <---");
             if (error != null) {
                 logger.debug("error from oauth");
                 throw new ForbiddenException("error");
diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
index 573da77..908844c 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -21,37 +21,15 @@
  */
 package org.keycloak.services.resources;
 
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-
-import javax.imageio.spi.ServiceRegistry;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.container.ResourceContext;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Cookie;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.NewCookie;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-
 import org.jboss.resteasy.logging.Logger;
 import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.HttpResponse;
-import org.keycloak.models.*;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
@@ -68,6 +46,31 @@ import org.keycloak.social.SocialProviderException;
 import org.keycloak.services.managers.SocialRequestManager;
 import org.keycloak.social.SocialUser;
 
+import javax.imageio.spi.ServiceRegistry;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.container.ResourceContext;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
@@ -170,6 +173,7 @@ public class SocialResource {
                     // already registered. But actually Keycloak allows duplicate emails
                 } else {
                     user = realm.addUser(socialUser.getUsername());
+                    user.setEnabled(true);
                     user.setFirstName(socialUser.getFirstName());
                     user.setLastName(socialUser.getLastName());
                     user.setEmail(socialUser.getEmail());
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index c825004..580473b 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -8,7 +8,16 @@ import org.jboss.resteasy.jwt.JsonSerialization;
 import org.jboss.resteasy.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.HttpResponse;
-import org.keycloak.models.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.representations.AccessTokenResponse;
 import org.keycloak.representations.SkeletonKeyToken;
 import org.keycloak.representations.idm.CredentialRepresentation;
@@ -18,7 +27,6 @@ import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.TokenManager;
 import org.keycloak.services.messages.Messages;
-import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.OAuthFlows;
 import org.keycloak.services.validation.Validation;
@@ -40,9 +48,11 @@ import javax.ws.rs.core.SecurityContext;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.Providers;
-
 import java.security.PrivateKey;
-import java.util.*;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -262,18 +272,22 @@ public class TokenService {
         OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
 
         if (!realm.isEnabled()) {
+            logger.warn("Realm not enabled");
             return oauth.forwardToSecurityFailure("Realm not enabled");
         }
         UserModel client = realm.getUser(clientId);
         if (client == null) {
+            logger.warn("Unknown login requester.");
             return oauth.forwardToSecurityFailure("Unknown login requester.");
         }
 
         if (!client.isEnabled()) {
+            logger.warn("Login requester not enabled.");
             return oauth.forwardToSecurityFailure("Login requester not enabled.");
         }
 
         if (!realm.isRegistrationAllowed()) {
+            logger.warn("Registration not allowed");
             return oauth.forwardToSecurityFailure("Registration not allowed");
         }
 
@@ -297,6 +311,7 @@ public class TokenService {
         }
 
         user = realm.addUser(username);
+        user.setEnabled(true);
         user.setFirstName(formData.getFirst("firstName"));
         user.setLastName(formData.getFirst("lastName"));
 
@@ -309,6 +324,17 @@ public class TokenService {
             realm.updateCredential(user, credentials);
         }
 
+        for (String r : realm.getDefaultRoles()) {
+            realm.grantRole(user, realm.getRole(r));
+        }
+
+        for (ApplicationModel application : realm.getApplications()) {
+            for (String r : application.getDefaultRoles()) {
+                application.grantRole(user, application.getRole(r));
+            }
+        }
+
+
         return null;
     }
 
@@ -409,7 +435,7 @@ public class TokenService {
         logger.debug("accessRequest SUCCESS");
         AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
 
-        return Cors.add(request, Response.ok(res)).allowedOrigins(client).build();
+        return Cors.add(request, Response.ok(res)).allowedOrigins(client).allowedMethods("POST").build();
     }
 
     protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) {
@@ -440,36 +466,41 @@ public class TokenService {
     public Response loginPage(final @QueryParam("response_type") String responseType,
             final @QueryParam("redirect_uri") String redirect, final @QueryParam("client_id") String clientId,
             final @QueryParam("scope") String scopeParam, final @QueryParam("state") String state, final @QueryParam("prompt") String prompt) {
+        logger.info("TokenService.loginPage");
         OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
 
         if (!realm.isEnabled()) {
+            logger.warn("Realm not enabled");
             oauth.forwardToSecurityFailure("Realm not enabled");
             return null;
         }
         UserModel client = realm.getUser(clientId);
         if (client == null) {
+            logger.warn("Unknown login requester: " + clientId);
             oauth.forwardToSecurityFailure("Unknown login requester.");
             transaction.rollback();
             return null;
         }
 
         if (!client.isEnabled()) {
+            logger.warn("Login requester not enabled.");
             oauth.forwardToSecurityFailure("Login requester not enabled.");
             transaction.rollback();
             session.close();
             return null;
         }
-
+        logger.info("Checking roles...");
         RoleModel resourceRole = realm.getRole(Constants.APPLICATION_ROLE);
         RoleModel identityRequestRole = realm.getRole(Constants.IDENTITY_REQUESTER_ROLE);
         boolean isResource = realm.hasRole(client, resourceRole);
         if (!isResource && !realm.hasRole(client, identityRequestRole)) {
+            logger.warn("Login requester not allowed to request login.");
             oauth.forwardToSecurityFailure("Login requester not allowed to request login.");
             transaction.rollback();
             session.close();
             return null;
         }
-
+        logger.info("Checking cookie...");
         UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
         if (user != null) {
             logger.debug(user.getLoginName() + " already logged in.");
@@ -479,7 +510,7 @@ public class TokenService {
         if (prompt != null && prompt.equals("none")) {
             return oauth.redirectError(client, "access_denied", state, redirect);
         }
-
+        logger.info("forwardToLogin() now...");
         return Flows.forms(realm, request, uriInfo).forwardToLogin();
     }
 
@@ -488,21 +519,26 @@ public class TokenService {
     public Response registerPage(final @QueryParam("response_type") String responseType,
             final @QueryParam("redirect_uri") String redirect, final @QueryParam("client_id") String clientId,
             final @QueryParam("scope") String scopeParam, final @QueryParam("state") String state) {
+        logger.info("**********registerPage()");
         OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
 
         if (!realm.isEnabled()) {
+            logger.warn("Realm not enabled");
             return oauth.forwardToSecurityFailure("Realm not enabled");
         }
         UserModel client = realm.getUser(clientId);
         if (client == null) {
+            logger.warn("Unknown login requester.");
             return oauth.forwardToSecurityFailure("Unknown login requester.");
         }
 
         if (!client.isEnabled()) {
+            logger.warn("Login requester not enabled.");
             return oauth.forwardToSecurityFailure("Login requester not enabled.");
         }
 
         if (!realm.isRegistrationAllowed()) {
+            logger.warn("Registration not allowed");
             return oauth.forwardToSecurityFailure("Registration not allowed");
         }
 
diff --git a/services/src/main/java/org/keycloak/services/utils/PropertiesManager.java b/services/src/main/java/org/keycloak/services/utils/PropertiesManager.java
old mode 100644
new mode 100755
index ee16547..583a8c8
--- a/services/src/main/java/org/keycloak/services/utils/PropertiesManager.java
+++ b/services/src/main/java/org/keycloak/services/utils/PropertiesManager.java
@@ -8,6 +8,7 @@ public class PropertiesManager {
     private static final String SESSION_FACTORY = "keycloak.sessionFactory";
     public static final String SESSION_FACTORY_PICKETLINK = "picketlink";
     public static final String SESSION_FACTORY_MONGO = "mongo";
+    public static final String SESSION_FACTORY_JPA = "jpa";
 
     private static final String MONGO_HOST = "keycloak.mongodb.host";
     private static final String MONGO_PORT = "keycloak.mongodb.port";
@@ -25,7 +26,7 @@ public class PropertiesManager {
     public static final int MONGO_DEFAULT_PORT_UNIT_TESTS = 27777;
 
     public static String getSessionFactoryType() {
-        return System.getProperty(SESSION_FACTORY, SESSION_FACTORY_PICKETLINK);
+        return System.getProperty(SESSION_FACTORY, SESSION_FACTORY_JPA);
     }
 
     public static void setSessionFactoryType(String sessionFactoryType) {
@@ -33,7 +34,7 @@ public class PropertiesManager {
     }
 
     public static void setDefaultSessionFactoryType() {
-        System.setProperty(SESSION_FACTORY, SESSION_FACTORY_PICKETLINK);
+        System.setProperty(SESSION_FACTORY, SESSION_FACTORY_JPA);
     }
 
     public static boolean isMongoSessionFactory() {
@@ -44,6 +45,11 @@ public class PropertiesManager {
         return getSessionFactoryType().equals(SESSION_FACTORY_PICKETLINK);
     }
 
+    public static boolean isJpaSessionFactory() {
+        return getSessionFactoryType().equals(SESSION_FACTORY_JPA);
+    }
+
+
     public static String getMongoHost() {
         return System.getProperty(MONGO_HOST, "localhost");
     }
diff --git a/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java b/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java
old mode 100644
new mode 100755
index 70a9456..e749f16
--- a/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java
+++ b/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java
@@ -1,21 +1,19 @@
 package org.keycloak.services.email;
 
-import java.io.IOException;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.net.SocketException;
-import java.util.HashMap;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.AddressException;
-import javax.mail.internet.MimeMessage;
-
+import com.icegreen.greenmail.util.GreenMail;
+import com.icegreen.greenmail.util.ServerSetup;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.icegreen.greenmail.util.GreenMail;
-import com.icegreen.greenmail.util.ServerSetup;
+import javax.mail.MessagingException;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.MimeMessage;
+import java.io.IOException;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.SocketException;
+import java.util.HashMap;
 
 public class EmailSenderTest {
 
diff --git a/services/src/test/java/org/keycloak/services/managers/AuthenticationManagerTest.java b/services/src/test/java/org/keycloak/services/managers/AuthenticationManagerTest.java
index a2049fd..4d67838 100755
--- a/services/src/test/java/org/keycloak/services/managers/AuthenticationManagerTest.java
+++ b/services/src/test/java/org/keycloak/services/managers/AuthenticationManagerTest.java
@@ -1,26 +1,21 @@
 package org.keycloak.services.managers;
 
-import java.util.UUID;
-
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
-import org.keycloak.services.resources.KeycloakApplication;
+import org.keycloak.models.utils.TimeBasedOTP;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
 import org.keycloak.test.common.AbstractKeycloakTest;
 import org.keycloak.test.common.SessionFactoryTestContext;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.UUID;
 
 public class AuthenticationManagerTest extends AbstractKeycloakTest {
 
@@ -144,6 +139,7 @@ public class AuthenticationManagerTest extends AbstractKeycloakTest {
         am = new AuthenticationManager();
 
         user = realm.addUser("test");
+        user.setEnabled(true);
 
         UserCredentialModel credential = new UserCredentialModel();
         credential.setType(CredentialRepresentation.PASSWORD);
diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java
index d6b178a..1c86dfe 100755
--- a/services/src/test/java/org/keycloak/test/AdapterTest.java
+++ b/services/src/test/java/org/keycloak/test/AdapterTest.java
@@ -4,16 +4,20 @@ import org.junit.Assert;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
-import org.keycloak.models.*;
+import org.keycloak.models.Constants;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.ApplianceBootstrap;
 import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.test.common.AbstractKeycloakTest;
 import org.keycloak.test.common.SessionFactoryTestContext;
 
-
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -163,9 +167,7 @@ public class AdapterTest extends AbstractKeycloakTest {
         test1CreateRealm();
 
         OAuthClientModel oauth = new OAuthClientManager(realmModel).create("oauth-client");
-        oauth.setBaseUrl("/foo/bar");
         oauth = realmModel.getOAuthClient("oauth-client");
-        Assert.assertEquals("/foo/bar", oauth.getBaseUrl());
         Assert.assertTrue(realmModel.hasRole(oauth.getOAuthAgent(), Constants.IDENTITY_REQUESTER_ROLE));
 
 
diff --git a/services/src/test/java/org/keycloak/test/ApplicationModelTest.java b/services/src/test/java/org/keycloak/test/ApplicationModelTest.java
old mode 100644
new mode 100755
index 5d0de1a..a5e2a01
--- a/services/src/test/java/org/keycloak/test/ApplicationModelTest.java
+++ b/services/src/test/java/org/keycloak/test/ApplicationModelTest.java
@@ -4,7 +4,12 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.keycloak.models.*;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+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 org.keycloak.services.managers.RealmManager;
@@ -13,8 +18,6 @@ import org.keycloak.services.resources.KeycloakApplication;
 import java.util.Iterator;
 import java.util.List;
 
-import static org.junit.Assert.assertNotNull;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java b/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java
index 0656f98..a6debbf 100755
--- a/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java
+++ b/services/src/test/java/org/keycloak/test/common/AbstractKeycloakTest.java
@@ -1,9 +1,5 @@
 package org.keycloak.test.common;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -15,6 +11,9 @@ import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
@@ -34,7 +33,8 @@ public abstract class AbstractKeycloakTest {
     {
         // TODO: MongoDB disabled by default
         TEST_CONTEXTS = new SessionFactoryTestContext[] {
-                new PicketlinkSessionFactoryTestContext(),
+                //new PicketlinkSessionFactoryTestContext(),
+                new JpaSessionFactoryTestContext(),
                 // new MongoDBSessionFactoryTestContext()
         };
     }
diff --git a/services/src/test/java/org/keycloak/test/common/JpaSessionFactoryTestContext.java b/services/src/test/java/org/keycloak/test/common/JpaSessionFactoryTestContext.java
new file mode 100755
index 0000000..94b8066
--- /dev/null
+++ b/services/src/test/java/org/keycloak/test/common/JpaSessionFactoryTestContext.java
@@ -0,0 +1,24 @@
+package org.keycloak.test.common;
+
+import org.keycloak.services.utils.PropertiesManager;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class JpaSessionFactoryTestContext implements SessionFactoryTestContext {
+
+    @Override
+    public void beforeTestClass() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void afterTestClass() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void initEnvironment() {
+        PropertiesManager.setSessionFactoryType(PropertiesManager.SESSION_FACTORY_JPA);
+    }
+}
diff --git a/services/src/test/java/org/keycloak/test/common/MongoDBSessionFactoryTestContext.java b/services/src/test/java/org/keycloak/test/common/MongoDBSessionFactoryTestContext.java
old mode 100644
new mode 100755
index def3f34..1b00fa5
--- a/services/src/test/java/org/keycloak/test/common/MongoDBSessionFactoryTestContext.java
+++ b/services/src/test/java/org/keycloak/test/common/MongoDBSessionFactoryTestContext.java
@@ -7,7 +7,6 @@ import de.flapdoodle.embed.mongo.config.MongodConfig;
 import de.flapdoodle.embed.mongo.distribution.Version;
 import de.flapdoodle.embed.process.runtime.Network;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.services.resources.KeycloakApplication;
 import org.keycloak.services.utils.PropertiesManager;
 
 /**
diff --git a/services/src/test/java/org/keycloak/test/common/PicketlinkSessionFactoryTestContext.java b/services/src/test/java/org/keycloak/test/common/PicketlinkSessionFactoryTestContext.java
old mode 100644
new mode 100755
index 80b2cbc..d152f3b
--- a/services/src/test/java/org/keycloak/test/common/PicketlinkSessionFactoryTestContext.java
+++ b/services/src/test/java/org/keycloak/test/common/PicketlinkSessionFactoryTestContext.java
@@ -1,6 +1,5 @@
 package org.keycloak.test.common;
 
-import org.keycloak.services.resources.KeycloakApplication;
 import org.keycloak.services.utils.PropertiesManager;
 
 /**
diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java
index febdc39..9bd13f9 100755
--- a/services/src/test/java/org/keycloak/test/ImportTest.java
+++ b/services/src/test/java/org/keycloak/test/ImportTest.java
@@ -1,24 +1,16 @@
 package org.keycloak.test;
 
-import org.junit.After;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.services.resources.KeycloakApplication;
-import org.keycloak.services.resources.SaasService;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.test.common.AbstractKeycloakTest;
 import org.keycloak.test.common.SessionFactoryTestContext;
 
diff --git a/services/src/test/java/org/keycloak/test/ModelTest.java b/services/src/test/java/org/keycloak/test/ModelTest.java
index 9b244be..33eb405 100755
--- a/services/src/test/java/org/keycloak/test/ModelTest.java
+++ b/services/src/test/java/org/keycloak/test/ModelTest.java
@@ -1,22 +1,21 @@
 package org.keycloak.test;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
 public class ModelTest extends AbstractKeycloakServerTest {
     private KeycloakSessionFactory factory;
     private KeycloakSession identitySession;
diff --git a/services/src/test/java/org/keycloak/test/UserModelTest.java b/services/src/test/java/org/keycloak/test/UserModelTest.java
old mode 100644
new mode 100755
index 9029511..910a20c
--- a/services/src/test/java/org/keycloak/test/UserModelTest.java
+++ b/services/src/test/java/org/keycloak/test/UserModelTest.java
@@ -1,8 +1,5 @@
 package org.keycloak.test;
 
-import java.util.Iterator;
-import java.util.List;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -16,6 +13,9 @@ import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 
+import java.util.Iterator;
+import java.util.List;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
@@ -89,6 +89,9 @@ public class UserModelTest extends AbstractKeycloakServerTest {
         Assert.assertTrue(user.getRequiredActions().isEmpty());
 
         user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
+        String id = realm.getId();
+        commit();
+        realm = manager.getRealm(id);
         user = realm.getUser("user");
 
         Assert.assertEquals(1, user.getRequiredActions().size());
@@ -119,6 +122,14 @@ public class UserModelTest extends AbstractKeycloakServerTest {
         Assert.assertTrue(user.getRequiredActions().isEmpty());
     }
 
+    protected void commit() {
+        identitySession.getTransaction().commit();
+        identitySession.close();
+        identitySession = factory.createSession();
+        identitySession.getTransaction().begin();
+        manager = new RealmManager(identitySession);
+    }
+
     public static void assertEquals(UserModel expected, UserModel actual) {
         Assert.assertEquals(expected.getLoginName(), actual.getLoginName());
         Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
diff --git a/services/src/test/resources/META-INF/persistence.xml b/services/src/test/resources/META-INF/persistence.xml
index c17ec56..ae026ef 100755
--- a/services/src/test/resources/META-INF/persistence.xml
+++ b/services/src/test/resources/META-INF/persistence.xml
@@ -2,7 +2,7 @@
     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="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+    <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>
@@ -34,5 +34,36 @@
         </properties>
     </persistence-unit>
 
+    <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.ApplicationScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</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.RealmScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.RoleEntity</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>
+
+        <exclude-unlisted-classes>true</exclude-unlisted-classes>
+
+        <properties>
+            <property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
+            <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
+            <property name="hibernate.connection.username" value="sa"/>
+            <property name="hibernate.connection.password" value=""/>
+            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
+            <property name="hibernate.show_sql" value="false" />
+            <property name="hibernate.format_sql" value="true" />
+        </properties>
+    </persistence-unit>
+
+
 
 </persistence>
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
old mode 100644
new mode 100755
index d19f0c7..ac9bc86
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
@@ -1,15 +1,5 @@
 package org.keycloak.social.facebook;
 
-import java.net.URI;
-import java.util.UUID;
-
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Form;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-
 import org.jboss.resteasy.client.jaxrs.ResteasyClient;
 import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
 import org.keycloak.social.AuthCallback;
@@ -19,6 +9,15 @@ import org.keycloak.social.SocialProviderConfig;
 import org.keycloak.social.SocialProviderException;
 import org.keycloak.social.SocialUser;
 
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+import java.util.UUID;
+
 /**
  * Social provider for Facebook
  *
diff --git a/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java b/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
old mode 100644
new mode 100755
diff --git a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
old mode 100644
new mode 100755
index 6ea93c8..8f7a508
--- a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
+++ b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
@@ -27,7 +27,6 @@ import org.keycloak.social.SocialProvider;
 import org.keycloak.social.SocialProviderConfig;
 import org.keycloak.social.SocialProviderException;
 import org.keycloak.social.SocialUser;
-
 import twitter4j.Twitter;
 import twitter4j.TwitterFactory;
 import twitter4j.auth.RequestToken;
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
old mode 100644
new mode 100755
index a411b48..ffbe981
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -81,6 +81,7 @@
             <groupId>org.jboss.logging</groupId>
             <artifactId>jboss-logging</artifactId>
         </dependency>
+        <!--
         <dependency>
             <groupId>org.picketlink</groupId>
             <artifactId>picketlink-idm-api</artifactId>
@@ -101,6 +102,7 @@
             <groupId>org.picketlink</groupId>
             <artifactId>picketlink-config</artifactId>
         </dependency>
+        -->
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index cceefaa..1d5f43e 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -23,31 +23,42 @@ package org.keycloak.testutils;
 
 import io.undertow.Undertow;
 import io.undertow.Undertow.Builder;
-import io.undertow.server.handlers.resource.*;
+import io.undertow.server.handlers.resource.FileResource;
+import io.undertow.server.handlers.resource.FileResourceManager;
+import io.undertow.server.handlers.resource.Resource;
+import io.undertow.server.handlers.resource.ResourceChangeListener;
+import io.undertow.server.handlers.resource.ResourceManager;
+import io.undertow.server.handlers.resource.URLResource;
 import io.undertow.servlet.Servlets;
 import io.undertow.servlet.api.DefaultServletConfig;
 import io.undertow.servlet.api.DeploymentInfo;
 import io.undertow.servlet.api.FilterInfo;
-
-import java.io.*;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.DispatcherType;
-
 import org.jboss.resteasy.jwt.JsonSerialization;
 import org.jboss.resteasy.logging.Logger;
 import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
 import org.jboss.resteasy.spi.ResteasyDeployment;
-import org.keycloak.models.*;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.filters.KeycloakSessionServletFilter;
 import org.keycloak.services.managers.ApplianceBootstrap;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
 
+import javax.servlet.DispatcherType;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
@@ -251,8 +262,7 @@ public class KeycloakServer {
         di.setDeploymentName("Keycloak");
         di.setResourceManager(new KeycloakResourceManager(config.getResourcesHome()));
 
-        Set<String> allowed = new HashSet<String>(Arrays.asList(new String[]{"js", "css", "png", "jpg", "gif", "html", "svg"}));
-        di.setDefaultServletConfig(new DefaultServletConfig(false, allowed));
+        di.setDefaultServletConfig(new DefaultServletConfig(true));
         di.addWelcomePage("index.html");
 
         FilterInfo filter = Servlets.filter("SessionFilter", KeycloakSessionServletFilter.class);
@@ -316,6 +326,24 @@ public class KeycloakServer {
                 return new FileResource(file, new FileResourceManager(file.getParentFile(), 1), path);
             }
         }
+
+        @Override
+        public boolean isResourceChangeListenerSupported() {
+            return false;
+        }
+
+        @Override
+        public void registerResourceChangeListener(ResourceChangeListener listener) {
+        }
+
+        @Override
+        public void removeResourceChangeListener(ResourceChangeListener listener) {
+        }
+
+        @Override
+        public void close() throws IOException {
+        }
+
     }
 
     private static File file(String... path) {
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/MailServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/MailServer.java
old mode 100644
new mode 100755
index 8ba730a..fd9ad22
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/MailServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/MailServer.java
@@ -1,11 +1,11 @@
 package org.keycloak.testutils;
 
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMessage.RecipientType;
-
 import com.icegreen.greenmail.util.GreenMail;
 import com.icegreen.greenmail.util.ServerSetup;
 
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMessage.RecipientType;
+
 public class MailServer {
 
     public static void main(String[] args) throws Exception {
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/TotpGenerator.java b/testsuite/integration/src/main/java/org/keycloak/testutils/TotpGenerator.java
old mode 100644
new mode 100755
index bc5f633..ff0ac20
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/TotpGenerator.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/TotpGenerator.java
@@ -1,11 +1,12 @@
 package org.keycloak.testutils;
 
+import org.keycloak.models.utils.Base32;
+import org.keycloak.models.utils.TimeBasedOTP;
+
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.TimeUnit;
 
-import org.picketlink.common.util.Base32;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
 
 public class TotpGenerator {
 
diff --git a/testsuite/integration/src/main/resources/META-INF/persistence.xml b/testsuite/integration/src/main/resources/META-INF/persistence.xml
index c17ec56..f299e7e 100755
--- a/testsuite/integration/src/main/resources/META-INF/persistence.xml
+++ b/testsuite/integration/src/main/resources/META-INF/persistence.xml
@@ -2,24 +2,22 @@
     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="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+    <persistence-unit name="jpa-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>
+        <class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</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.RealmScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.RoleEntity</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>
 
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
old mode 100644
new mode 100755
index 9891af0..e3fe2dd
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
@@ -12,7 +12,9 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.Constants;
 import org.keycloak.testsuite.OAuthClient;
@@ -52,6 +54,16 @@ public class ProfileTest {
             user.setAttribute("key2", "value2");
 
             ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+            for (String r : accountApp.getDefaultRoles()) {
+                accountApp.grantRole(user, accountApp.getRole(r));
+            }
+
+            UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
+            user2.setEnabled(true);
+            UserCredentialModel creds = new UserCredentialModel();
+            creds.setType(CredentialRepresentation.PASSWORD);
+            creds.setValue("password");
+            appRealm.updateCredential(user2, creds);
 
             ApplicationModel app = appRealm.getApplicationNameMap().get("test-app");
             accountApp.addScopeMapping(app.getApplicationUser(), org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE);
@@ -81,8 +93,6 @@ public class ProfileTest {
     @WebResource
     protected OAuthGrantPage grantPage;
 
-    private List<String> defaultRoles;
-
     @Test
     public void getProfile() throws Exception {
         oauth.doLogin("test-user@localhost", "password");
@@ -154,31 +164,13 @@ public class ProfileTest {
 
     @Test
     public void getProfileNoAccess() throws Exception {
-        try {
-            keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
-                @Override
-                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    ApplicationModel app = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
-                    defaultRoles = app.getDefaultRoles();
-                    app.updateDefaultRoles(new String[0]);
-                }
-            });
-
-            oauth.doLogin("test-user@localhost", "password");
-
-            String code = oauth.getCurrentQuery().get("code");
-            String token = oauth.doAccessTokenRequest(code, "password").getAccessToken();
-
-            HttpResponse response = doGetProfile(token, null);
-            assertEquals(403, response.getStatusLine().getStatusCode());
-        } finally {
-            keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
-                @Override
-                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION).updateDefaultRoles((String[]) defaultRoles.toArray());
-                }
-            });
-        }
+        oauth.doLogin("test-user-no-access@localhost", "password");
+
+        String code = oauth.getCurrentQuery().get("code");
+        String token = oauth.doAccessTokenRequest(code, "password").getAccessToken();
+
+        HttpResponse response = doGetProfile(token, null);
+        assertEquals(403, response.getStatusLine().getStatusCode());
     }
 
     @Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
index 8b27729..7909d83 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
@@ -21,21 +21,14 @@
  */
 package org.keycloak.testsuite.actions;
 
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
-
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.LoginPage;
@@ -48,6 +41,12 @@ import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
index d591829..917d047 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
@@ -25,10 +25,10 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.LoginPage;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java
index 76757f4..28197d0 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java
@@ -25,10 +25,10 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
index bb70d97..4829158 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
@@ -25,11 +25,10 @@ import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.TimeBasedOTP;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.pages.AccountTotpPage;
 import org.keycloak.testsuite.pages.AppPage;
@@ -42,7 +41,6 @@ import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
 import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
index c567e99..0b66340 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
@@ -22,13 +22,12 @@
 package org.keycloak.testsuite.actions;
 
 import org.junit.Assert;
-import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.LoginPage;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/ApplicationServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/ApplicationServlet.java
old mode 100644
new mode 100755
index 4202cc1..9aa9655
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/ApplicationServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/ApplicationServlet.java
@@ -21,19 +21,18 @@
  */
 package org.keycloak.testsuite;
 
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.List;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
old mode 100644
new mode 100755
index 32ab6bf..bab9f43
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
@@ -1,7 +1,5 @@
 package org.keycloak.testsuite;
 
-import java.util.UUID;
-
 import org.keycloak.social.AuthCallback;
 import org.keycloak.social.AuthRequest;
 import org.keycloak.social.SocialProvider;
@@ -9,6 +7,8 @@ import org.keycloak.social.SocialProviderConfig;
 import org.keycloak.social.SocialProviderException;
 import org.keycloak.social.SocialUser;
 
+import java.util.UUID;
+
 public class DummySocial implements SocialProvider {
 
     private static final String AUTH_PATH = "http://localhost:8081/dummy-social/auth";
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
old mode 100644
new mode 100755
index d7b1e37..f6cc0d0
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
@@ -1,17 +1,16 @@
 package org.keycloak.testsuite;
 
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.Charset;
-import java.util.List;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.List;
 
 public class DummySocialServlet extends HttpServlet {
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
index f7bc811..4d0d3ca 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java
@@ -24,6 +24,7 @@ package org.keycloak.testsuite.forms;
 import org.apache.http.HttpResponse;
 import org.junit.*;
 import org.keycloak.models.*;
+import org.keycloak.models.utils.TimeBasedOTP;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.OAuthClient;
@@ -36,7 +37,6 @@ import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
 
 import java.util.List;
 
@@ -48,7 +48,23 @@ import static org.junit.Assert.assertEquals;
 public class AccountTest {
 
     @ClassRule
-    public static KeycloakRule keycloakRule = new KeycloakRule();
+    public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
+        @Override
+        public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+            UserModel user = appRealm.getUser("test-user@localhost");
+            ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION);
+            for (String r : accountApp.getDefaultRoles()) {
+                accountApp.grantRole(user, accountApp.getRole(r));
+            }
+
+            UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
+            user2.setEnabled(true);
+            UserCredentialModel creds = new UserCredentialModel();
+            creds.setType(CredentialRepresentation.PASSWORD);
+            creds.setValue("password");
+            appRealm.updateCredential(user2, creds);
+        }
+    });
 
     @Rule
     public WebRule webRule = new WebRule(this);
@@ -79,8 +95,6 @@ public class AccountTest {
 
     private TimeBasedOTP totp = new TimeBasedOTP();
 
-    private List<String> defaultRoles;
-
     @After
     public void after() {
         keycloakRule.configure(new KeycloakSetup() {
@@ -119,7 +133,7 @@ public class AccountTest {
         loginPage.open();
         loginPage.login("test-user@localhost", "password");
 
-        Assert.assertEquals("Invalid username or password", loginPage.getError());
+        Assert.assertEquals("Invalid username or password.", loginPage.getError());
 
         loginPage.open();
         loginPage.login("test-user@localhost", "new-password");
@@ -176,7 +190,7 @@ public class AccountTest {
         Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
 
         // Error with false code
-        totpPage.configure(totp.generate(totpPage.getTotpSecret()+"123"));
+        totpPage.configure(totp.generate(totpPage.getTotpSecret() + "123"));
 
         Assert.assertTrue(profilePage.isError());
 
@@ -189,29 +203,11 @@ public class AccountTest {
 
     @Test
     public void changeProfileNoAccess() throws Exception {
-        try {
-            keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
-                @Override
-                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    ApplicationModel app = appRealm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
-                    defaultRoles = app.getDefaultRoles();
-                    app.updateDefaultRoles(new String[0]);
-                }
-            });
-
-            profilePage.open();
-            loginPage.login("test-user@localhost", "password");
-
-            Assert.assertTrue(errorPage.isCurrent());
-            Assert.assertEquals("No access", errorPage.getError());
-        } finally {
-            keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
-                @Override
-                public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
-                    appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION).updateDefaultRoles((String[]) defaultRoles.toArray());
-                }
-            });
-        }
+        profilePage.open();
+        loginPage.login("test-user-no-access@localhost", "password");
+
+        Assert.assertTrue(errorPage.isCurrent());
+        Assert.assertEquals("No access", errorPage.getError());
     }
 
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
index d9628df..fab49b2 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java
@@ -60,7 +60,7 @@ public class LoginTest {
 
         loginPage.assertCurrent();
 
-        Assert.assertEquals("Invalid username or password", loginPage.getError());
+        Assert.assertEquals("Invalid username or password.", loginPage.getError());
     }
 
     @Test
@@ -70,7 +70,7 @@ public class LoginTest {
 
         loginPage.assertCurrent();
 
-        Assert.assertEquals("Invalid username or password", loginPage.getError());
+        Assert.assertEquals("Invalid username or password.", loginPage.getError());
     }
 
     @Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
index 2ff938b..a3ea179 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java
@@ -21,18 +21,17 @@
  */
 package org.keycloak.testsuite.forms;
 
-import java.net.MalformedURLException;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.TimeBasedOTP;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.LoginPage;
@@ -43,7 +42,8 @@ import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
 import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
-import org.picketlink.idm.credential.util.TimeBasedOTP;
+
+import java.net.MalformedURLException;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -102,7 +102,7 @@ public class LoginTotpTest {
         loginTotpPage.login("123456");
 
         loginPage.assertCurrent();
-        Assert.assertEquals("Invalid username or password", loginPage.getError());
+        Assert.assertEquals("Invalid username or password.", loginPage.getError());
     }
 
     @Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
index 93e773e..e82b31f 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
@@ -90,7 +90,7 @@ public class RegisterTest {
         registerPage.register("firstName", "lastName", "email", "registerUserMissingPassword", null, null);
 
         registerPage.assertCurrent();
-        Assert.assertEquals("Please specify password", registerPage.getError());
+        Assert.assertEquals("Please specify password.", registerPage.getError());
     }
 
     @Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
old mode 100644
new mode 100755
index 396f3d9..2610ff5
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
@@ -21,11 +21,6 @@
  */
 package org.keycloak.testsuite.forms;
 
-import java.io.IOException;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
-
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
@@ -42,6 +37,10 @@ import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.IOException;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
old mode 100644
new mode 100755
index 2ccd506..017aca5
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -21,9 +21,6 @@
  */
 package org.keycloak.testsuite.oauth;
 
-import java.io.IOException;
-
-import org.apache.http.client.ClientProtocolException;
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Rule;
@@ -41,6 +38,8 @@ import org.keycloak.testsuite.rule.WebResource;
 import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
+import java.io.IOException;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
old mode 100644
new mode 100755
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
old mode 100644
new mode 100755
index 2a0e372..c69208f
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -21,17 +21,6 @@
  */
 package org.keycloak.testsuite;
 
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-import java.security.PublicKey;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.UriBuilder;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
@@ -53,6 +42,16 @@ import org.keycloak.representations.SkeletonKeyToken;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractAccountPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractAccountPage.java
old mode 100644
new mode 100755
index 9860b14..d849330
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractAccountPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AbstractAccountPage.java
@@ -21,9 +21,6 @@
  */
 package org.keycloak.testsuite.pages;
 
-import org.junit.Assert;
-import org.keycloak.testsuite.rule.WebResource;
-import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/GreenMailRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/GreenMailRule.java
old mode 100644
new mode 100755
index 386ddb7..bd52a59
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/GreenMailRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/GreenMailRule.java
@@ -21,18 +21,13 @@
  */
 package org.keycloak.testsuite.rule;
 
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.net.SocketException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-import java.util.Properties;
-
-import javax.mail.internet.MimeMessage;
-
-import org.junit.rules.ExternalResource;
-
 import com.icegreen.greenmail.util.GreenMail;
 import com.icegreen.greenmail.util.ServerSetup;
+import org.junit.rules.ExternalResource;
+
+import javax.mail.internet.MimeMessage;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.SocketException;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
index 010b1cc..cdbcfe1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java
@@ -23,13 +23,6 @@ package org.keycloak.testsuite.rule;
 
 import io.undertow.servlet.api.DeploymentInfo;
 import io.undertow.servlet.api.ServletInfo;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.servlet.Servlet;
-
 import org.jboss.resteasy.jwt.JsonSerialization;
 import org.junit.rules.ExternalResource;
 import org.keycloak.models.Constants;
@@ -40,6 +33,11 @@ import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.ApplicationServlet;
 import org.keycloak.testutils.KeycloakServer;
 
+import javax.servlet.Servlet;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/WebRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/WebRule.java
old mode 100644
new mode 100755
index ccdca44..ef37e21
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/WebRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/WebRule.java
@@ -21,8 +21,7 @@
  */
 package org.keycloak.testsuite.rule;
 
-import java.lang.reflect.Field;
-
+import com.gargoylesoftware.htmlunit.WebClient;
 import org.junit.rules.ExternalResource;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.pages.AbstractPage;
@@ -31,7 +30,7 @@ import org.openqa.selenium.chrome.ChromeDriver;
 import org.openqa.selenium.firefox.FirefoxDriver;
 import org.openqa.selenium.support.PageFactory;
 
-import com.gargoylesoftware.htmlunit.WebClient;
+import java.lang.reflect.Field;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
index 4f87a10..e4c3c6f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
@@ -26,9 +26,9 @@ import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.keycloak.models.RealmModel;
 import org.keycloak.representations.SkeletonKeyToken;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.RealmModel;
 import org.keycloak.testsuite.DummySocialServlet;
 import org.keycloak.testsuite.OAuthClient;
 import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
@@ -44,7 +44,6 @@ import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
 
 import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -104,9 +103,6 @@ public class SocialLoginTest {
         SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken());
 
         Assert.assertEquals("dummy-user", token.getPrincipal());
-
-        Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
-        Assert.assertTrue(token.getRealmAccess().isUserInRole("user"));
     }
 
     @Test
diff --git a/testsuite/performance/pom.xml b/testsuite/performance/pom.xml
old mode 100644
new mode 100755
index 1cb8220..f9dc957
--- a/testsuite/performance/pom.xml
+++ b/testsuite/performance/pom.xml
@@ -146,6 +146,7 @@
                                 <artifactId>jboss-logging</artifactId>
                                 <version>${jboss.logging.version}</version>
                             </dependency>
+                            <!--
                             <dependency>
                                 <groupId>org.picketlink</groupId>
                                 <artifactId>picketlink-idm-impl</artifactId>
@@ -161,6 +162,7 @@
                                 <artifactId>picketlink-config</artifactId>
                                 <version>${picketlink.version}</version>
                             </dependency>
+                            -->
                             <dependency>
                                 <groupId>org.mongodb</groupId>
                                 <artifactId>mongo-java-driver</artifactId>
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
old mode 100644
new mode 100755
index efe57c1..882f8bb
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/BaseJMeterPerformanceTest.java
@@ -1,9 +1,5 @@
 package org.keycloak.testsuite.performance;
 
-import java.util.concurrent.Callable;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.atomic.AtomicInteger;
-
 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
 import org.apache.jmeter.samplers.SampleResult;
@@ -12,6 +8,10 @@ import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.services.resources.KeycloakApplication;
 
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
old mode 100644
new mode 100755
index 2749998..c839337
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
@@ -1,7 +1,5 @@
 package org.keycloak.testsuite.performance;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
@@ -11,6 +9,8 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
old mode 100644
new mode 100755
index 67d2ca6..12fced6
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
@@ -1,7 +1,5 @@
 package org.keycloak.testsuite.performance;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
@@ -13,6 +11,8 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
old mode 100644
new mode 100755
index 416cd60..737fc21
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
@@ -1,7 +1,5 @@
 package org.keycloak.testsuite.performance;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
@@ -10,6 +8,8 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java
old mode 100644
new mode 100755
index 262ad93..b13b7d1
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/RemoveUsersWorker.java
@@ -1,13 +1,12 @@
 package org.keycloak.testsuite.performance;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.services.utils.PropertiesManager;
+
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/testsuite/performance/src/test/resources/META-INF/persistence.xml b/testsuite/performance/src/test/resources/META-INF/persistence.xml
old mode 100644
new mode 100755
index 1dff641..8083104
--- a/testsuite/performance/src/test/resources/META-INF/persistence.xml
+++ b/testsuite/performance/src/test/resources/META-INF/persistence.xml
@@ -2,7 +2,7 @@
              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="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
+    <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>
@@ -18,8 +18,39 @@
         <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.services.models.picketlink.mappings.RealmEntity</class>
-        <class>org.keycloak.services.models.picketlink.mappings.ApplicationEntity</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:mysql://localhost/keycloakPerfTest"/>
+            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
+            <property name="hibernate.connection.username" value="portal"/>
+            <property name="hibernate.connection.password" value="portal"/>
+            <!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
+            <!--<property name="hibernate.hbm2ddl.auto" value="update" />-->
+            <property name="hibernate.hbm2ddl.auto" value="${keycloak.jpa.hbm2ddl.auto}" />
+            <property name="hibernate.show_sql" value="false" />
+            <property name="hibernate.format_sql" value="true" />
+        </properties>
+    </persistence-unit>
+    <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.ApplicationScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</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.RealmScopeMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
+        <class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
+        <class>org.keycloak.models.jpa.entities.RoleEntity</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>
 
         <exclude-unlisted-classes>true</exclude-unlisted-classes>