keycloak-aplcache

Changes

pom.xml 111(+54 -57)

services/pom.xml 4(+2 -2)

testsuite/integration/src/test/java/org/keycloak/testsuite/InfinispanCLI.java 243(+0 -243)

Details

diff --git a/adapters/oidc/as7-eap6/as7-adapter/pom.xml b/adapters/oidc/as7-eap6/as7-adapter/pom.xml
index 55037af..a9251d5 100755
--- a/adapters/oidc/as7-eap6/as7-adapter/pom.xml
+++ b/adapters/oidc/as7-eap6/as7-adapter/pom.xml
@@ -73,7 +73,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml b/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml
index 217b417..c926324 100755
--- a/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml
+++ b/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml
@@ -41,7 +41,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/oidc/as7-eap6/as7-subsystem/pom.xml b/adapters/oidc/as7-eap6/as7-subsystem/pom.xml
index e3ab393..8938e88 100755
--- a/adapters/oidc/as7-eap6/as7-subsystem/pom.xml
+++ b/adapters/oidc/as7-eap6/as7-subsystem/pom.xml
@@ -64,25 +64,25 @@
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-naming</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-server</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-ee</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-web</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
diff --git a/adapters/oidc/jaxrs-oauth-client/pom.xml b/adapters/oidc/jaxrs-oauth-client/pom.xml
index 60e8ae7..eac0f49 100755
--- a/adapters/oidc/jaxrs-oauth-client/pom.xml
+++ b/adapters/oidc/jaxrs-oauth-client/pom.xml
@@ -72,7 +72,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/oidc/js/src/main/resources/keycloak.js b/adapters/oidc/js/src/main/resources/keycloak.js
index dad522e..4bfec59 100755
--- a/adapters/oidc/js/src/main/resources/keycloak.js
+++ b/adapters/oidc/js/src/main/resources/keycloak.js
@@ -236,7 +236,7 @@
         kc.createLogoutUrl = function(options) {
             var url = getRealmUrl()
                 + '/protocol/openid-connect/logout'
-                + '?redirect_uri=' + encodeURIComponent(adapter.redirectUri(options));
+                + '?redirect_uri=' + encodeURIComponent(adapter.redirectUri(options, false));
 
             return url;
         }
@@ -842,14 +842,18 @@
                         return createPromise().promise;
                     },
 
-                    redirectUri: function(options) {
+                    redirectUri: function(options, encodeHash) {
+                        if (arguments.length == 1) {
+                            encodeHash = true;
+                        }
+
                         if (options && options.redirectUri) {
                             return options.redirectUri;
                         } else if (kc.redirectUri) {
                             return kc.redirectUri;
                         } else {
                             var redirectUri = location.href;
-                            if (location.hash) {
+                            if (location.hash && encodeHash) {
                                 redirectUri = redirectUri.substring(0, location.href.indexOf('#'));
                                 redirectUri += (redirectUri.indexOf('?') == -1 ? '?' : '&') + 'redirect_fragment=' + encodeURIComponent(location.hash.substring(1));
                             }
diff --git a/adapters/oidc/servlet-filter/pom.xml b/adapters/oidc/servlet-filter/pom.xml
index 9e39669..1e01239 100755
--- a/adapters/oidc/servlet-filter/pom.xml
+++ b/adapters/oidc/servlet-filter/pom.xml
@@ -75,7 +75,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/oidc/servlet-oauth-client/pom.xml b/adapters/oidc/servlet-oauth-client/pom.xml
index 0f2891e..560eecf 100755
--- a/adapters/oidc/servlet-oauth-client/pom.xml
+++ b/adapters/oidc/servlet-oauth-client/pom.xml
@@ -53,7 +53,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/oidc/spring-security/pom.xml b/adapters/oidc/spring-security/pom.xml
index c55275b..ff39fb5 100755
--- a/adapters/oidc/spring-security/pom.xml
+++ b/adapters/oidc/spring-security/pom.xml
@@ -41,7 +41,6 @@
         <dependency>
             <groupId>org.keycloak</groupId>
             <artifactId>keycloak-core</artifactId>
-            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
@@ -50,11 +49,10 @@
         <dependency>
             <groupId>org.keycloak</groupId>
             <artifactId>keycloak-adapter-core</artifactId>
-            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -82,7 +80,6 @@
         <dependency>
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcprov-jdk15on</artifactId>
-            <version>${bouncycastle.crypto.version}</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
diff --git a/adapters/oidc/undertow/pom.xml b/adapters/oidc/undertow/pom.xml
index 80d476e..ed5e7ce 100755
--- a/adapters/oidc/undertow/pom.xml
+++ b/adapters/oidc/undertow/pom.xml
@@ -75,7 +75,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
 
diff --git a/adapters/oidc/wildfly/wf8-subsystem/pom.xml b/adapters/oidc/wildfly/wf8-subsystem/pom.xml
index 7176f6d..871775c 100755
--- a/adapters/oidc/wildfly/wf8-subsystem/pom.xml
+++ b/adapters/oidc/wildfly/wf8-subsystem/pom.xml
@@ -79,21 +79,15 @@
         <dependency>
             <groupId>org.jboss.logging</groupId>
             <artifactId>jboss-logging-annotations</artifactId>
-            <version>${jboss-logging-tools.version}</version>
-            <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
-            projects that depend on this project.-->
+            <version>${jboss.logging.tools.wf8.version}</version>
             <scope>provided</scope>
-            <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.logging</groupId>
             <artifactId>jboss-logging-processor</artifactId>
-            <version>${jboss-logging-tools.version}</version>
-            <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
-            projects that depend on this project.-->
+            <version>${jboss.logging.tools.wf8.version}</version>
             <scope>provided</scope>
-            <optional>true</optional>
         </dependency>
 
         <dependency>
diff --git a/adapters/oidc/wildfly/wildfly-adapter/pom.xml b/adapters/oidc/wildfly/wildfly-adapter/pom.xml
index c92a5ae..8e83abd 100755
--- a/adapters/oidc/wildfly/wildfly-adapter/pom.xml
+++ b/adapters/oidc/wildfly/wildfly-adapter/pom.xml
@@ -89,7 +89,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
 
diff --git a/adapters/saml/as7-eap6/adapter/pom.xml b/adapters/saml/as7-eap6/adapter/pom.xml
index f190d76..25cf62f 100755
--- a/adapters/saml/as7-eap6/adapter/pom.xml
+++ b/adapters/saml/as7-eap6/adapter/pom.xml
@@ -53,7 +53,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/saml/as7-eap6/subsystem/pom.xml b/adapters/saml/as7-eap6/subsystem/pom.xml
index 34d1e2e..47e9d9e 100755
--- a/adapters/saml/as7-eap6/subsystem/pom.xml
+++ b/adapters/saml/as7-eap6/subsystem/pom.xml
@@ -64,25 +64,25 @@
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-naming</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-server</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-ee</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-web</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
@@ -104,7 +104,7 @@ projects that depend on this project.-->
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-controller</artifactId>
-            <version>${jboss.version}</version>
+            <version>${jboss.as.version}</version>
         </dependency>
 
         <dependency>
diff --git a/adapters/saml/servlet-filter/pom.xml b/adapters/saml/servlet-filter/pom.xml
index e3dbee8..69ce19b 100755
--- a/adapters/saml/servlet-filter/pom.xml
+++ b/adapters/saml/servlet-filter/pom.xml
@@ -61,7 +61,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
 		<dependency>
diff --git a/adapters/saml/undertow/pom.xml b/adapters/saml/undertow/pom.xml
index ce7006e..f429c45 100755
--- a/adapters/saml/undertow/pom.xml
+++ b/adapters/saml/undertow/pom.xml
@@ -69,7 +69,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/saml/wildfly/wildfly-adapter/pom.xml b/adapters/saml/wildfly/wildfly-adapter/pom.xml
index acc426f..7b4e9a7 100755
--- a/adapters/saml/wildfly/wildfly-adapter/pom.xml
+++ b/adapters/saml/wildfly/wildfly-adapter/pom.xml
@@ -69,7 +69,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
 
diff --git a/adapters/spi/jboss-adapter-core/pom.xml b/adapters/spi/jboss-adapter-core/pom.xml
index 9e05f33..a2229e3 100755
--- a/adapters/spi/jboss-adapter-core/pom.xml
+++ b/adapters/spi/jboss-adapter-core/pom.xml
@@ -67,7 +67,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/spi/servlet-adapter-spi/pom.xml b/adapters/spi/servlet-adapter-spi/pom.xml
index c4c944b..d6f82e2 100755
--- a/adapters/spi/servlet-adapter-spi/pom.xml
+++ b/adapters/spi/servlet-adapter-spi/pom.xml
@@ -45,7 +45,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/FilterSessionStore.java b/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/FilterSessionStore.java
index 6a17c8e..2470ef4 100755
--- a/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/FilterSessionStore.java
+++ b/adapters/spi/servlet-adapter-spi/src/main/java/org/keycloak/adapters/servlet/FilterSessionStore.java
@@ -23,6 +23,7 @@ import org.keycloak.adapters.spi.KeycloakAccount;
 import org.keycloak.common.util.Encode;
 import org.keycloak.common.util.MultivaluedHashMap;
 
+import javax.servlet.ReadListener;
 import javax.servlet.ServletException;
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
@@ -173,11 +174,54 @@ public class FilterSessionStore implements AdapterSessionStore {
                 public ServletInputStream getInputStream() throws IOException {
 
                     if (needRequestRestore && body != null) {
-                        final ByteArrayInputStream is = new ByteArrayInputStream(body);
                         return new ServletInputStream() {
+                            private int lastIndex = 0;
+                            private ReadListener readListener = null;
+
+                            @Override
+                            public boolean isFinished() {
+                                return lastIndex == body.length;
+                            }
+
+                            @Override
+                            public boolean isReady() {
+                                return true;
+                            }
+
+                            @Override
+                            public void setReadListener(ReadListener readListener) {
+                                this.readListener = readListener;
+                                if (!isFinished()) {
+                                    try {
+                                        readListener.onDataAvailable();
+                                    } catch (IOException e) {
+                                        readListener.onError(e);
+                                    }
+                                } else {
+                                    try {
+                                        readListener.onAllDataRead();
+                                    } catch (IOException e) {
+                                        readListener.onError(e);
+                                    }
+                                }
+                            }
+
                             @Override
                             public int read() throws IOException {
-                                return is.read();
+                                int i = -1;
+                                if (!isFinished()) {
+                                    i = body[lastIndex];
+                                    lastIndex++;
+                                    if (isFinished() && readListener != null) {
+                                        try {
+                                            readListener.onAllDataRead();
+                                        } catch (IOException e) {
+                                            readListener.onError(e);
+                                            throw e;
+                                        }
+                                    }
+                                }
+                                return i;
                             }
                         };
                     }
diff --git a/adapters/spi/undertow-adapter-spi/pom.xml b/adapters/spi/undertow-adapter-spi/pom.xml
index 7912f1d..1aae136 100755
--- a/adapters/spi/undertow-adapter-spi/pom.xml
+++ b/adapters/spi/undertow-adapter-spi/pom.xml
@@ -47,7 +47,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml b/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml
index c1f0ad4..d60c1cd 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/client-registration.xml
@@ -27,7 +27,7 @@
     <para>
         The Client Registration Service provides built-in support for Keycloak Client Representations, OpenID Connect
         Client Meta Data and SAML Entity Descriptors. It's also possible to plugin custom client registration providers
-        if required. The Client Registration Service endpoint is <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/&lt;provider&gt;</literal>.
+        if required. The Client Registration Service endpoint is <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/&lt;provider&gt;</literal>.
     </para>
     <para>
         The built-in supported <literal>providers</literal> are:
@@ -123,23 +123,23 @@ Authorization: bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJmMjJmNzQyYy04ZjNlLTQ2M....
         </para>
         <para>
             To create a client create a Client Representation (JSON) then do a HTTP POST to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default</literal>. It will return a Client Representation
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/default</literal>. It will return a Client Representation
             that also includes the registration access token. You should save the registration access token somewhere
             if you want to retrieve the config, update or delete the client later.
         </para>
         <para>
             To retrieve the Client Representation then do a HTTP GET to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default/&lt;client id&gt;</literal>. It will also
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/default/&lt;client id&gt;</literal>. It will also
             return a new registration access token.
         </para>
         <para>
             To update the Client Representation then do a HTTP PUT to with the updated Client Representation to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default/&lt;client id&gt;</literal>. It will also
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/default/&lt;client id&gt;</literal>. It will also
             return a new registration access token.
         </para>
         <para>
             To delete the Client Representation then do a HTTP DELETE to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/default/&lt;client id&gt;</literal>
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/default/&lt;client id&gt;</literal>
         </para>
     </section>
 
@@ -155,7 +155,7 @@ Authorization: basic BASE64(client-id + ':' + client-secret)
         </para>
         <para>
             To retrieve the Adapter Configuration then do a HTTP GET to:
-            <literal>&lt;KEYCLOAK URL&gt;//realms/&lt;realm&gt;/clients/installation/&lt;client id&gt;</literal>
+            <literal>&lt;KEYCLOAK URL&gt;//realms/&lt;realm&gt;/clients-registrations/installation/&lt;client id&gt;</literal>
         </para>
         <para>
             No authentication is required for public clients. This means that for the JavaScript adapter you can
@@ -172,7 +172,7 @@ Authorization: basic BASE64(client-id + ':' + client-secret)
         </para>
         <para>
             The endpoint to use these specifications to register clients in Keycloak is:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/oidc[/&lt;client id&gt;]</literal>.
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/oidc[/&lt;client id&gt;]</literal>.
         </para>
         <para>
             This endpoints can also be found in the OpenID Connect Discovery endpoint for the realm:
@@ -190,7 +190,7 @@ Authorization: basic BASE64(client-id + ':' + client-secret)
         </para>
         <para>
             To create a client do a HTTP POST with the SAML Entity Descriptor to:
-            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients/saml2-entity-descriptor</literal>.
+            <literal>&lt;KEYCLOAK URL&gt;/realms/&lt;realm&gt;/clients-registrations/saml2-entity-descriptor</literal>.
         </para>
     </section>
 
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index b942709..30bd80c 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -108,6 +108,12 @@
                 </para>
             </simplesect>
             <simplesect>
+                <title>Client Registration service endpoints moved</title>
+                <para>
+                    The Client Registration service endpoints have been moved from <literal>{realm}/clients</literal> to <literal>{realm}/clients-registrations</literal>.
+                </para>
+            </simplesect>
+            <simplesect>
                 <title>Deprecated OpenID Connect endpoints</title>
                 <para>
                     In 1.2 we deprecated a number of endpoints that where not consistent with the OpenID Connect
diff --git a/examples/basic-auth/pom.xml b/examples/basic-auth/pom.xml
index a73db62..a1ef3c2 100755
--- a/examples/basic-auth/pom.xml
+++ b/examples/basic-auth/pom.xml
@@ -50,7 +50,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/broker/twitter-authentication/pom.xml b/examples/broker/twitter-authentication/pom.xml
index 83ea633..7a92b08 100755
--- a/examples/broker/twitter-authentication/pom.xml
+++ b/examples/broker/twitter-authentication/pom.xml
@@ -58,7 +58,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/cors/database-service/pom.xml b/examples/cors/database-service/pom.xml
index 2c22c0b..44262ed 100755
--- a/examples/cors/database-service/pom.xml
+++ b/examples/cors/database-service/pom.xml
@@ -48,7 +48,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/admin-access-app/pom.xml b/examples/demo-template/admin-access-app/pom.xml
index cfabf9b..b3f3001 100755
--- a/examples/demo-template/admin-access-app/pom.xml
+++ b/examples/demo-template/admin-access-app/pom.xml
@@ -42,7 +42,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/customer-app/pom.xml b/examples/demo-template/customer-app/pom.xml
index 4c52e05..1fdf6db 100755
--- a/examples/demo-template/customer-app/pom.xml
+++ b/examples/demo-template/customer-app/pom.xml
@@ -42,7 +42,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/customer-app-filter/pom.xml b/examples/demo-template/customer-app-filter/pom.xml
index fb17b6b..758d6fb 100755
--- a/examples/demo-template/customer-app-filter/pom.xml
+++ b/examples/demo-template/customer-app-filter/pom.xml
@@ -42,7 +42,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/database-service/pom.xml b/examples/demo-template/database-service/pom.xml
index f3465e7..a864cee 100755
--- a/examples/demo-template/database-service/pom.xml
+++ b/examples/demo-template/database-service/pom.xml
@@ -48,7 +48,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/offline-access-app/pom.xml b/examples/demo-template/offline-access-app/pom.xml
index 8c715dd..3cefb0d 100644
--- a/examples/demo-template/offline-access-app/pom.xml
+++ b/examples/demo-template/offline-access-app/pom.xml
@@ -42,7 +42,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/product-app/pom.xml b/examples/demo-template/product-app/pom.xml
index 93d2425..a44de34 100755
--- a/examples/demo-template/product-app/pom.xml
+++ b/examples/demo-template/product-app/pom.xml
@@ -42,7 +42,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/service-account/pom.xml b/examples/demo-template/service-account/pom.xml
index 33f9e5e..68e69c8 100644
--- a/examples/demo-template/service-account/pom.xml
+++ b/examples/demo-template/service-account/pom.xml
@@ -34,7 +34,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/third-party/pom.xml b/examples/demo-template/third-party/pom.xml
index 7ebdbbb..ebbecaf 100755
--- a/examples/demo-template/third-party/pom.xml
+++ b/examples/demo-template/third-party/pom.xml
@@ -34,8 +34,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
-            <version>1.0.1.Final</version>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/demo-template/third-party-cdi/pom.xml b/examples/demo-template/third-party-cdi/pom.xml
index 73723b3..5dd08c6 100755
--- a/examples/demo-template/third-party-cdi/pom.xml
+++ b/examples/demo-template/third-party-cdi/pom.xml
@@ -34,8 +34,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
-            <version>1.0.1.Final</version>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/fuse/customer-app-fuse/pom.xml b/examples/fuse/customer-app-fuse/pom.xml
index 196227c..0dea1c4 100755
--- a/examples/fuse/customer-app-fuse/pom.xml
+++ b/examples/fuse/customer-app-fuse/pom.xml
@@ -52,7 +52,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/fuse/product-app-fuse/pom.xml b/examples/fuse/product-app-fuse/pom.xml
index 5fa2684..c24b5d1 100755
--- a/examples/fuse/product-app-fuse/pom.xml
+++ b/examples/fuse/product-app-fuse/pom.xml
@@ -53,7 +53,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
diff --git a/examples/kerberos/pom.xml b/examples/kerberos/pom.xml
index 9d9dc25..3252d92 100755
--- a/examples/kerberos/pom.xml
+++ b/examples/kerberos/pom.xml
@@ -44,7 +44,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/examples/ldap/pom.xml b/examples/ldap/pom.xml
index d3767e3..2412222 100644
--- a/examples/ldap/pom.xml
+++ b/examples/ldap/pom.xml
@@ -42,7 +42,7 @@
     <dependencies>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/integration/client-registration/src/main/java/org/keycloak/client/registration/ClientRegistration.java b/integration/client-registration/src/main/java/org/keycloak/client/registration/ClientRegistration.java
index b83e652..8961aad 100644
--- a/integration/client-registration/src/main/java/org/keycloak/client/registration/ClientRegistration.java
+++ b/integration/client-registration/src/main/java/org/keycloak/client/registration/ClientRegistration.java
@@ -177,7 +177,7 @@ public class ClientRegistration {
         }
 
         public ClientRegistrationBuilder url(String authUrl, String realm) {
-            url = HttpUtil.getUrl(authUrl, "realms", realm, "clients");
+            url = HttpUtil.getUrl(authUrl, "realms", realm, "clients-registrations");
             return this;
         }
 
diff --git a/model/jpa/pom.xml b/model/jpa/pom.xml
index bbed050..6b03eec 100755
--- a/model/jpa/pom.xml
+++ b/model/jpa/pom.xml
@@ -63,7 +63,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>org.hibernate</groupId>

pom.xml 111(+54 -57)

diff --git a/pom.xml b/pom.xml
index ec2b0e6..58ba936 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,71 +40,74 @@
         <product.version>${project.version}</product.version>
         <product.build-time>${timestamp}</product.build-time>
 
-        <apacheds.version>2.0.0-M17</apacheds.version>
-        <apacheds.codec.version>1.0.0-M23</apacheds.codec.version>
-        <org.apache.james.apache-mime4j.version>0.6</org.apache.james.apache-mime4j.version>
-        <bouncycastle.crypto.version>1.52</bouncycastle.crypto.version>
+        <!-- WildFly -->
+        <eap.version>7.0.0.Beta</eap.version>
+        <jboss.as.version>7.2.0.Final</jboss.as.version>
+        <wildfly.version>10.0.0.Final</wildfly.version>
+
+        <aesh.version>0.66.4</aesh.version>
+        <apache.httpcomponents.version>4.5</apache.httpcomponents.version>
+        <apache.httpcomponents.httpcore.version>4.4.1</apache.httpcomponents.httpcore.version>
+        <apache.mime4j.version>0.6</apache.mime4j.version>
+        <bouncycastle.version>1.52</bouncycastle.version>
+        <dom4j.version>1.6.1</dom4j.version>
+        <github.relaxng.version>2011.1</github.relaxng.version>
+        <h2.version>1.3.173</h2.version>
+        <hibernate.entitymanager.version>5.0.7.Final</hibernate.entitymanager.version>
+        <hibernate.javax.persistence.version>1.0.0.Final</hibernate.javax.persistence.version>
+        <infinispan.version>8.1.0.Final</infinispan.version>
         <jackson.version>2.5.4</jackson.version>
-        <apache.httpcomponents.version>4.3.6</apache.httpcomponents.version>
-        <apache.httpcomponents.httpcore.version>4.3.3</apache.httpcomponents.httpcore.version>
-        <resteasy.version>3.0.14.Final</resteasy.version>
-        <keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version>
-        <undertow.version>1.3.10.Final</undertow.version>
-        <picketlink.version>2.7.0.Final</picketlink.version>
-        <mongo.driver.version>3.2.0</mongo.driver.version>
+        <javax.mail.version>1.5.5</javax.mail.version>
         <jboss.logging.version>3.3.0.Final</jboss.logging.version>
         <jboss.logging.tools.version>2.0.1.Final</jboss.logging.tools.version>
-        <jboss-logging-tools.version>1.2.0.Beta1</jboss-logging-tools.version>
-        <jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>1.0.4.Final</jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>
+        <jboss.logging.tools.wf8.version>1.2.0.Final</jboss.logging.tools.wf8.version>
         <jboss-jaxrs-api_2.0_spec>1.0.0.Final</jboss-jaxrs-api_2.0_spec>
-        <hibernate.javax.persistence.version>1.0.0.Final</hibernate.javax.persistence.version>
-        <hibernate.javax.persistence.artifactId>hibernate-jpa-2.1-api</hibernate.javax.persistence.artifactId>
-        <hibernate.entitymanager.version>4.3.10.Final</hibernate.entitymanager.version>
-        <h2.version>1.3.173</h2.version>
-        <mysql.version>5.1.29</mysql.version>
-        <postgresql.version>9.3-1100-jdbc41</postgresql.version>
-        <dom4j.version>1.6.1</dom4j.version>
-        <xml-apis.version>1.4.01</xml-apis.version>
+        <jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>1.0.4.Final</jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>
+        <log4j.version>1.2.16</log4j.version>
+        <resteasy.version>3.0.14.Final</resteasy.version>
+        <servlet.api.31.version>1.0.0.Final</servlet.api.31.version>
         <slf4j.version>1.7.7</slf4j.version>
-        <wildfly.version>10.0.0.Final</wildfly.version>
+        <sun.istack.version>2.21</sun.istack.version>
+        <sun.jaxb.version>2.2.11</sun.jaxb.version>
+        <sun.xsom.version>20140925</sun.xsom.version>
+        <undertow.version>1.3.15.Final</undertow.version>
         <wildfly.core.version>2.0.10.Final</wildfly.core.version>
         <wildfly.build-tools.version>1.1.0.Final</wildfly.build-tools.version>
+        <!--<xmlsec.version>2.0.5</xmlsec.version>--> <!-- WILDFLY VERSION -->
+        <xmlsec.version>1.5.1</xmlsec.version>
 
-        <eap.version>7.0.0.Beta</eap.version>
-
-        <jboss.version>7.2.0.Final</jboss.version>
-
-        <servlet.api.30.version>1.0.2.Final</servlet.api.30.version>
+        <!-- Others -->
+        <apacheds.version>2.0.0-M17</apacheds.version>
+        <apacheds.codec.version>1.0.0-M23</apacheds.codec.version>
         <google.zxing.version>3.2.1</google.zxing.version>
-        <github.relaxng.version>2011.1</github.relaxng.version>
         <freemarker.version>2.3.23</freemarker.version>
-        <twitter4j.version>4.0.4</twitter4j.version>
-        <selenium.version>2.35.0</selenium.version>
-        <sun.istack.version>2.21</sun.istack.version>
-        <sun.jaxb.version>2.2.11</sun.jaxb.version>
-        <sun.xsom.version>20140925</sun.xsom.version>
-        <javax.mail.version>1.4.5</javax.mail.version>
-        <infinispan.version>8.1.0.Final</infinispan.version>
-        <liquibase.version>3.4.1</liquibase.version>
         <jetty9.version>9.1.0.v20131115</jetty9.version>
+        <liquibase.version>3.4.1</liquibase.version>
+        <mongo.driver.version>3.2.0</mongo.driver.version>
+        <mysql.version>5.1.29</mysql.version>
         <osgi.version>4.2.0</osgi.version>
         <pax.web.version>3.1.2</pax.web.version>
+        <postgresql.version>9.3-1100-jdbc41</postgresql.version>
+        <twitter4j.version>4.0.4</twitter4j.version>
+
+        <!-- Test -->
+        <greenmail.version>1.3.1b</greenmail.version>
+        <hamcrest.version>1.3</hamcrest.version>
         <jmeter.version>2.10</jmeter.version>
         <junit.version>4.12</junit.version>
-        <hamcrest.version>1.3</hamcrest.version>
-        <log4j.version>1.2.17</log4j.version>
-        <greenmail.version>1.3.1b</greenmail.version>
-        <xmlsec.version>1.5.1</xmlsec.version>
-        <aesh.version>0.66.4</aesh.version>
+        <picketlink.version>2.7.0.Final</picketlink.version>
+        <selenium.version>2.35.0</selenium.version>
+        <xml-apis.version>1.4.01</xml-apis.version>
 
+        <!-- Maven Plugins -->
+        <embedmongo.plugin.version>0.1.12</embedmongo.plugin.version>
         <enforcer.plugin.version>1.4</enforcer.plugin.version>
         <jboss.as.plugin.version>7.5.Final</jboss.as.plugin.version>
-        <wildfly.plugin.version>1.0.1.Final</wildfly.plugin.version>
-        <minify.plugin.version>1.7.2</minify.plugin.version>
-        <embedmongo.plugin.version>0.1.12</embedmongo.plugin.version>
         <jmeter.plugin.version>1.9.0</jmeter.plugin.version>
         <jmeter.analysis.plugin.version>1.0.4</jmeter.analysis.plugin.version>
+        <minify.plugin.version>1.7.2</minify.plugin.version>
         <osgi.bundle.plugin.version>2.3.7</osgi.bundle.plugin.version>
+        <wildfly.plugin.version>1.0.1.Final</wildfly.plugin.version>
     </properties>
 
     <url>http://keycloak.org</url>
@@ -201,16 +204,16 @@
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcprov-jdk15on</artifactId>
-                <version>${bouncycastle.crypto.version}</version>
+                <version>${bouncycastle.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcpkix-jdk15on</artifactId>
-                <version>${bouncycastle.crypto.version}</version>
+                <version>${bouncycastle.version}</version>
             </dependency>
             <dependency>
                 <groupId>javax.mail</groupId>
-                <artifactId>mail</artifactId>
+                <artifactId>javax.mail-api</artifactId>
                 <version>${javax.mail.version}</version>
             </dependency>
             <dependency>
@@ -300,8 +303,8 @@
             </dependency>
             <dependency>
                 <groupId>org.jboss.spec.javax.servlet</groupId>
-                <artifactId>jboss-servlet-api_3.0_spec</artifactId>
-                <version>${servlet.api.30.version}</version>
+                <artifactId>jboss-servlet-api_3.1_spec</artifactId>
+                <version>${servlet.api.31.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.picketlink</groupId>
@@ -343,7 +346,7 @@
             </dependency>
             <dependency>
                 <groupId>org.hibernate.javax.persistence</groupId>
-                <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+                <artifactId>hibernate-jpa-2.1-api</artifactId>
                 <version>${hibernate.javax.persistence.version}</version>
             </dependency>
             <dependency>
@@ -508,7 +511,7 @@
             <dependency>
                 <groupId>org.apache.james</groupId>
                 <artifactId>apache-mime4j</artifactId>
-                <version>${org.apache.james.apache-mime4j.version}</version>
+                <version>${apache.mime4j.version}</version>
                 <exclusions>
                     <exclusion>
                         <groupId>commons-logging</groupId>
@@ -585,12 +588,6 @@
                 <version>${wildfly.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.jboss.logging</groupId>
-                <artifactId>jboss-logging-processor</artifactId>
-                <version>${jboss-logging-tools.version}</version>
-                <scope>compile</scope>
-            </dependency>
-            <dependency>
                 <groupId>org.infinispan</groupId>
                 <artifactId>infinispan-core</artifactId>
                 <version>${infinispan.version}</version>

services/pom.xml 4(+2 -2)

diff --git a/services/pom.xml b/services/pom.xml
index 039cda9..425ef53 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -54,7 +54,7 @@
         </dependency>
         <dependency>
             <groupId>javax.mail</groupId>
-            <artifactId>mail</artifactId>
+            <artifactId>javax.mail-api</artifactId>
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
@@ -63,7 +63,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.twitter4j</groupId>
diff --git a/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationService.java b/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationService.java
index b317600..e9651a9 100644
--- a/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationService.java
+++ b/services/src/main/java/org/keycloak/services/clientregistration/ClientRegistrationService.java
@@ -17,11 +17,11 @@
 
 package org.keycloak.services.clientregistration;
 
-import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.services.ErrorResponseException;
 
+import javax.ws.rs.NotFoundException;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.core.Context;
diff --git a/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java b/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java
index 8306972..45df982 100755
--- a/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AbstractSecuredLocalService.java
@@ -21,6 +21,7 @@ import org.jboss.resteasy.spi.HttpRequest;
 import org.keycloak.AbstractOAuthClient;
 import org.keycloak.common.ClientConnection;
 import org.keycloak.OAuth2Constants;
+import org.keycloak.common.util.KeycloakUriBuilder;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -113,13 +114,15 @@ public abstract class AbstractSecuredLocalService {
                 throw new BadRequestException("state not specified");
             }
 
-            URI uri = getBaseRedirectUri();
-            URI redirectUri = path != null ? uri.resolve(path) : uri;
+            KeycloakUriBuilder redirect = KeycloakUriBuilder.fromUri(getBaseRedirectUri());
+            if (path != null) {
+                redirect.path(path);
+            }
             if (referrer != null) {
-                redirectUri = redirectUri.resolve("?referrer=" + referrer);
+                redirect.queryParam("referrer", referrer);
             }
 
-            return Response.status(302).location(redirectUri).build();
+            return Response.status(302).location(redirect.build()).build();
         } finally {
         }
     }
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 1845501..1d39612 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -84,23 +84,6 @@ public class RealmsResource {
         return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getBrokerService");
     }
 
-    @Path("{realm}/login-status-iframe.html")
-    @Deprecated
-    public Object getLoginStatusIframe(final @PathParam("realm") String name,
-                                       @QueryParam("client_id") String client_id,
-                                       @QueryParam("origin") String origin) {
-        RealmModel realm = init(name);
-
-        EventBuilder event = new EventBuilder(realm, session, clientConnection);
-
-        LoginProtocolFactory factory = (LoginProtocolFactory)session.getKeycloakSessionFactory().getProviderFactory(LoginProtocol.class, OIDCLoginProtocol.LOGIN_PROTOCOL);
-        OIDCLoginProtocolService endpoint = (OIDCLoginProtocolService)factory.createProtocolEndpoint(realm, event);
-
-        ResteasyProviderFactory.getInstance().injectProperties(endpoint);
-        return endpoint.getLoginStatusIframe();
-
-    }
-
     @Path("{realm}/protocol/{protocol}")
     public Object getProtocol(final @PathParam("realm") String name,
                                             final @PathParam("protocol") String protocol) {
@@ -115,13 +98,6 @@ public class RealmsResource {
         return endpoint;
     }
 
-    @Path("{realm}/tokens")
-    @Deprecated
-    public Object getTokenService(final @PathParam("realm") String name) {
-        // for backward compatibility.
-        return getProtocol(name, "openid-connect");
-    }
-
     @Path("{realm}/login-actions")
     public LoginActionsService getLoginActionsService(final @PathParam("realm") String name) {
         RealmModel realm = init(name);
@@ -131,7 +107,7 @@ public class RealmsResource {
         return service;
     }
 
-    @Path("{realm}/clients")
+    @Path("{realm}/clients-registrations")
     public ClientRegistrationService getClientsService(final @PathParam("realm") String name) {
         RealmModel realm = init(name);
         EventBuilder event = new EventBuilder(realm, session, clientConnection);
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index 6650521..d9331f9 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -57,7 +57,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -183,7 +183,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 4f08b9b..8d9e85d 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -774,4 +774,27 @@ public class AccountTest {
         Assert.assertEquals(0, thirdPartyEntry.getProtocolMappersGranted().size());
     }
 
+    @Test
+    public void loginToSpecificPage() {
+        changePasswordPage.open();
+        loginPage.login("test-user@localhost", "password");
+
+        Assert.assertTrue(changePasswordPage.isCurrent());
+
+        events.clear();
+    }
+
+    @Test
+    public void loginToSpecificPageWithReferrer() {
+        driver.navigate().to(changePasswordPage.getPath() + "?referrer=account");
+        System.out.println(driver.getCurrentUrl());
+
+        loginPage.login("test-user@localhost", "password");
+        System.out.println(driver.getCurrentUrl());
+
+        Assert.assertTrue(changePasswordPage.isCurrent());
+
+        events.clear();
+    }
+
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java
index a5c2f0f..16e302e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/AbstractKerberosTest.java
@@ -284,7 +284,7 @@ public abstract class AbstractKerberosTest {
         SpnegoAuthenticator.bypassChallengeJavascript = true;
         driver.navigate().to(KERBEROS_APP_URL);
         String kcLoginPageLocation = driver.getCurrentUrl();
-        String location = "http://localhost:8081/auth/realms/test/protocol/openid-connect/auth?response_type=code&client_id=kerberos-app&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fkerberos-portal&state=0%2F88a96ddd-84fe-4e77-8a46-02394d7b3a7d&login=true";
+
         // Request for SPNEGO login sent with Resteasy client
         spnegoSchemeFactory.setCredentials(username, password);
         Response response = client.target(kcLoginPageLocation).request().get();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KeycloakSPNegoSchemeFactory.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KeycloakSPNegoSchemeFactory.java
index ff48af6..5dbffd1 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KeycloakSPNegoSchemeFactory.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/KeycloakSPNegoSchemeFactory.java
@@ -22,6 +22,7 @@ import java.security.PrivilegedExceptionAction;
 import javax.security.auth.Subject;
 
 import org.apache.http.auth.AuthScheme;
+import org.apache.http.auth.Credentials;
 import org.apache.http.impl.auth.SPNegoScheme;
 import org.apache.http.impl.auth.SPNegoSchemeFactory;
 import org.apache.http.params.HttpParams;
@@ -72,7 +73,7 @@ public class KeycloakSPNegoSchemeFactory extends SPNegoSchemeFactory {
 
 
         @Override
-        protected byte[] generateGSSToken(byte[] input, Oid oid, String authServer) throws GSSException {
+        protected byte[] generateGSSToken(byte[] input, Oid oid, String authServer, Credentials credentials) throws GSSException {
             KerberosUsernamePasswordAuthenticator authenticator = new KerberosUsernamePasswordAuthenticator(kerberosConfig);
             try {
                 Subject clientSubject = authenticator.authenticateSubject(username, password);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
index 46e2b9b..30a3947 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
@@ -33,6 +33,7 @@ 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 org.keycloak.testsuite.util.cli.InfinispanCLI;
 import org.keycloak.util.JsonSerialization;
 
 import javax.servlet.DispatcherType;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountPasswordPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountPasswordPage.java
index 7231b23..1e1da65 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountPasswordPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountPasswordPage.java
@@ -58,7 +58,7 @@ public class AccountPasswordPage extends AbstractAccountPage {
     }
 
     public boolean isCurrent() {
-        return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().endsWith("/account/password");
+        return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().split("\\?")[0].endsWith("/account/password");
     }
 
     public void open() {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java
new file mode 100644
index 0000000..8b72c1d
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractCommand.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util.cli;
+
+import java.util.List;
+
+import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.KeycloakSessionTask;
+import org.keycloak.models.utils.KeycloakModelUtils;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public abstract class AbstractCommand {
+
+    protected final Logger log = Logger.getLogger(this.getClass().getName());
+
+    protected List<String> args;
+    protected KeycloakSessionFactory sessionFactory;
+
+    public void injectProperties(List<String> args, InfinispanCLI cli, KeycloakSessionFactory sessionFactory) {
+        this.args = args;
+        this.sessionFactory = sessionFactory;
+    }
+
+    public void runCommand() {
+        try {
+            KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+
+                @Override
+                public void run(KeycloakSession session) {
+                    doRunCommand(session);
+                }
+
+            });
+        } catch (HandledException handled) {
+            // Fine to ignore. Was handled already
+        } catch (RuntimeException e) {
+            log.error("Error occured during command. ", e);
+        }
+    }
+
+    public abstract String getName();
+    protected abstract void doRunCommand(KeycloakSession session);
+
+    protected String getArg(int index) {
+        try {
+            return args.get(index);
+        } catch (IndexOutOfBoundsException ex) {
+            log.errorf("Usage: %s", printUsage());
+            throw new HandledException();
+        }
+    }
+
+    protected Integer getIntArg(int index) {
+        String str = getArg(index);
+        try {
+            return Integer.parseInt(str);
+        } catch (NumberFormatException nex) {
+            log.errorf("Usage: %s", printUsage());
+            throw new HandledException();
+        }
+    }
+
+    public String printUsage() {
+        return getName();
+    }
+
+    public static class HandledException extends RuntimeException {
+    }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractOfflineCacheCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractOfflineCacheCommand.java
new file mode 100644
index 0000000..ae677b8
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/AbstractOfflineCacheCommand.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util.cli;
+
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.context.Flag;
+import org.keycloak.common.util.Time;
+import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
+import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public abstract class AbstractOfflineCacheCommand extends AbstractCommand {
+
+    @Override
+    protected void doRunCommand(KeycloakSession session) {
+        InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
+        Cache<String, SessionEntity> ispnCache = provider.getCache(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME);
+        doRunCacheCommand(session, ispnCache);
+    }
+
+    protected void printSession(String id, UserSessionEntity userSession) {
+        if (userSession == null) {
+            log.info("Not found session with Id: " + id);
+        } else {
+            log.info("Found session. ID: " + toString(userSession));
+        }
+    }
+
+    protected String toString(UserSessionEntity userSession) {
+        int clientSessionsSize = userSession.getClientSessions()==null ? 0 : userSession.getClientSessions().size();
+        return "ID: " + userSession.getId() + ", realm: " + userSession.getRealm() + ", lastAccessTime: " + Time.toDate(userSession.getLastSessionRefresh()) +
+                ", clientSessions: " + clientSessionsSize;
+    }
+
+    protected abstract void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache);
+
+
+    // IMPLS
+
+    public static class PutCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "put";
+        }
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            UserSessionEntity userSession = new UserSessionEntity();
+            String id = getArg(0);
+
+            userSession.setId(id);
+            userSession.setRealm(getArg(1));
+
+            userSession.setLastSessionRefresh(Time.currentTime());
+            cache.put(id, userSession);
+        }
+
+        @Override
+        public String printUsage() {
+            return getName() + " <user-session-id> <realm-name>";
+        }
+    }
+
+
+    public static class GetCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "get";
+        }
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            String id = getArg(0);
+            UserSessionEntity userSession = (UserSessionEntity) cache.get(id);
+            printSession(id, userSession);
+        }
+
+        @Override
+        public String printUsage() {
+            return getName() + " <user-session-id>";
+        }
+    }
+
+
+    public static class RemoveCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "remove";
+        }
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            String id = getArg(0);
+            cache.remove(id);
+        }
+
+        @Override
+        public String printUsage() {
+            return getName() + " <user-session-id>";
+        }
+    }
+
+
+    public static class ClearCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "clear";
+        }
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            cache.clear();
+        }
+    }
+
+
+    public static class SizeCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "size";
+        }
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            log.info("Size: " + cache.size());
+        }
+    }
+
+
+    public static class ListCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "list";
+        }
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            for (String id : cache.keySet()) {
+                SessionEntity entity = cache.get(id);
+                if (!(entity instanceof UserSessionEntity)) {
+                    continue;
+                }
+                UserSessionEntity userSession = (UserSessionEntity) cache.get(id);
+                log.info("list: key=" + id + ", value=" + toString(userSession));
+            }
+        }
+    }
+
+
+    public static class GetLocalCommand extends AbstractOfflineCacheCommand {
+
+        @Override
+        public String getName() {
+            return "getLocal";
+        }
+
+
+        @Override
+        protected void doRunCacheCommand(KeycloakSession session, Cache<String, SessionEntity> cache) {
+            String id = getArg(0);
+            cache = ((AdvancedCache) cache).withFlags(Flag.CACHE_MODE_LOCAL);
+            UserSessionEntity userSession = (UserSessionEntity) cache.get(id);
+            printSession(id, userSession);
+        }
+
+        @Override
+        public String printUsage() {
+            return getName() + " <user-session-id>";
+        }
+    }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/InfinispanCLI.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/InfinispanCLI.java
new file mode 100644
index 0000000..22b1026
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/InfinispanCLI.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util.cli;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.testsuite.KeycloakServer;
+
+/**
+ * HOWTO USE THIS:
+ *
+ * 1) Run KeycloakServer with system properties (assuming mongo up and running on localhost):
+ *      -Dkeycloak.realm.provider=mongo -Dkeycloak.user.provider=mongo -Dkeycloak.userSessionPersister.provider=mongo -Dkeycloak.connectionsMongo.db=keycloak -Dkeycloak.connectionsInfinispan.clustered=true -Dresources -DstartInfinispanCLI
+ *
+ * 2) Write command on STDIN to persist 50000 userSessions to mongo: persistSessions 50000
+ *
+ * 3) Run command "clear" to ensure infinispan cache is cleared. Doublecheck with command "size" is 0
+ *
+ * 4) Write command to load sessions from persistent storage - 100 sessions per worker transaction: loadPersistentSessions 100
+ *
+ * See the progress in log. Finally run command "size" to ensure size is 100001 (50000 userSessions + 50000 clientSessions + 1 initializationState item)
+ *
+ * 5) Alternative to step 3+4 - Kill the server after step 2 and start two KeycloakServer in parallel on ports 8081 and 8082 . See the progress in logs of loading persistent sessions to infinispan.
+ * Kill the coordinator (usually 8081 node) during startup and see the node 8082 became coordinator and took ownership of loading persistent sessions. After node 8082 fully started, the size of infinispan is again 100001
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class InfinispanCLI {
+
+    private static final Logger log = Logger.getLogger(InfinispanCLI.class);
+
+    private static final Class<?>[] BUILTIN_COMMANDS = {
+            ExitCommand.class,
+            HelpCommand.class,
+            AbstractOfflineCacheCommand.PutCommand.class,
+            AbstractOfflineCacheCommand.GetCommand.class,
+            AbstractOfflineCacheCommand.GetLocalCommand.class,
+            AbstractOfflineCacheCommand.RemoveCommand.class,
+            AbstractOfflineCacheCommand.SizeCommand.class,
+            AbstractOfflineCacheCommand.ListCommand.class,
+            AbstractOfflineCacheCommand.ClearCommand.class,
+            PersistSessionsCommand.class,
+            LoadPersistentSessionsCommand.class,
+            UserCommands.Create.class,
+            UserCommands.Remove.class,
+            UserCommands.Count.class,
+            UserCommands.GetUser.class
+    };
+
+    private final KeycloakSessionFactory sessionFactory;
+    private final Map<String, Class<? extends AbstractCommand>> commands = new LinkedHashMap<>();
+
+    public InfinispanCLI(KeycloakServer server) {
+        this.sessionFactory = server.getSessionFactory();
+
+        // register builtin commands
+        for (Class<?> clazz : BUILTIN_COMMANDS) {
+            Class<? extends AbstractCommand> commandClazz = (Class<? extends AbstractCommand>) clazz;
+            try {
+                AbstractCommand command = commandClazz.newInstance();
+                commands.put(command.getName(), commandClazz);
+            } catch (Exception ex) {
+                log.error("Error registering command of class: " + commandClazz.getName(), ex);
+            }
+        }
+    }
+
+    public void registerCommand(String name, Class<? extends AbstractCommand> command) {
+        commands.put(name, command);
+    }
+
+    // WARNING: Stdin blocking operation
+    public void start() throws IOException {
+        log.info("Starting infinispan CLI. Exit with 'exit' . Available commands with 'help' ");
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+        String line;
+        try {
+            while ((line = reader.readLine()) != null) {
+                log.info("Command: " + line);
+
+                String[] splits = line.split(" ");
+                String commandName = splits[0];
+                Class<? extends AbstractCommand> commandClass = commands.get(commandName);
+                if (commandClass == null) {
+                    log.errorf("Unknown command: %s", commandName);
+                } else {
+                    try {
+                        AbstractCommand command = commandClass.newInstance();
+                        List<String> args = new ArrayList<>(Arrays.asList(splits));
+                        args.remove(0);
+                        command.injectProperties(args, this, sessionFactory);
+                        command.runCommand();
+
+                        // Just special handling of ExitCommand
+                        if (command instanceof ExitCommand) {
+                            return;
+                        }
+
+                    } catch (InstantiationException ex) {
+                        log.error(ex);
+                    } catch (IllegalAccessException ex) {
+                        log.error(ex);
+                    }
+                }
+            }
+        } finally {
+            log.info("Exit infinispan CLI");
+            reader.close();
+        }
+    }
+
+    public static class ExitCommand extends AbstractCommand {
+
+        @Override
+        public String getName() {
+            return "exit";
+        }
+
+        @Override
+        public void runCommand() {
+            // no need to implement. Exit handled in parent
+        }
+
+        @Override
+        protected void doRunCommand(KeycloakSession session) {
+            // no need to implement
+        }
+
+        @Override
+        public String printUsage() {
+            return getName();
+        }
+    }
+
+    public static class HelpCommand extends AbstractCommand {
+
+        private List<String> commandNames = new ArrayList<>();
+
+        @Override
+        public void injectProperties(List<String> args, InfinispanCLI cli, KeycloakSessionFactory sessionFactory) {
+            for (String commandName : cli.commands.keySet()) {
+                commandNames.add(commandName);
+            }
+        }
+
+        @Override
+        public String getName() {
+            return "help";
+        }
+
+        @Override
+        public void runCommand() {
+            log.info("Available commands: " + commandNames.toString());
+        }
+
+        @Override
+        protected void doRunCommand(KeycloakSession session) {
+            // no need to implement
+        }
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/LoadPersistentSessionsCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/LoadPersistentSessionsCommand.java
new file mode 100644
index 0000000..0c1a506
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/LoadPersistentSessionsCommand.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util.cli;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.UserSessionProvider;
+import org.keycloak.models.UserSessionProviderFactory;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class LoadPersistentSessionsCommand extends AbstractCommand {
+
+    @Override
+    public String getName() {
+        return "loadPersistentSessions";
+    }
+
+    @Override
+    protected void doRunCommand(KeycloakSession session) {
+        int sessionsPerSegment = getIntArg(0);
+        UserSessionProviderFactory sessionProviderFactory = (UserSessionProviderFactory) sessionFactory.getProviderFactory(UserSessionProvider.class);
+        sessionProviderFactory.loadPersistentSessions(sessionFactory, 10, sessionsPerSegment);
+
+        log.info("All persistent sessions loaded successfully");
+    }
+
+    @Override
+    public String printUsage() {
+        return super.printUsage() + " <sessions-count-per-segment>";
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java
new file mode 100644
index 0000000..7f67865
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/PersistSessionsCommand.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util.cli;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ClientSessionModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionTask;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.session.UserSessionPersisterProvider;
+import org.keycloak.models.utils.KeycloakModelUtils;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class PersistSessionsCommand extends AbstractCommand {
+
+    @Override
+    public String getName() {
+        return "persistSessions";
+    }
+
+    @Override
+    public void doRunCommand(KeycloakSession sess) {
+        final int count = getIntArg(0);
+        final List<String> userSessionIds = new LinkedList<>();
+        final List<String> clientSessionIds = new LinkedList<>();
+
+        // Create sessions in separate transaction first
+        KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+
+            @Override
+            public void run(KeycloakSession session) {
+                RealmModel realm = session.realms().getRealmByName("master");
+                UserModel john = session.users().getUserByUsername("admin", realm);
+                ClientModel testApp = realm.getClientByClientId("security-admin-console");
+                UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
+
+                for (int i = 0; i < count; i++) {
+                    UserSessionModel userSession = session.sessions().createUserSession(realm, john, "john-doh@localhost", "127.0.0.2", "form", true, null, null);
+                    ClientSessionModel clientSession = session.sessions().createClientSession(realm, testApp);
+                    clientSession.setUserSession(userSession);
+                    clientSession.setRedirectUri("http://redirect");
+                    clientSession.setNote("foo", "bar-" + i);
+                    userSessionIds.add(userSession.getId());
+                    clientSessionIds.add(clientSession.getId());
+                }
+            }
+
+        });
+
+        log.info("Sessions created in infinispan storage");
+
+        // Persist them now
+        KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+
+            @Override
+            public void run(KeycloakSession session) {
+                RealmModel realm = session.realms().getRealmByName("master");
+                UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
+
+                int counter = 0;
+                for (String userSessionId : userSessionIds) {
+                    counter++;
+                    UserSessionModel userSession = session.sessions().getUserSession(realm, userSessionId);
+                    persister.createUserSession(userSession, true);
+                    if (counter%1000 == 0) {
+                        log.infof("%d user sessions persisted. Continue", counter);
+                    }
+                }
+
+                log.infof("All %d user sessions persisted", counter);
+
+                counter = 0;
+                for (String clientSessionId : clientSessionIds) {
+                    counter++;
+                    ClientSessionModel clientSession = session.sessions().getClientSession(realm, clientSessionId);
+                    persister.createClientSession(clientSession, true);
+                    if (counter%1000 == 0) {
+                        log.infof("%d client sessions persisted. Continue", counter);
+                    }
+                }
+
+                log.infof("All %d client sessions persisted", counter);
+            }
+
+        });
+
+        // Persist them now
+        KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+
+            @Override
+            public void run(KeycloakSession session) {
+                UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
+                log.info("Total number of sessions in persister: " + persister.getUserSessionsCount(true));
+            }
+
+        });
+    }
+
+    @Override
+    public String printUsage() {
+        return super.printUsage() + " <sessions-count>";
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/UserCommands.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/UserCommands.java
new file mode 100644
index 0000000..950b9a4
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/UserCommands.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util.cli;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class UserCommands {
+
+    public static class Create extends AbstractCommand {
+
+        @Override
+        public String getName() {
+            return "createUsers";
+        }
+
+        @Override
+        protected void doRunCommand(KeycloakSession session) {
+            String usernamePrefix = getArg(0);
+            String password = getArg(1);
+            String realmName = getArg(2);
+            int first = getIntArg(3);
+            int count = getIntArg(4);
+            String roleNames = getArg(5);
+
+            RealmModel realm = session.realms().getRealmByName(realmName);
+            if (realm == null) {
+                log.errorf("Unknown realm: %s", realmName);
+                return;
+            }
+
+            Set<RoleModel> roles = findRoles(realm, roleNames);
+
+            int last = first + count;
+            for (int counter = first; counter < last; counter++) {
+                String username = usernamePrefix + counter;
+                UserModel user = session.users().addUser(realm, username);
+                user.setEnabled(true);
+                user.setEmail(username + "@keycloak.org");
+                UserCredentialModel passwordCred = UserCredentialModel.password(password);
+                user.updateCredential(passwordCred);
+
+                for (RoleModel role : roles) {
+                    user.grantRole(role);
+                }
+            }
+            log.infof("Users from %s to %s created", usernamePrefix + first, usernamePrefix + (last - 1));
+        }
+
+        @Override
+        public String printUsage() {
+            return super.printUsage() + " <username-prefix> <password> <realm-name> <starting-user-offset> <count> <realm-roles-list>. \nRoles list is divided by comma (client roles not yet supported)>\n" +
+                    "Example usage: " + super.printUsage() + " test test demo 0 20 user,admin";
+        }
+
+        private Set<RoleModel> findRoles(RealmModel realm, String rolesList) {
+            Set<RoleModel> result = new HashSet<>();
+
+            String[] roles = rolesList.split(",");
+            for (String roleName : roles) {
+                roleName = roleName.trim();
+                RoleModel role;
+                if (roleName.contains("/")) {
+                    String[] spl = roleName.split("/");
+                    ClientModel client = realm.getClientByClientId(spl[0]);
+                    if (client == null) {
+                        log.errorf("Client not found: %s", spl[0]);
+                        throw new HandledException();
+                    }
+                    role = client.getRole(spl[1]);
+                } else {
+                    role = realm.getRole(roleName);
+                }
+
+                if (role == null) {
+                    log.errorf("Role not found: %s", roleName);
+                    throw new HandledException();
+                }
+
+                result.add(role);
+            }
+
+            return result;
+        }
+
+    }
+
+
+    public static class Remove extends AbstractCommand {
+
+        @Override
+        public String getName() {
+            return "removeUsers";
+        }
+
+        @Override
+        protected void doRunCommand(KeycloakSession session) {
+            String usernamePrefix = getArg(0);
+            String realmName = getArg(1);
+            int first = getIntArg(2);
+            int count = getIntArg(3);
+
+            RealmModel realm = session.realms().getRealmByName(realmName);
+            if (realm == null) {
+                log.errorf("Unknown realm: %s", realmName);
+                return;
+            }
+
+            int last = first + count;
+            for (int counter = first; counter < last; counter++) {
+                String username = usernamePrefix + counter;
+                UserModel user = session.users().getUserByUsername(username, realm);
+                if (user == null) {
+                    log.errorf("User '%s' not found", username);
+                } else {
+                    session.users().removeUser(realm, user);
+                }
+            }
+            log.infof("Users from %s to %s removed", usernamePrefix + first, usernamePrefix + (last - 1));
+        }
+
+        @Override
+        public String printUsage() {
+            return super.printUsage() + " <username-prefix> <realm-name> <starting-user-offset> <count> \n" +
+                    "Example usage: " + super.printUsage() + " test demo 0 20";
+        }
+    }
+
+
+    public static class Count extends AbstractCommand {
+
+        @Override
+        public String getName() {
+            return "getUsersCount";
+        }
+
+        @Override
+        protected void doRunCommand(KeycloakSession session) {
+            String realmName = getArg(0);
+            RealmModel realm = session.realms().getRealmByName(realmName);
+            if (realm == null) {
+                log.errorf("Unknown realm: %s", realmName);
+                return;
+            }
+
+            int usersCount = session.users().getUsersCount(realm);
+            log.infof("Users count in realm %s: %d", realmName, usersCount);
+        }
+
+        @Override
+        public String printUsage() {
+            return super.printUsage() + " <realm-name>";
+        }
+    }
+
+
+    public static class GetUser extends AbstractCommand {
+
+        @Override
+        public String getName() {
+            return "getUser";
+        }
+
+        @Override
+        protected void doRunCommand(KeycloakSession session) {
+            String realmName = getArg(0);
+            String username = getArg(1);
+            RealmModel realm = session.realms().getRealmByName(realmName);
+            if (realm == null) {
+                log.errorf("Unknown realm: %s", realmName);
+                return;
+            }
+
+            UserModel user = session.users().getUserByUsername(username, realm);
+            if (user == null) {
+                log.infof("User '%s' doesn't exist in realm '%s'", username, realmName);
+            } else {
+                log.infof("User: ID: '%s', username: '%s', mail: '%s'", user.getId(), user.getUsername(), user.getEmail());
+            }
+        }
+
+        @Override
+        public String printUsage() {
+            return super.printUsage() + " <realm-name> <username>";
+        }
+    }
+}
diff --git a/testsuite/integration-arquillian/README.md b/testsuite/integration-arquillian/README.md
index 5f7f831..39168de 100644
--- a/testsuite/integration-arquillian/README.md
+++ b/testsuite/integration-arquillian/README.md
@@ -13,17 +13,28 @@ other options are: `auth-server-wildfly` and `auth-server-eap7`. The values corr
 **Note 1:** For the non-default options it's necessary to build a corresponding server module prior to running any of the test modules.
 This can be done by building the server module directly (from `servers/wildfly`/`servers/eap7`), 
 or by activating `auth-server-wildfly`/`auth-server-eap7` profile when building from the top level module.
-(The profiles will also set the proper value of the `auth.server.container` property.)
 
 **Note 2:** Most server-side configurations are done during the build of the server module
 and included in the output artifact - which is then consumed by the test modules( if a corresponding profile is activated).
 To reflect a change in server config in the test (e.g. a datasource) it's necessary to rebuild the server module after each change.
 
-### Migration
+#### Migration
 
-Migration tests can be enabled by setting `-Dmigrated.auth.server.container` property or activating a corresponding profile.
-When enabled, the `AuthServerTestEnricher` class will start/stop the selected *migrated* instance 
-even **before** the *current* auth server instance is started.
+Migration tests can be enabled by setting `-Dmigrated.auth.server.version` property. Supported versions can be found at the bottom of `tests/pom.xml`.
+When enabled, the `AuthServerTestEnricher` class will start and stop the selected migrated instance 
+*before* the current auth server instance is started.
+
+#### Cluster Setup
+
+Cluster setup can be enabled with profile `auth-server-wildfly-cluster`.
+(It is also necessary to build the server modules with this profile before running the test. See *Notes 1 and 2* above.)
+
+Clustering tests require MULTICAST to be enabled on machine's `loopback` network interface.
+This can be done by running the following commands under root privileges:
+```
+route add -net 224.0.0.0 netmask 240.0.0.0 dev lo
+ifconfig lo multicast
+```
 
 ### App Servers
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java
index 9dd6089..fc523b7 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java
@@ -3,12 +3,15 @@ package org.keycloak.testsuite.cluster;
 import java.util.ArrayList;
 import java.util.List;
 import org.jboss.arquillian.container.test.api.ContainerController;
+import org.jboss.arquillian.graphene.page.Page;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import static org.junit.Assert.assertTrue;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.models.Constants;
+import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.arquillian.ContainerInfo;
+import org.keycloak.testsuite.auth.page.AuthRealm;
 import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
 import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
 
@@ -35,25 +38,38 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
             controller.start(backendNode.getQualifier());
             assertTrue(controller.isStarted(backendNode.getQualifier()));
 
-            log.info("Initializing admin client for: '" + backendNode.getContextRoot() + "/auth'");
-            backendAdminClients.add(Keycloak.getInstance(backendNode.getContextRoot() + "/auth",
-                    MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID));
+            backendAdminClients.add(createAdminClientFor(backendNode));
         }
     }
 
-    protected ContainerInfo backendInfo(int i) {
+    protected Keycloak createAdminClientFor(ContainerInfo backendNode) {
+        log.info("Initializing admin client for " + backendNode.getContextRoot() + "/auth");
+        return Keycloak.getInstance(backendNode.getContextRoot() + "/auth",
+                MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
+    }
+
+    protected ContainerInfo backendNode(int i) {
         return suiteContext.getAuthServerBackendsInfo().get(i);
     }
 
     protected void startBackendNode(int i) {
-        String container = backendInfo(i).getQualifier();
+        String container = backendNode(i).getQualifier();
         if (!controller.isStarted(container)) {
             controller.start(container);
+            backendAdminClients.set(i, createAdminClientFor(backendNode(i)));
         }
     }
 
-    protected void stopBackendNode(int i) {
-        controller.kill(backendInfo(i).getQualifier());
+    protected void killBackendNode(int i) {
+        backendAdminClients.get(i).close();
+        controller.kill(backendNode(i).getQualifier());
     }
 
+    protected void listRealms(int i) {
+        log.info(String.format("Node %s: AccessTokenString: %s", i + 1, backendAdminClients.get(i).tokenManager().getAccessTokenString()));
+        for (RealmRepresentation r : backendAdminClients.get(i).realms().findAll()) {
+            log.info(String.format("Node %s: Realm: %s, Id: %s", i + 1, r.getRealm(), r.getId()));
+        }
+    }
+    
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractTwoNodeClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractTwoNodeClusterTest.java
new file mode 100644
index 0000000..d88e616
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractTwoNodeClusterTest.java
@@ -0,0 +1,57 @@
+package org.keycloak.testsuite.cluster;
+
+import org.junit.Before;
+import org.keycloak.admin.client.Keycloak;
+import org.keycloak.testsuite.arquillian.ContainerInfo;
+import static org.keycloak.testsuite.util.WaitUtils.pause;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public abstract class AbstractTwoNodeClusterTest extends AbstractClusterTest {
+
+    @Before
+    public void beforeTwoNodeClusterTest() {
+        startBackendNodes(2);
+        pause(3000);
+    }
+
+    protected ContainerInfo backend1Info() {
+        return backendNode(0);
+    }
+
+    protected ContainerInfo backend2Info() {
+        return backendNode(1);
+    }
+
+    protected Keycloak backend1AdminClient() {
+        return backendAdminClients.get(0);
+    }
+
+    protected Keycloak backend2AdminClient() {
+        return backendAdminClients.get(1);
+    }
+
+    protected void startBackend1() {
+        startBackendNode(0);
+    }
+
+    protected void startBackend2() {
+        startBackendNode(1);
+    }
+
+    protected void failback() {
+        startBackend1();
+        startBackend2();
+    }
+
+    protected void killBackend1() {
+        killBackendNode(0);
+    }
+
+    protected void killBackend2() {
+        killBackendNode(1);
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/SessionFailoverClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/SessionFailoverClusterTest.java
new file mode 100644
index 0000000..591e2e8
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/SessionFailoverClusterTest.java
@@ -0,0 +1,95 @@
+package org.keycloak.testsuite.cluster;
+
+import java.util.List;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import static org.keycloak.testsuite.auth.page.AuthRealm.ADMIN;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+import static org.keycloak.testsuite.util.WaitUtils.pause;
+import org.openqa.selenium.Cookie;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class SessionFailoverClusterTest extends AbstractTwoNodeClusterTest {
+
+    public static final String KEYCLOAK_SESSION_COOKIE = "KEYCLOAK_SESSION";
+    public static final String KEYCLOAK_IDENTITY_COOKIE = "KEYCLOAK_IDENTITY";
+
+    @Override
+    public void addTestRealms(List<RealmRepresentation> testRealms) {
+    }
+
+    @Test
+    @Ignore("work in progress") // only works with owners="2" at the moment
+    public void sessionFailover() {
+        
+        // LOGOUT
+        accountPage.navigateTo();
+        driver.navigate().refresh();
+        pause(3000);
+        loginPage.form().login(ADMIN, ADMIN);
+        assertCurrentUrlStartsWith(accountPage);
+        
+        Cookie sessionCookie = driver.manage().getCookieNamed(KEYCLOAK_SESSION_COOKIE);
+        assertNotNull(sessionCookie);
+
+        killBackend1();
+
+        // check if session survived backend failure
+        
+        driver.navigate().refresh();
+        pause(3000);
+        
+        assertCurrentUrlStartsWith(accountPage);
+        Cookie sessionCookieAfterFailover = driver.manage().getCookieNamed(KEYCLOAK_SESSION_COOKIE);
+        assertNotNull(sessionCookieAfterFailover);
+        assertEquals(sessionCookieAfterFailover.getValue(), sessionCookie.getValue());
+
+        failback();
+
+        // check if session survived backend failback
+        driver.navigate().refresh();
+        pause(3000);
+        assertCurrentUrlStartsWith(accountPage);
+        Cookie sessionCookieAfterFailback = driver.manage().getCookieNamed(KEYCLOAK_SESSION_COOKIE);
+        assertNotNull(sessionCookieAfterFailback);
+        assertEquals(sessionCookieAfterFailover.getValue(), sessionCookie.getValue());
+
+        // LOGOUT
+        accountPage.navigateTo();
+        accountPage.signOut();
+
+        assertCurrentUrlDoesntStartWith(accountPage);
+        masterRealmPage.navigateTo();
+        sessionCookie = driver.manage().getCookieNamed(KEYCLOAK_SESSION_COOKIE);
+        assertNull(sessionCookie);
+
+        killBackend1();
+        
+        // check if session survived backend failure
+        driver.navigate().refresh();
+        pause(3000);
+        assertCurrentUrlDoesntStartWith(accountPage);
+        masterRealmPage.navigateTo();
+        sessionCookieAfterFailover = driver.manage().getCookieNamed(KEYCLOAK_SESSION_COOKIE);
+        assertNull(sessionCookieAfterFailover);
+        
+        failback();
+    
+        // check if session survived backend failback
+        driver.navigate().refresh();
+        pause(3000);
+        assertCurrentUrlDoesntStartWith(accountPage);
+        masterRealmPage.navigateTo();
+        sessionCookieAfterFailback = driver.manage().getCookieNamed(KEYCLOAK_SESSION_COOKIE);
+        assertNull(sessionCookieAfterFailback);
+    }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
index 404f5b5..fc91116 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
@@ -72,10 +72,12 @@
                 <property name="enabled">${auth.server.wildfly.cluster}</property>
                 <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
                 <property name="jbossHome">${keycloak.balancer.home}</property>
-                <property name="javaVmArguments">
+                <property name="jbossArguments">
                     -Djboss.socket.binding.port-offset=${auth.server.port.offset} 
-                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
-                    ${adapter.test.props}
+                </property>
+                <property name="javaVmArguments">
+                    -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m
+                    -Djava.net.preferIPv4Stack=true
                 </property>
                 <property name="managementPort">${auth.server.management.port}</property>
                 <property name="startupTimeoutInSeconds">${startup.timeout.sec}</property>
@@ -87,11 +89,14 @@
                 <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
                 <property name="jbossHome">${keycloak.backend1.home}</property>
                 <property name="serverConfig">standalone-ha.xml</property>
-                <property name="javaVmArguments">
+                <property name="jbossArguments">
                     -Djboss.socket.binding.port-offset=${auth.server.backend1.port.offset} 
-                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
-                    ${adapter.test.props}
                     -Djboss.node.name=node1
+                    ${adapter.test.props}
+                </property>
+                <property name="javaVmArguments">
+                    -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m
+                    -Djava.net.preferIPv4Stack=true
                 </property>
                 <!--<property name="outputToConsole">false</property>-->
                 <property name="managementPort">${auth.server.backend1.management.port}</property>
@@ -104,11 +109,14 @@
                 <property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
                 <property name="jbossHome">${keycloak.backend2.home}</property>
                 <property name="serverConfig">standalone-ha.xml</property>
-                <property name="javaVmArguments">
+                <property name="jbossArguments">
                     -Djboss.socket.binding.port-offset=${auth.server.backend2.port.offset} 
-                    -Xms64m -Xmx512m -XX:MaxPermSize=256m 
-                    ${adapter.test.props}
                     -Djboss.node.name=node2
+                    ${adapter.test.props}
+                </property>
+                <property name="javaVmArguments">
+                    -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m
+                    -Djava.net.preferIPv4Stack=true
                 </property>
                 <!--<property name="outputToConsole">false</property>-->
                 <property name="managementPort">${auth.server.backend2.management.port}</property>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/eap6/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/eap6/pom.xml
index b3e000a..6ee862c 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/eap6/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/eap6/pom.xml
@@ -69,7 +69,7 @@
                                 <artifactItem>
                                     <groupId>org.jboss.as</groupId>
                                     <artifactId>jboss-as-dist</artifactId>
-                                    <version>${jboss.version}</version>
+                                    <version>${jboss.as.version}</version>
                                     <type>zip</type>
                                     <outputDirectory>${containers.home}</outputDirectory>
                                 </artifactItem>
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 4e35234..533745d 100644
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -363,7 +363,7 @@
         
                 <dependency>
                     <groupId>org.hibernate.javax.persistence</groupId>
-                    <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+                    <artifactId>hibernate-jpa-2.1-api</artifactId>
                 </dependency>
                 <dependency>
                     <groupId>com.h2database</groupId>
diff --git a/testsuite/jetty/jetty81/pom.xml b/testsuite/jetty/jetty81/pom.xml
index 5c057cd..73dd109 100755
--- a/testsuite/jetty/jetty81/pom.xml
+++ b/testsuite/jetty/jetty81/pom.xml
@@ -59,7 +59,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -165,7 +165,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/jetty/jetty91/pom.xml b/testsuite/jetty/jetty91/pom.xml
index 4109077..1bb34e9 100755
--- a/testsuite/jetty/jetty91/pom.xml
+++ b/testsuite/jetty/jetty91/pom.xml
@@ -59,7 +59,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -165,7 +165,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/jetty/jetty92/pom.xml b/testsuite/jetty/jetty92/pom.xml
index 34484d6..76fb153 100755
--- a/testsuite/jetty/jetty92/pom.xml
+++ b/testsuite/jetty/jetty92/pom.xml
@@ -63,7 +63,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -165,7 +165,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/performance/pom.xml b/testsuite/performance/pom.xml
index f38bab5..f18dce2 100755
--- a/testsuite/performance/pom.xml
+++ b/testsuite/performance/pom.xml
@@ -203,8 +203,7 @@
 
                             <dependency>
                                 <groupId>org.hibernate.javax.persistence</groupId>
-                                <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
-                                <version>${hibernate.javax.persistence.version}</version>
+                                <artifactId>hibernate-jpa-2.1-api</artifactId>
                             </dependency>
                             <dependency>
                                 <groupId>com.h2database</groupId>
diff --git a/testsuite/proxy/pom.xml b/testsuite/proxy/pom.xml
index ab0082e..233f4d8 100755
--- a/testsuite/proxy/pom.xml
+++ b/testsuite/proxy/pom.xml
@@ -54,7 +54,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -156,7 +156,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/tomcat6/pom.xml b/testsuite/tomcat6/pom.xml
index 9090caa..42aeab4 100755
--- a/testsuite/tomcat6/pom.xml
+++ b/testsuite/tomcat6/pom.xml
@@ -53,7 +53,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -165,7 +165,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/tomcat7/pom.xml b/testsuite/tomcat7/pom.xml
index cca4ad5..8ca978b 100755
--- a/testsuite/tomcat7/pom.xml
+++ b/testsuite/tomcat7/pom.xml
@@ -77,7 +77,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -197,7 +197,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/tomcat8/pom.xml b/testsuite/tomcat8/pom.xml
index 7f55823..1f9cbb9 100755
--- a/testsuite/tomcat8/pom.xml
+++ b/testsuite/tomcat8/pom.xml
@@ -49,7 +49,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -169,7 +169,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/testsuite/wildfly/pom.xml b/testsuite/wildfly/pom.xml
index e325876..e907b70 100644
--- a/testsuite/wildfly/pom.xml
+++ b/testsuite/wildfly/pom.xml
@@ -56,7 +56,7 @@
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.servlet</groupId>
-            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
         </dependency>
         <dependency>
             <groupId>org.jboss.spec.javax.ws.rs</groupId>
@@ -158,7 +158,7 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>${hibernate.javax.persistence.artifactId}</artifactId>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git a/wildfly/server-subsystem/pom.xml b/wildfly/server-subsystem/pom.xml
index 7a08c7d..4f7ce1e 100755
--- a/wildfly/server-subsystem/pom.xml
+++ b/wildfly/server-subsystem/pom.xml
@@ -70,20 +70,13 @@
         <dependency>
             <groupId>org.jboss.logging</groupId>
             <artifactId>jboss-logging-annotations</artifactId>
-            <version>${jboss-logging-tools.version}</version>
-            <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
-            projects that depend on this project.-->
             <scope>provided</scope>
-            <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.logging</groupId>
             <artifactId>jboss-logging-processor</artifactId>
-            <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
-            projects that depend on this project.-->
             <scope>provided</scope>
-            <optional>true</optional>
         </dependency>
 
         <dependency>