keycloak-memoizeit
Changes
model/api/src/main/resources/META-INF/services/org.keycloak.hash.PasswordHashProviderFactory 1(+1 -0)
model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java 12(+6 -6)
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java 10(+5 -5)
services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java 2(+1 -1)
services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java 2(+1 -1)
services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java 2(+1 -1)
services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidateOTP.java 2(+1 -1)
services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidatePassword.java 2(+1 -1)
testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java 14(+12 -2)
testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/CustomerPortalExample.java 8(+4 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/ProductPortalExample.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java 7(+3 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java 12(+6 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/fragment/AccountManagementAlert.java 32(+32 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/PasswordFields.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/Login.java 7(+3 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginActions.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java 25(+12 -13)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/ResetCredentials.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java 7(+3 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/Authentication.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java 8(+4 -4)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java 12(+6 -6)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/AdminEvents.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/Config.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/LoginEvents.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/KerberosUserProviderForm.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/LdapUserProviderForm.java 17(+7 -10)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/UserFederation.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/AdminConsoleAlert.java 42(+13 -29)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java 17(+9 -8)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Menu.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java 10(+5 -5)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/ThemeSettings.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/TokenSettings.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java 16(+8 -8)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RolesTable.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/UserAttributesForm.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/Users.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java 51(+51 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java 50(+8 -42)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java 25(+2 -23)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java 2(+0 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AbstractAccountManagementTest.java 18(+17 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ChangePasswordTest.java 10(+5 -5)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java 20(+19 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/PasswordPolicyTest.java 40(+20 -20)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java 7(+3 -4)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java 10(+5 -5)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java 4(+2 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/KerberosUserFederationTest.java 10(+5 -5)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/LdapUserFederationTest.java 24(+12 -12)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/idp/IdentityProviderTest.java 3(+1 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/realm/SecurityDefensesTest.java 8(+4 -4)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/RealmRolesTest.java 10(+5 -5)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/RequiredUserActionsTest.java 6(+3 -3)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/UserAttributesTest.java 10(+5 -5)
Details
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
index 4365291..7b94680 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
@@ -1103,6 +1103,7 @@ module.factory('PasswordPolicy', function() {
     var p = {};
 
     p.policyMessages = {
+        hashAlgorithm: 	"Default hashing algorithm.  Default is 'pbkdf2'.",
         hashIterations: 	"Number of hashing iterations.  Default is 1.  Recommended is 50000.",
         length:         	"Minimal password length (integer type). Default value is 8.",
         digits:         	"Minimal number (integer type) of digits in password. Default value is 1.",
@@ -1116,6 +1117,7 @@ module.factory('PasswordPolicy', function() {
     }
 
     p.allPolicies = [
+        { name: 'hashAlgorithm', value: 'pbkdf2' },
         { name: 'hashIterations', value: 1 },
         { name: 'length', value: 8 },
         { name: 'digits', value: 1 },
                diff --git a/model/api/src/main/java/org/keycloak/hash/PasswordHashManager.java b/model/api/src/main/java/org/keycloak/hash/PasswordHashManager.java
new file mode 100644
index 0000000..5988a41
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/hash/PasswordHashManager.java
@@ -0,0 +1,30 @@
+package org.keycloak.hash;
+
+import org.keycloak.models.*;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class PasswordHashManager {
+
+    public static UserCredentialValueModel encode(KeycloakSession session, RealmModel realm, String rawPassword) {
+        PasswordPolicy passwordPolicy = realm.getPasswordPolicy();
+        String algorithm = passwordPolicy.getHashAlgorithm();
+        int iterations = passwordPolicy.getHashIterations();
+        if (iterations < 1) {
+            iterations = 1;
+        }
+        PasswordHashProvider provider = session.getProvider(PasswordHashProvider.class, algorithm);
+        if (provider == null) {
+            throw new RuntimeException("Password hash provider for algorithm " + algorithm + " not found");
+        }
+        return provider.encode(rawPassword, iterations);
+    }
+
+    public static boolean verify(KeycloakSession session, RealmModel realm, String password, UserCredentialValueModel credential) {
+        String algorithm = credential.getAlgorithm() != null ? credential.getAlgorithm() : realm.getPasswordPolicy().getHashAlgorithm();
+        PasswordHashProvider provider = session.getProvider(PasswordHashProvider.class, algorithm);
+        return provider.verify(password, credential);
+    }
+
+}
                diff --git a/model/api/src/main/java/org/keycloak/hash/PasswordHashProvider.java b/model/api/src/main/java/org/keycloak/hash/PasswordHashProvider.java
new file mode 100644
index 0000000..df0e21d
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/hash/PasswordHashProvider.java
@@ -0,0 +1,15 @@
+package org.keycloak.hash;
+
+import org.keycloak.models.UserCredentialValueModel;
+import org.keycloak.provider.Provider;
+
+/**
+ * @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
+ */
+public interface PasswordHashProvider extends Provider {
+
+    UserCredentialValueModel encode(String rawPassword, int iterations);
+
+    boolean verify(String rawPassword, UserCredentialValueModel credential);
+
+}
                diff --git a/model/api/src/main/java/org/keycloak/hash/PasswordHashProviderFactory.java b/model/api/src/main/java/org/keycloak/hash/PasswordHashProviderFactory.java
new file mode 100644
index 0000000..5c16baa
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/hash/PasswordHashProviderFactory.java
@@ -0,0 +1,10 @@
+package org.keycloak.hash;
+
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
+ */
+public interface PasswordHashProviderFactory extends ProviderFactory<PasswordHashProvider> {
+
+}
                diff --git a/model/api/src/main/java/org/keycloak/hash/PasswordHashSpi.java b/model/api/src/main/java/org/keycloak/hash/PasswordHashSpi.java
new file mode 100644
index 0000000..3f1d9af
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/hash/PasswordHashSpi.java
@@ -0,0 +1,31 @@
+package org.keycloak.hash;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
+ */
+public class PasswordHashSpi implements Spi {
+
+    @Override
+    public boolean isInternal() {
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        return "password-hash";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return PasswordHashProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return PasswordHashProviderFactory.class;
+    }
+}
                diff --git a/model/api/src/main/java/org/keycloak/hash/Pbkdf2PasswordHashProvider.java b/model/api/src/main/java/org/keycloak/hash/Pbkdf2PasswordHashProvider.java
new file mode 100644
index 0000000..2b2c9b7
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/hash/Pbkdf2PasswordHashProvider.java
@@ -0,0 +1,91 @@
+package org.keycloak.hash;
+
+import org.keycloak.Config;
+import org.keycloak.common.util.Base64;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserCredentialValueModel;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+/**
+ * @author <a href="mailto:me@tsudot.com">Kunal Kerkar</a>
+ */
+public class Pbkdf2PasswordHashProvider implements PasswordHashProviderFactory, PasswordHashProvider {
+
+    public static final String ID = "pbkdf2";
+
+    private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
+    private static final int DERIVED_KEY_SIZE = 512;
+
+    public UserCredentialValueModel encode(String rawPassword, int iterations) {
+        byte[] salt = getSalt();
+        String encodedPassword = encode(rawPassword, iterations, salt);
+
+        UserCredentialValueModel credentials = new UserCredentialValueModel();
+        credentials.setAlgorithm(ID);
+        credentials.setType(UserCredentialModel.PASSWORD);
+        credentials.setSalt(salt);
+        credentials.setHashIterations(iterations);
+        credentials.setValue(encodedPassword);
+        return credentials;
+    }
+
+    public boolean verify(String rawPassword, UserCredentialValueModel credential) {
+        return encode(rawPassword, credential.getHashIterations(), credential.getSalt()).equals(credential.getValue());
+    }
+
+    @Override
+    public PasswordHashProvider create(KeycloakSession session) {
+        return this;
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory factory) {
+    }
+
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private String encode(String rawPassword, int iterations, byte[] salt) {
+        KeySpec spec = new PBEKeySpec(rawPassword.toCharArray(), salt, iterations, DERIVED_KEY_SIZE);
+
+        try {
+            byte[] key = getSecretKeyFactory().generateSecret(spec).getEncoded();
+            return Base64.encodeBytes(key);
+        } catch (InvalidKeySpecException e) {
+            throw new RuntimeException("Credential could not be encoded");
+        }
+    }
+
+    private byte[] getSalt() {
+        byte[] buffer = new byte[16];
+        SecureRandom secureRandom = new SecureRandom();
+        secureRandom.nextBytes(buffer);
+        return buffer;
+    }
+
+    private SecretKeyFactory getSecretKeyFactory() {
+        try {
+            return SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("PBKDF2 algorithm not found");
+        }
+    }
+
+}
                diff --git a/model/api/src/main/java/org/keycloak/models/Constants.java b/model/api/src/main/java/org/keycloak/models/Constants.java
index 0c52929..159d943 100755
--- a/model/api/src/main/java/org/keycloak/models/Constants.java
+++ b/model/api/src/main/java/org/keycloak/models/Constants.java
@@ -21,6 +21,8 @@ public interface Constants {
     String[] BROKER_SERVICE_ROLES = {READ_TOKEN_ROLE};
     String OFFLINE_ACCESS_ROLE = OAuth2Constants.OFFLINE_ACCESS;
 
+    String DEFAULT_HASH_ALGORITHM = "pbkdf2";
+
     // 15 minutes
     int DEFAULT_ACCESS_TOKEN_LIFESPAN_FOR_IMPLICIT_FLOW_TIMEOUT = 900;
     // 30 days
                diff --git a/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java b/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java
index 3674334..b7ed682 100755
--- a/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java
+++ b/model/api/src/main/java/org/keycloak/models/PasswordPolicy.java
@@ -1,6 +1,7 @@
 package org.keycloak.models;
 
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
+import org.keycloak.hash.PasswordHashManager;
+import org.keycloak.hash.PasswordHashProvider;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -67,6 +68,8 @@ public class PasswordPolicy implements Serializable {
                 list.add(new SpecialChars(arg));
             } else if (name.equals(NotUsername.NAME)) {
                 list.add(new NotUsername(arg));
+            } else if (name.equals(HashAlgorithm.NAME)) {
+                list.add(new HashAlgorithm(arg));
             } else if (name.equals(HashIterations.NAME)) {
                 list.add(new HashIterations(arg));
             } else if (name.equals(RegexPatterns.NAME)) {
@@ -83,6 +86,18 @@ public class PasswordPolicy implements Serializable {
         return list;
     }
 
+    public String getHashAlgorithm() {
+        if (policies == null)
+            return Constants.DEFAULT_HASH_ALGORITHM;
+        for (Policy p : policies) {
+            if (p instanceof HashAlgorithm) {
+                return ((HashAlgorithm) p).algorithm;
+            }
+
+        }
+        return Constants.DEFAULT_HASH_ALGORITHM;
+    }
+
     /**
      *
      * @return -1 if no hash iterations setting
@@ -131,9 +146,9 @@ public class PasswordPolicy implements Serializable {
        return -1;
    }
 
-    public Error validate(UserModel user, String password) {
+    public Error validate(KeycloakSession session, UserModel user, String password) {
         for (Policy p : policies) {
-            Error error = p.validate(user, password);
+            Error error = p.validate(session, user, password);
             if (error != null) {
                 return error;
             }
@@ -141,9 +156,9 @@ public class PasswordPolicy implements Serializable {
         return null;
     }
     
-    public Error validate(String user, String password) {
+    public Error validate(KeycloakSession session, String user, String password) {
         for (Policy p : policies) {
-            Error error = p.validate(user, password);
+            Error error = p.validate(session, user, password);
             if (error != null) {
                 return error;
             }
@@ -152,8 +167,8 @@ public class PasswordPolicy implements Serializable {
     }
 
     private static interface Policy extends Serializable {
-        public Error validate(UserModel user, String password);
-        public Error validate(String user, String password);
+        public Error validate(KeycloakSession session, UserModel user, String password);
+        public Error validate(KeycloakSession session, String user, String password);
     }
 
     public static class Error {
@@ -174,6 +189,25 @@ public class PasswordPolicy implements Serializable {
         }
     }
 
+    private static class HashAlgorithm implements Policy {
+        private static final String NAME = "hashAlgorithm";
+        private String algorithm;
+
+        public HashAlgorithm(String arg) {
+            algorithm = stringArg(NAME, Constants.DEFAULT_HASH_ALGORITHM, arg);
+        }
+        
+        @Override
+        public Error validate(KeycloakSession session, String user, String password) {
+            return null;
+        }
+        
+        @Override
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return null;
+        }
+    }
+
     private static class HashIterations implements Policy {
         private static final String NAME = "hashIterations";
         private int iterations;
@@ -181,14 +215,14 @@ public class PasswordPolicy implements Serializable {
         public HashIterations(String arg) {
             iterations = intArg(NAME, 1, arg);
         }
-        
+
         @Override
-        public Error validate(String user, String password) {
+        public Error validate(KeycloakSession session, String user, String password) {
             return null;
         }
-        
+
         @Override
-        public Error validate(UserModel user, String password) {
+        public Error validate(KeycloakSession session, UserModel user, String password) {
             return null;
         }
     }
@@ -200,13 +234,13 @@ public class PasswordPolicy implements Serializable {
         }
 
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             return username.equals(password) ? new Error(INVALID_PASSWORD_NOT_USERNAME) : null;
         }
         
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -221,13 +255,13 @@ public class PasswordPolicy implements Serializable {
         
 
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             return password.length() < min ? new Error(INVALID_PASSWORD_MIN_LENGTH_MESSAGE, min) : null;
         }
         
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -242,7 +276,7 @@ public class PasswordPolicy implements Serializable {
         
 
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             int count = 0;
             for (char c : password.toCharArray()) {
                 if (Character.isDigit(c)) {
@@ -253,8 +287,8 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -268,7 +302,7 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             int count = 0;
             for (char c : password.toCharArray()) {
                 if (Character.isLowerCase(c)) {
@@ -279,8 +313,8 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -293,7 +327,7 @@ public class PasswordPolicy implements Serializable {
         }
 
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             int count = 0;
             for (char c : password.toCharArray()) {
                 if (Character.isUpperCase(c)) {
@@ -304,8 +338,8 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -319,7 +353,7 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             int count = 0;
             for (char c : password.toCharArray()) {
                 if (!Character.isLetterOrDigit(c)) {
@@ -330,8 +364,8 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -345,7 +379,7 @@ public class PasswordPolicy implements Serializable {
         }
 
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             Pattern pattern = Pattern.compile(regexPattern);
             Matcher matcher = pattern.matcher(password);
             if (!matcher.matches()) {
@@ -355,8 +389,8 @@ public class PasswordPolicy implements Serializable {
         }
 
         @Override
-        public Error validate(UserModel user, String password) {
-            return validate(user.getUsername(), password);
+        public Error validate(KeycloakSession session, UserModel user, String password) {
+            return validate(session, user.getUsername(), password);
         }
     }
 
@@ -370,18 +404,19 @@ public class PasswordPolicy implements Serializable {
         }
         
         @Override
-        public Error validate(String user, String password) {
+        public Error validate(KeycloakSession session, String user, String password) {
             return null;
         }
 
         @Override
-        public Error validate(UserModel user, String password) {
+        public Error validate(KeycloakSession session, UserModel user, String password) {
             
             if (passwordHistoryPolicyValue != -1) {
             
                 UserCredentialValueModel cred = getCredentialValueModel(user, UserCredentialModel.PASSWORD);
                 if (cred != null) {
-                    if(new Pbkdf2PasswordEncoder(cred.getSalt()).verify(password, cred.getValue(), cred.getHashIterations())) {
+                    PasswordHashProvider hashProvider = session.getProvider(PasswordHashProvider.class, cred.getAlgorithm());
+                    if(hashProvider.verify(password, cred)) {
                         return new Error(INVALID_PASSWORD_HISTORY, passwordHistoryPolicyValue);
                     }
                 }
@@ -389,7 +424,8 @@ public class PasswordPolicy implements Serializable {
                 List<UserCredentialValueModel> passwordExpiredCredentials = getCredentialValueModels(user, passwordHistoryPolicyValue - 1,
                         UserCredentialModel.PASSWORD_HISTORY);
                 for (UserCredentialValueModel credential : passwordExpiredCredentials) {
-                    if (new Pbkdf2PasswordEncoder(credential.getSalt()).verify(password, credential.getValue(), credential.getHashIterations())) {
+                    PasswordHashProvider hashProvider = session.getProvider(PasswordHashProvider.class, cred.getAlgorithm());
+                    if (hashProvider.verify(password, credential)) {
                         return new Error(INVALID_PASSWORD_HISTORY, passwordHistoryPolicyValue);
                     }
                 }
@@ -444,12 +480,12 @@ public class PasswordPolicy implements Serializable {
         }
 
         @Override
-        public Error validate(String username, String password) {
+        public Error validate(KeycloakSession session, String username, String password) {
             return null;
         }
 
         @Override
-        public Error validate(UserModel user, String password) {
+        public Error validate(KeycloakSession session, UserModel user, String password) {
             return null;
         }
     }
@@ -462,6 +498,14 @@ public class PasswordPolicy implements Serializable {
         }
     }
 
+    private static String stringArg(String policy, String defaultValue, String arg) {
+        if (arg == null) {
+            return defaultValue;
+        } else {
+            return arg;
+        }
+    }
+
     @Override
     public String toString() {
         return policyString;
                diff --git a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
index 7e2bfb4..1929c9f 100755
--- a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
@@ -21,6 +21,7 @@ public class UserCredentialModel {
     protected String type;
     protected String value;
     protected String device;
+    protected String algorithm;
 
     public UserCredentialModel() {
     }
@@ -107,4 +108,12 @@ public class UserCredentialModel {
     public void setDevice(String device) {
         this.device = device;
     }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public void setAlgorithm(String algorithm) {
+        this.algorithm = algorithm;
+    }
 }
                diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
index 1a1709b..58344cc 100755
--- a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
+++ b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
@@ -395,7 +395,7 @@ public class UserFederationManager implements UserProvider {
     public void updateCredential(RealmModel realm, UserModel user, UserCredentialModel credential) {
         if (credential.getType().equals(UserCredentialModel.PASSWORD)) {
             if (realm.getPasswordPolicy() != null) {
-                PasswordPolicy.Error error = realm.getPasswordPolicy().validate(user, credential.getValue());
+                PasswordPolicy.Error error = realm.getPasswordPolicy().validate(session, user, credential.getValue());
                 if (error != null) throw new ModelException(error.getMessage(), error.getParameters());
             }
         }
@@ -403,7 +403,7 @@ public class UserFederationManager implements UserProvider {
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> input) {
         UserFederationProvider link = getFederationLink(realm, user);
         if (link != null) {
             validateUser(realm, user);
@@ -421,10 +421,10 @@ public class UserFederationManager implements UserProvider {
                 if (!link.validCredentials(realm, user, fedCreds)) {
                     return false;
                 }
-                return session.userStorage().validCredentials(realm, user, localCreds);
+                return session.userStorage().validCredentials(session, realm, user, localCreds);
             }
         }
-        return session.userStorage().validCredentials(realm, user, input);
+        return session.userStorage().validCredentials(session, realm, user, input);
     }
 
     /**
@@ -466,12 +466,12 @@ public class UserFederationManager implements UserProvider {
 
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
-        return validCredentials(realm, user, Arrays.asList(input));
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return validCredentials(session, realm, user, Arrays.asList(input));
     }
 
     @Override
-    public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel... input) {
+    public CredentialValidationOutput validCredentials(KeycloakSession session, RealmModel realm, UserCredentialModel... input) {
         List<UserFederationProviderModel> fedProviderModels = realm.getUserFederationProviders();
         List<UserFederationProvider> fedProviders = new ArrayList<UserFederationProvider>();
         for (UserFederationProviderModel fedProviderModel : fedProviderModels) {
                diff --git a/model/api/src/main/java/org/keycloak/models/UserProvider.java b/model/api/src/main/java/org/keycloak/models/UserProvider.java
index 962bc77..1c2b5c7 100755
--- a/model/api/src/main/java/org/keycloak/models/UserProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserProvider.java
@@ -59,9 +59,9 @@ public interface UserProvider extends Provider {
     void preRemove(RealmModel realm, ClientModel client);
     void preRemove(ClientModel realm, ProtocolMapperModel protocolMapper);
 
-    boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input);
-    boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input);
-    CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel... input);
+    boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> input);
+    boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel... input);
+    CredentialValidationOutput validCredentials(KeycloakSession session, RealmModel realm, UserCredentialModel... input);
 
     void close();
 }
                diff --git a/model/api/src/main/java/org/keycloak/models/utils/CredentialValidation.java b/model/api/src/main/java/org/keycloak/models/utils/CredentialValidation.java
index d3e4d4a..6afc9ed 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/CredentialValidation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/CredentialValidation.java
@@ -1,8 +1,11 @@
 package org.keycloak.models.utils;
 
+import org.keycloak.hash.PasswordHashManager;
 import org.keycloak.jose.jws.JWSInput;
 import org.keycloak.jose.jws.JWSInputException;
 import org.keycloak.jose.jws.crypto.RSAProvider;
+import org.keycloak.models.Constants;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OTPPolicy;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
@@ -11,8 +14,8 @@ import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.PasswordToken;
 import org.keycloak.common.util.Time;
+import org.keycloak.hash.PasswordHashProvider;
 
-import java.io.IOException;
 import java.util.List;
 
 /**
@@ -38,7 +41,7 @@ public class CredentialValidation {
      * @param password
      * @return
      */
-    public static boolean validPassword(RealmModel realm, UserModel user, String password) {
+    public static boolean validPassword(KeycloakSession session, RealmModel realm, UserModel user, String password) {
         UserCredentialValueModel passwordCred = null;
         for (UserCredentialValueModel cred : user.getCredentialsDirectly()) {
             if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
@@ -47,25 +50,23 @@ public class CredentialValidation {
         }
         if (passwordCred == null) return false;
 
-        return validateHashedCredential(realm, user, password, passwordCred);
+        return validateHashedCredential(session, realm, user, password, passwordCred);
 
     }
 
-    public static boolean validateHashedCredential(RealmModel realm, UserModel user, String unhashedCredValue, UserCredentialValueModel credential) {
+
+    public static boolean validateHashedCredential(KeycloakSession session, RealmModel realm, UserModel user, String unhashedCredValue, UserCredentialValueModel credential) {
         if(unhashedCredValue == null){
             return false;
         }
 
-        boolean validated = new Pbkdf2PasswordEncoder(credential.getSalt()).verify(unhashedCredValue, credential.getValue(), credential.getHashIterations());
+        boolean validated = PasswordHashManager.verify(session, realm, unhashedCredValue, credential);
+
         if (validated) {
             int iterations = hashIterations(realm);
             if (iterations > -1 && iterations != credential.getHashIterations()) {
-                UserCredentialValueModel newCred = new UserCredentialValueModel();
-                newCred.setType(credential.getType());
-                newCred.setDevice(credential.getDevice());
-                newCred.setSalt(credential.getSalt());
-                newCred.setHashIterations(iterations);
-                newCred.setValue(new Pbkdf2PasswordEncoder(newCred.getSalt()).encode(unhashedCredValue, iterations));
+
+                UserCredentialValueModel newCred = PasswordHashManager.encode(session, realm, unhashedCredValue);
                 user.updateCredentialDirectly(newCred);
             }
 
@@ -157,9 +158,9 @@ public class CredentialValidation {
      * @param credentials
      * @return
      */
-    public static boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> credentials) {
+    public static boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> credentials) {
         for (UserCredentialModel credential : credentials) {
-            if (!validCredential(realm, user, credential)) return false;
+            if (!validCredential(session, realm, user, credential)) return false;
         }
         return true;
     }
@@ -172,16 +173,16 @@ public class CredentialValidation {
      * @param credentials
      * @return
      */
-    public static boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... credentials) {
+    public static boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel... credentials) {
         for (UserCredentialModel credential : credentials) {
-            if (!validCredential(realm, user, credential)) return false;
+            if (!validCredential(session, realm, user, credential)) return false;
         }
         return true;
     }
 
-    private static boolean validCredential(RealmModel realm, UserModel user, UserCredentialModel credential) {
+    private static boolean validCredential(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel credential) {
         if (credential.getType().equals(UserCredentialModel.PASSWORD)) {
-            if (!validPassword(realm, user, credential.getValue())) {
+            if (!validPassword(session, realm, user, credential.getValue())) {
                 return false;
             }
         } else if (credential.getType().equals(UserCredentialModel.PASSWORD_TOKEN)) {
                diff --git a/model/api/src/main/resources/META-INF/services/org.keycloak.hash.PasswordHashProviderFactory b/model/api/src/main/resources/META-INF/services/org.keycloak.hash.PasswordHashProviderFactory
new file mode 100644
index 0000000..f29ba9c
--- /dev/null
+++ b/model/api/src/main/resources/META-INF/services/org.keycloak.hash.PasswordHashProviderFactory
@@ -0,0 +1 @@
+org.keycloak.hash.Pbkdf2PasswordHashProvider
\ No newline at end of file
                diff --git a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index be3982b..fd8c0fd 100755
--- a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -4,4 +4,5 @@ org.keycloak.models.RealmSpi
 org.keycloak.models.UserSessionSpi
 org.keycloak.models.UserSpi
 org.keycloak.models.session.UserSessionPersisterSpi
-org.keycloak.migration.MigrationSpi
\ No newline at end of file
+org.keycloak.migration.MigrationSpi
+org.keycloak.hash.PasswordHashSpi
                diff --git a/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java b/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java
index 8c662fb..f910ea1 100755
--- a/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java
+++ b/model/api/src/test/java/org/keycloak/models/PasswordPolicyTest.java
@@ -15,73 +15,73 @@ public class PasswordPolicyTest {
     @Test
     public void testLength() {
         PasswordPolicy policy = new PasswordPolicy("length");
-        Assert.assertEquals("invalidPasswordMinLengthMessage", policy.validate("jdoe", "1234567").getMessage());
-        Assert.assertArrayEquals(new Object[]{8}, policy.validate("jdoe", "1234567").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "12345678"));
+        Assert.assertEquals("invalidPasswordMinLengthMessage", policy.validate(null, "jdoe", "1234567").getMessage());
+        Assert.assertArrayEquals(new Object[]{8}, policy.validate(null, "jdoe", "1234567").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "12345678"));
 
         policy = new PasswordPolicy("length(4)");
-        Assert.assertEquals("invalidPasswordMinLengthMessage", policy.validate("jdoe", "123").getMessage());
-        Assert.assertArrayEquals(new Object[]{4}, policy.validate("jdoe", "123").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "1234"));
+        Assert.assertEquals("invalidPasswordMinLengthMessage", policy.validate(null, "jdoe", "123").getMessage());
+        Assert.assertArrayEquals(new Object[]{4}, policy.validate(null, "jdoe", "123").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "1234"));
     }
 
     @Test
     public void testDigits() {
         PasswordPolicy policy = new PasswordPolicy("digits");
-        Assert.assertEquals("invalidPasswordMinDigitsMessage", policy.validate("jdoe", "abcd").getMessage());
-        Assert.assertArrayEquals(new Object[]{1}, policy.validate("jdoe", "abcd").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "abcd1"));
+        Assert.assertEquals("invalidPasswordMinDigitsMessage", policy.validate(null, "jdoe", "abcd").getMessage());
+        Assert.assertArrayEquals(new Object[]{1}, policy.validate(null, "jdoe", "abcd").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "abcd1"));
 
         policy = new PasswordPolicy("digits(2)");
-        Assert.assertEquals("invalidPasswordMinDigitsMessage", policy.validate("jdoe", "abcd1").getMessage());
-        Assert.assertArrayEquals(new Object[]{2}, policy.validate("jdoe", "abcd1").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "abcd12"));
+        Assert.assertEquals("invalidPasswordMinDigitsMessage", policy.validate(null, "jdoe", "abcd1").getMessage());
+        Assert.assertArrayEquals(new Object[]{2}, policy.validate(null, "jdoe", "abcd1").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "abcd12"));
     }
 
     @Test
     public void testLowerCase() {
         PasswordPolicy policy = new PasswordPolicy("lowerCase");
-        Assert.assertEquals("invalidPasswordMinLowerCaseCharsMessage", policy.validate("jdoe", "ABCD1234").getMessage());
-        Assert.assertArrayEquals(new Object[]{1}, policy.validate("jdoe", "ABCD1234").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "ABcD1234"));
+        Assert.assertEquals("invalidPasswordMinLowerCaseCharsMessage", policy.validate(null, "jdoe", "ABCD1234").getMessage());
+        Assert.assertArrayEquals(new Object[]{1}, policy.validate(null, "jdoe", "ABCD1234").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "ABcD1234"));
 
         policy = new PasswordPolicy("lowerCase(2)");
-        Assert.assertEquals("invalidPasswordMinLowerCaseCharsMessage", policy.validate("jdoe", "ABcD1234").getMessage());
-        Assert.assertArrayEquals(new Object[]{2}, policy.validate("jdoe", "ABcD1234").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "aBcD1234"));
+        Assert.assertEquals("invalidPasswordMinLowerCaseCharsMessage", policy.validate(null, "jdoe", "ABcD1234").getMessage());
+        Assert.assertArrayEquals(new Object[]{2}, policy.validate(null, "jdoe", "ABcD1234").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "aBcD1234"));
     }
 
     @Test
     public void testUpperCase() {
         PasswordPolicy policy = new PasswordPolicy("upperCase");
-        Assert.assertEquals("invalidPasswordMinUpperCaseCharsMessage", policy.validate("jdoe", "abcd1234").getMessage());
-        Assert.assertArrayEquals(new Object[]{1}, policy.validate("jdoe", "abcd1234").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "abCd1234"));
+        Assert.assertEquals("invalidPasswordMinUpperCaseCharsMessage", policy.validate(null, "jdoe", "abcd1234").getMessage());
+        Assert.assertArrayEquals(new Object[]{1}, policy.validate(null, "jdoe", "abcd1234").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "abCd1234"));
 
         policy = new PasswordPolicy("upperCase(2)");
-        Assert.assertEquals("invalidPasswordMinUpperCaseCharsMessage", policy.validate("jdoe", "abCd1234").getMessage());
-        Assert.assertArrayEquals(new Object[]{2}, policy.validate("jdoe", "abCd1234").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "AbCd1234"));
+        Assert.assertEquals("invalidPasswordMinUpperCaseCharsMessage", policy.validate(null, "jdoe", "abCd1234").getMessage());
+        Assert.assertArrayEquals(new Object[]{2}, policy.validate(null, "jdoe", "abCd1234").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "AbCd1234"));
     }
 
     @Test
     public void testSpecialChars() {
         PasswordPolicy policy = new PasswordPolicy("specialChars");
-        Assert.assertEquals("invalidPasswordMinSpecialCharsMessage", policy.validate("jdoe", "abcd1234").getMessage());
-        Assert.assertArrayEquals(new Object[]{1}, policy.validate("jdoe", "abcd1234").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "ab&d1234"));
+        Assert.assertEquals("invalidPasswordMinSpecialCharsMessage", policy.validate(null, "jdoe", "abcd1234").getMessage());
+        Assert.assertArrayEquals(new Object[]{1}, policy.validate(null, "jdoe", "abcd1234").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "ab&d1234"));
 
         policy = new PasswordPolicy("specialChars(2)");
-        Assert.assertEquals("invalidPasswordMinSpecialCharsMessage", policy.validate("jdoe", "ab&d1234").getMessage());
-        Assert.assertArrayEquals(new Object[]{2}, policy.validate("jdoe", "ab&d1234").getParameters());
-        Assert.assertNull(policy.validate("jdoe", "ab&d-234"));
+        Assert.assertEquals("invalidPasswordMinSpecialCharsMessage", policy.validate(null, "jdoe", "ab&d1234").getMessage());
+        Assert.assertArrayEquals(new Object[]{2}, policy.validate(null, "jdoe", "ab&d1234").getParameters());
+        Assert.assertNull(policy.validate(null, "jdoe", "ab&d-234"));
     }
 
     @Test
     public void testNotUsername() {
         PasswordPolicy policy = new PasswordPolicy("notUsername");
-        Assert.assertEquals("invalidPasswordNotUsernameMessage", policy.validate("jdoe", "jdoe").getMessage());
-        Assert.assertNull(policy.validate("jdoe", "ab&d1234"));
+        Assert.assertEquals("invalidPasswordNotUsernameMessage", policy.validate(null, "jdoe", "jdoe").getMessage());
+        Assert.assertNull(policy.validate(null, "jdoe", "ab&d1234"));
     }
 
     @Test
@@ -119,33 +119,33 @@ public class PasswordPolicyTest {
         
         //Fails to match one of the regex pattern
         policy = new PasswordPolicy("regexPattern(jdoe) and regexPattern(j*d)");
-        Assert.assertEquals("invalidPasswordRegexPatternMessage", policy.validate("jdoe", "jdoe").getMessage());
+        Assert.assertEquals("invalidPasswordRegexPatternMessage", policy.validate(null, "jdoe", "jdoe").getMessage());
         
         ////Fails to match all of the regex patterns
         policy = new PasswordPolicy("regexPattern(j*p) and regexPattern(j*d) and regexPattern(adoe)");
-        Assert.assertEquals("invalidPasswordRegexPatternMessage", policy.validate("jdoe", "jdoe").getMessage());
+        Assert.assertEquals("invalidPasswordRegexPatternMessage", policy.validate(null, "jdoe", "jdoe").getMessage());
         
         policy = new PasswordPolicy("regexPattern([a-z][a-z][a-z][a-z][0-9])");
-        Assert.assertEquals("invalidPasswordRegexPatternMessage", policy.validate("jdoe", "jdoe").getMessage());
+        Assert.assertEquals("invalidPasswordRegexPatternMessage", policy.validate(null, "jdoe", "jdoe").getMessage());
         
         policy = new PasswordPolicy("regexPattern(jdoe)");
-        Assert.assertNull(policy.validate("jdoe", "jdoe"));
+        Assert.assertNull(policy.validate(null, "jdoe", "jdoe"));
         
         policy = new PasswordPolicy("regexPattern([a-z][a-z][a-z][a-z][0-9])");
-        Assert.assertNull(policy.validate("jdoe", "jdoe0"));
+        Assert.assertNull(policy.validate(null, "jdoe", "jdoe0"));
     }
 
     @Test
     public void testComplex() {
         PasswordPolicy policy = new PasswordPolicy("length(8) and digits(2) and lowerCase(2) and upperCase(2) and specialChars(2) and notUsername()");
-        Assert.assertNotNull(policy.validate("jdoe", "12aaBB&"));
-        Assert.assertNotNull(policy.validate("jdoe", "aaaaBB&-"));
-        Assert.assertNotNull(policy.validate("jdoe", "12AABB&-"));
-        Assert.assertNotNull(policy.validate("jdoe", "12aabb&-"));
-        Assert.assertNotNull(policy.validate("jdoe", "12aaBBcc"));
-        Assert.assertNotNull(policy.validate("12aaBB&-", "12aaBB&-"));
-
-        Assert.assertNull(policy.validate("jdoe", "12aaBB&-"));
+        Assert.assertNotNull(policy.validate(null, "jdoe", "12aaBB&"));
+        Assert.assertNotNull(policy.validate(null, "jdoe", "aaaaBB&-"));
+        Assert.assertNotNull(policy.validate(null, "jdoe", "12AABB&-"));
+        Assert.assertNotNull(policy.validate(null, "jdoe", "12aabb&-"));
+        Assert.assertNotNull(policy.validate(null, "jdoe", "12aaBBcc"));
+        Assert.assertNotNull(policy.validate(null, "12aaBB&-", "12aaBB&-"));
+
+        Assert.assertNull(policy.validate(null, "jdoe", "12aaBB&-"));
     }
 
 }
                diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java
index 44260a1..c7f5bf2 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java
@@ -299,18 +299,18 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
-        return getDelegate().validCredentials(realm, user, input);
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return getDelegate().validCredentials(session, realm, user, input);
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
-        return getDelegate().validCredentials(realm, user, input);
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return getDelegate().validCredentials(session, realm, user, input);
     }
 
     @Override
-    public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel... input) {
-        return getDelegate().validCredentials(realm, input);
+    public CredentialValidationOutput validCredentials(KeycloakSession session, RealmModel realm, UserCredentialModel... input) {
+        return getDelegate().validCredentials(session, realm, input);
     }
 
     @Override
                diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
index 8ef4dd2..9f6fdba 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
@@ -4,6 +4,7 @@ import org.keycloak.common.util.MultivaluedHashMap;
 import org.keycloak.common.util.Time;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.GroupModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.ModelException;
 import org.keycloak.models.OTPPolicy;
@@ -29,7 +30,6 @@ import org.keycloak.models.jpa.entities.UserEntity;
 import org.keycloak.models.jpa.entities.UserRequiredActionEntity;
 import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
@@ -43,8 +43,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static org.keycloak.models.utils.Pbkdf2PasswordEncoder.getSalt;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
                diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
index 64650c9..b536a9c 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
@@ -59,7 +59,7 @@ public class JpaUserProvider implements UserProvider {
         entity.setRealmId(realm.getId());
         em.persist(entity);
         em.flush();
-        UserModel userModel = new UserAdapter(realm, em, entity);
+        UserModel userModel = new UserAdapter(session, realm, em, entity);
 
         if (addDefaultRoles) {
             for (String r : realm.getDefaultRoles()) {
@@ -241,7 +241,7 @@ public class JpaUserProvider implements UserProvider {
 
         List<UserModel> users = new ArrayList<UserModel>();
         for (UserEntity user : results) {
-            users.add(new UserAdapter(realm, em, user));
+            users.add(new UserAdapter(session, realm, em, user));
         }
         return users;
     }
@@ -259,7 +259,7 @@ public class JpaUserProvider implements UserProvider {
         query.setParameter("realmId", realm.getId());
         List<UserEntity> entities = query.getResultList();
         if (entities.size() == 0) return null;
-        return new UserAdapter(realm, em, entities.get(0));
+        return new UserAdapter(session, realm, em, entities.get(0));
     }
 
     @Override
@@ -269,7 +269,7 @@ public class JpaUserProvider implements UserProvider {
         query.setParameter("realmId", realm.getId());
         List<UserEntity> results = query.getResultList();
         if (results.size() == 0) return null;
-        return new UserAdapter(realm, em, results.get(0));
+        return new UserAdapter(session, realm, em, results.get(0));
     }
 
     @Override
@@ -278,7 +278,7 @@ public class JpaUserProvider implements UserProvider {
         query.setParameter("email", email.toLowerCase());
         query.setParameter("realmId", realm.getId());
         List<UserEntity> results = query.getResultList();
-        return results.isEmpty() ? null : new UserAdapter(realm, em, results.get(0));
+        return results.isEmpty() ? null : new UserAdapter(session, realm, em, results.get(0));
     }
 
      @Override
@@ -299,7 +299,7 @@ public class JpaUserProvider implements UserProvider {
                     ", userId=" + identity.getUserId() + ", results=" + results);
         } else {
             UserEntity user = results.get(0);
-            return new UserAdapter(realm, em, user);
+            return new UserAdapter(session, realm, em, user);
         }
     }
 
@@ -316,7 +316,7 @@ public class JpaUserProvider implements UserProvider {
                     ", results=" + results);
         } else {
             UserEntity user = results.get(0);
-            return new UserAdapter(client.getRealm(), em, user);
+            return new UserAdapter(session, client.getRealm(), em, user);
         }
     }
 
@@ -347,7 +347,7 @@ public class JpaUserProvider implements UserProvider {
         }
         List<UserEntity> results = query.getResultList();
         List<UserModel> users = new ArrayList<UserModel>();
-        for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
+        for (UserEntity entity : results) users.add(new UserAdapter(session, realm, em, entity));
         return users;
     }
 
@@ -365,7 +365,7 @@ public class JpaUserProvider implements UserProvider {
 
         List<UserModel> users = new ArrayList<UserModel>();
         for (UserEntity user : results) {
-            users.add(new UserAdapter(realm, em, user));
+            users.add(new UserAdapter(session, realm, em, user));
         }
         return users;
     }
@@ -388,7 +388,7 @@ public class JpaUserProvider implements UserProvider {
         }
         List<UserEntity> results = query.getResultList();
         List<UserModel> users = new ArrayList<UserModel>();
-        for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
+        for (UserEntity entity : results) users.add(new UserAdapter(session, realm, em, entity));
         return users;
     }
 
@@ -446,7 +446,7 @@ public class JpaUserProvider implements UserProvider {
         }
         List<UserEntity> results = query.getResultList();
         List<UserModel> users = new ArrayList<UserModel>();
-        for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
+        for (UserEntity entity : results) users.add(new UserAdapter(session, realm, em, entity));
         return users;
     }
 
@@ -460,7 +460,7 @@ public class JpaUserProvider implements UserProvider {
         List<UserModel> users = new ArrayList<UserModel>();
         for (UserAttributeEntity attr : results) {
             UserEntity user = attr.getUser();
-            users.add(new UserAdapter(realm, em, user));
+            users.add(new UserAdapter(session, realm, em, user));
         }
         return users;
     }
@@ -495,17 +495,17 @@ public class JpaUserProvider implements UserProvider {
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
-        return CredentialValidation.validCredentials(realm, user, input);
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return CredentialValidation.validCredentials(session, realm, user, input);
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
-        return CredentialValidation.validCredentials(realm, user, input);
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return CredentialValidation.validCredentials(session, realm, user, input);
     }
 
     @Override
-    public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel... input) {
+    public CredentialValidationOutput validCredentials(KeycloakSession session, RealmModel realm, UserCredentialModel... input) {
         // Not supported yet
         return null;
     }
                diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 5246890..ded42a7 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -1,7 +1,9 @@
 package org.keycloak.models.jpa;
 
+import org.keycloak.hash.PasswordHashManager;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.GroupModel;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OTPPolicy;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.UserConsentModel;
@@ -24,9 +26,9 @@ import org.keycloak.models.jpa.entities.UserGroupMembershipEntity;
 import org.keycloak.models.jpa.entities.UserRequiredActionEntity;
 import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
 import org.keycloak.common.util.MultivaluedHashMap;
 import org.keycloak.common.util.Time;
+import org.keycloak.hash.PasswordHashProvider;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
@@ -41,8 +43,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static org.keycloak.models.utils.Pbkdf2PasswordEncoder.getSalt;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -52,11 +52,13 @@ public class UserAdapter implements UserModel {
     protected UserEntity user;
     protected EntityManager em;
     protected RealmModel realm;
+    private final KeycloakSession session;
 
-    public UserAdapter(RealmModel realm, EntityManager em, UserEntity user) {
+    public UserAdapter(KeycloakSession session, RealmModel realm, EntityManager em, UserEntity user) {
         this.em = em;
         this.user = user;
         this.realm = realm;
+        this.session = session;
     }
 
     public UserEntity getUser() {
@@ -387,18 +389,12 @@ public class UserAdapter implements UserModel {
     }
 
     private void setValue(CredentialEntity credentialEntity, UserCredentialModel cred) {
-        byte[] salt = getSalt();
-        int hashIterations = 1;
-        PasswordPolicy policy = realm.getPasswordPolicy();
-        if (policy != null) {
-            hashIterations = policy.getHashIterations();
-            if (hashIterations == -1)
-                hashIterations = 1;
-        }
+        UserCredentialValueModel encoded = PasswordHashManager.encode(session, realm, cred.getValue());
         credentialEntity.setCreatedDate(Time.toMillis(Time.currentTime()));
-        credentialEntity.setValue(new Pbkdf2PasswordEncoder(salt).encode(cred.getValue(), hashIterations));
-        credentialEntity.setSalt(salt);
-        credentialEntity.setHashIterations(hashIterations);
+        credentialEntity.setAlgorithm(encoded.getAlgorithm());
+        credentialEntity.setValue(encoded.getValue());
+        credentialEntity.setSalt(encoded.getSalt());
+        credentialEntity.setHashIterations(encoded.getHashIterations());
     }
 
     private CredentialEntity getCredentialEntity(UserEntity userEntity, String credType) {
                diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
index 44758b7..3b5a1ac 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
@@ -474,17 +474,17 @@ public class MongoUserProvider implements UserProvider {
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, List<UserCredentialModel> input) {
-        return CredentialValidation.validCredentials(realm, user, input);
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, List<UserCredentialModel> input) {
+        return CredentialValidation.validCredentials(session, realm, user, input);
     }
 
     @Override
-    public boolean validCredentials(RealmModel realm, UserModel user, UserCredentialModel... input) {
-        return CredentialValidation.validCredentials(realm, user, input);
+    public boolean validCredentials(KeycloakSession session, RealmModel realm, UserModel user, UserCredentialModel... input) {
+        return CredentialValidation.validCredentials(session, realm, user, input);
     }
 
     @Override
-    public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel... input) {
+    public CredentialValidationOutput validCredentials(KeycloakSession session, RealmModel realm, UserCredentialModel... input) {
         // Not supported yet
         return null;
     }
                diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
index 83979c3..5e822b0 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
@@ -1,11 +1,10 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import static org.keycloak.models.utils.Pbkdf2PasswordEncoder.getSalt;
-
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.hash.PasswordHashManager;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.GroupModel;
 import org.keycloak.models.OTPPolicy;
@@ -26,8 +25,8 @@ import org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
 import org.keycloak.models.mongo.utils.MongoModelUtils;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
 import org.keycloak.common.util.Time;
+import org.keycloak.hash.PasswordHashProvider;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -329,18 +328,12 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
     }
 
     private void setValue(CredentialEntity credentialEntity, UserCredentialModel cred) {
-        byte[] salt = getSalt();
-        int hashIterations = 1;
-        PasswordPolicy policy = realm.getPasswordPolicy();
-        if (policy != null) {
-            hashIterations = policy.getHashIterations();
-            if (hashIterations == -1)
-                hashIterations = 1;
-        }
+        UserCredentialValueModel encoded = PasswordHashManager.encode(session, realm, cred.getValue());
         credentialEntity.setCreatedDate(Time.toMillis(Time.currentTime()));
-        credentialEntity.setValue(new Pbkdf2PasswordEncoder(salt).encode(cred.getValue(), hashIterations));
-        credentialEntity.setSalt(salt);
-        credentialEntity.setHashIterations(hashIterations);
+        credentialEntity.setAlgorithm(encoded.getAlgorithm());
+        credentialEntity.setValue(encoded.getValue());
+        credentialEntity.setSalt(encoded.getSalt());
+        credentialEntity.setHashIterations(encoded.getHashIterations());
     }
 
     private CredentialEntity getCredentialEntity(MongoUserEntity userEntity, String credType) {
                diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java
index 5afaa3d..68b036f 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java
@@ -149,7 +149,7 @@ public abstract class AbstractUsernameFormAuthenticator extends AbstractFormAuth
         List<UserCredentialModel> credentials = new LinkedList<>();
         String password = inputData.getFirst(CredentialRepresentation.PASSWORD);
         credentials.add(UserCredentialModel.password(password));
-        boolean valid = context.getSession().users().validCredentials(context.getRealm(), user, credentials);
+        boolean valid = context.getSession().users().validCredentials(context.getSession(), context.getRealm(), user, credentials);
         if (!valid) {
             context.getEvent().user(user);
             context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
                diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java
index 4a0c48d..3991011 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java
@@ -49,7 +49,7 @@ public class OTPFormAuthenticator extends AbstractUsernameFormAuthenticator impl
             return;
         }
         credentials.add(UserCredentialModel.otp(context.getRealm().getOTPPolicy().getType(), password));
-        boolean valid = context.getSession().users().validCredentials(context.getRealm(), context.getUser(), credentials);
+        boolean valid = context.getSession().users().validCredentials(context.getSession(), context.getRealm(), context.getUser(), credentials);
         if (!valid) {
             context.getEvent().user(context.getUser())
                     .error(Errors.INVALID_USER_CREDENTIALS);
                diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java
index 091c14d..92d3f21 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/SpnegoAuthenticator.java
@@ -69,7 +69,7 @@ public class SpnegoAuthenticator extends AbstractUsernameFormAuthenticator imple
         String spnegoToken = tokens[1];
         UserCredentialModel spnegoCredential = UserCredentialModel.kerberos(spnegoToken);
 
-        CredentialValidationOutput output = context.getSession().users().validCredentials(context.getRealm(), spnegoCredential);
+        CredentialValidationOutput output = context.getSession().users().validCredentials(context.getSession(), context.getRealm(), spnegoCredential);
 
         if (output.getAuthStatus() == CredentialValidationOutput.Status.AUTHENTICATED) {
             context.setUser(output.getAuthenticatedUser());
                diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidateOTP.java b/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidateOTP.java
index c26da77..f555ae6 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidateOTP.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidateOTP.java
@@ -51,7 +51,7 @@ public class ValidateOTP extends AbstractDirectGrantAuthenticator {
             return;
         }
         credentials.add(UserCredentialModel.otp(context.getRealm().getOTPPolicy().getType(), otp));
-        boolean valid = context.getSession().users().validCredentials(context.getRealm(), context.getUser(), credentials);
+        boolean valid = context.getSession().users().validCredentials(context.getSession(), context.getRealm(), context.getUser(), credentials);
         if (!valid) {
             context.getEvent().user(context.getUser());
             context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
                diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidatePassword.java b/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidatePassword.java
index 21aa18d..0bb89e4 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidatePassword.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/directgrant/ValidatePassword.java
@@ -32,7 +32,7 @@ public class ValidatePassword extends AbstractDirectGrantAuthenticator {
         List<UserCredentialModel> credentials = new LinkedList<>();
         String password = inputData.getFirst(CredentialRepresentation.PASSWORD);
         credentials.add(UserCredentialModel.password(password));
-        boolean valid = context.getSession().users().validCredentials(context.getRealm(), context.getUser(), credentials);
+        boolean valid = context.getSession().users().validCredentials(context.getSession(), context.getRealm(), context.getUser(), credentials);
         if (!valid) {
             context.getEvent().user(context.getUser());
             context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
                diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java
index ff2442f..027419c 100755
--- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java
+++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationPassword.java
@@ -53,7 +53,7 @@ public class RegistrationPassword implements FormAction, FormActionFactory {
             errors.add(new FormMessage(RegistrationPage.FIELD_PASSWORD_CONFIRM, Messages.INVALID_PASSWORD_CONFIRM));
         }
         if (formData.getFirst(RegistrationPage.FIELD_PASSWORD) != null) {
-            PasswordPolicy.Error err = context.getRealm().getPasswordPolicy().validate(context.getRealm().isRegistrationEmailAsUsername() ? formData.getFirst(RegistrationPage.FIELD_EMAIL) : formData.getFirst(RegistrationPage.FIELD_USERNAME), formData.getFirst(RegistrationPage.FIELD_PASSWORD));
+            PasswordPolicy.Error err = context.getRealm().getPasswordPolicy().validate(context.getSession(), context.getRealm().isRegistrationEmailAsUsername() ? formData.getFirst(RegistrationPage.FIELD_EMAIL) : formData.getFirst(RegistrationPage.FIELD_USERNAME), formData.getFirst(RegistrationPage.FIELD_PASSWORD));
             if (err != null)
                 errors.add(new FormMessage(RegistrationPage.FIELD_PASSWORD, err.getMessage(), err.getParameters()));
         }
                diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateTotp.java b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateTotp.java
index 18e6682..6c74154 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateTotp.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateTotp.java
@@ -73,7 +73,7 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
         UserCredentialModel cred = new UserCredentialModel();
         cred.setType(context.getRealm().getOTPPolicy().getType());
         cred.setValue(totp);
-        context.getSession().users().validCredentials(context.getRealm(), context.getUser(), cred);
+        context.getSession().users().validCredentials(context.getSession(), context.getRealm(), context.getUser(), cred);
 
         context.getUser().setOtpEnabled(true);
         context.success();
                diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 1394832..08ad37a 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -572,7 +572,7 @@ public class AccountService extends AbstractSecuredLocalService {
         UserCredentialModel cred = new UserCredentialModel();
         cred.setType(realm.getOTPPolicy().getType());
         cred.setValue(totp);
-        session.users().validCredentials(realm, user, cred);
+        session.users().validCredentials(session, realm, user, cred);
 
         event.event(EventType.UPDATE_TOTP).client(auth.getClient()).user(auth.getUser()).success();
 
@@ -619,7 +619,7 @@ public class AccountService extends AbstractSecuredLocalService {
             }
 
             UserCredentialModel cred = UserCredentialModel.password(password);
-            if (!session.users().validCredentials(realm, user, cred)) {
+            if (!session.users().validCredentials(session, realm, user, cred)) {
                 setReferrerOnPage();
                 return account.setError(Messages.INVALID_PASSWORD_EXISTING).createResponse(AccountPages.PASSWORD);
             }
                diff --git a/services/src/main/java/org/keycloak/services/validation/Validation.java b/services/src/main/java/org/keycloak/services/validation/Validation.java
index 0a3c9bb..0c3dcc0 100755
--- a/services/src/main/java/org/keycloak/services/validation/Validation.java
+++ b/services/src/main/java/org/keycloak/services/validation/Validation.java
@@ -1,6 +1,7 @@
 package org.keycloak.services.validation;
 
 import org.keycloak.authentication.requiredactions.util.UpdateProfileContext;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.FormMessage;
@@ -25,7 +26,7 @@ public class Validation {
     // Actually allow same emails like angular. See ValidationTest.testEmailValidation()
     private static final Pattern EMAIL_PATTERN = Pattern.compile("[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*");
 
-    public static List<FormMessage> validateRegistrationForm(RealmModel realm, MultivaluedMap<String, String> formData, List<String> requiredCredentialTypes, PasswordPolicy policy) {
+    public static List<FormMessage> validateRegistrationForm(KeycloakSession session, RealmModel realm, MultivaluedMap<String, String> formData, List<String> requiredCredentialTypes, PasswordPolicy policy) {
         List<FormMessage> errors = new ArrayList<>();
 
         if (!realm.isRegistrationEmailAsUsername() && isBlank(formData.getFirst(FIELD_USERNAME))) {
@@ -55,7 +56,7 @@ public class Validation {
         }
 
         if (formData.getFirst(FIELD_PASSWORD) != null) {
-            PasswordPolicy.Error err = policy.validate(realm.isRegistrationEmailAsUsername()?formData.getFirst(FIELD_EMAIL):formData.getFirst(FIELD_USERNAME), formData.getFirst(FIELD_PASSWORD));
+            PasswordPolicy.Error err = policy.validate(session, realm.isRegistrationEmailAsUsername()?formData.getFirst(FIELD_EMAIL):formData.getFirst(FIELD_USERNAME), formData.getFirst(FIELD_PASSWORD));
             if (err != null)
                 errors.add(new FormMessage(FIELD_PASSWORD, err.getMessage(), err.getParameters()));
         }
                diff --git a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index 5119548..6189178 100755
--- a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -8,4 +8,4 @@ org.keycloak.authentication.ClientAuthenticatorSpi
 org.keycloak.authentication.RequiredActionSpi
 org.keycloak.authentication.FormAuthenticatorSpi
 org.keycloak.authentication.FormActionSpi
-org.keycloak.services.clientregistration.ClientRegistrationSpi
\ No newline at end of file
+org.keycloak.services.clientregistration.ClientRegistrationSpi
                diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java
index dea6ebc..464f376 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java
@@ -1,16 +1,17 @@
 package org.keycloak.testsuite.adduser;
 
 import org.codehaus.jackson.type.TypeReference;
-import org.junit.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.keycloak.admin.client.Keycloak;
 import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.admin.client.resource.RoleMappingResource;
-import org.keycloak.admin.client.resource.RoleScopeResource;
 import org.keycloak.admin.client.resource.UserResource;
-import org.keycloak.common.util.Base64Url;
+import org.keycloak.common.util.Base64;
+import org.keycloak.hash.Pbkdf2PasswordHashProvider;
 import org.keycloak.models.Constants;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
 import org.keycloak.representations.idm.*;
 import org.keycloak.testsuite.KeycloakServer;
 import org.keycloak.util.JsonSerialization;
@@ -19,7 +20,6 @@ import org.keycloak.wildfly.adduser.AddUser;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.Collections;
 import java.util.List;
 
 import static org.junit.Assert.*;
@@ -59,7 +59,11 @@ public class AddUserTest {
         UserRepresentation user = realms.get(0).getUsers().get(0);
         assertEquals(new Integer(100000), user.getCredentials().get(0).getHashIterations());
         assertNull(user.getCredentials().get(0).getValue());
-        assertEquals(new Pbkdf2PasswordEncoder(Base64Url.decode(user.getCredentials().get(0).getSalt()), 100000).encode("password"), user.getCredentials().get(0).getHashedSaltedValue());
+
+        CredentialRepresentation credentials = user.getCredentials().get(0);
+
+        assertEquals(Pbkdf2PasswordHashProvider.ID, credentials.getAlgorithm());
+        assertEquals(new Integer(100000), credentials.getHashIterations());
 
         KeycloakServer server = new KeycloakServer();
         try {
                diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
index 2f89194..b01e1b9 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
@@ -322,7 +322,12 @@ public class ExportImportTest {
             Assert.fail("user " + username + " not found");
         }
 
-        Assert.assertTrue(userProvider.validCredentials(realm, user, UserCredentialModel.password(password)));
+        KeycloakSession session = keycloakRule.startSession();
+        try {
+            Assert.assertTrue(userProvider.validCredentials(session, realm, user, UserCredentialModel.password(password)));
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
     }
 
     private void assertNotAuthenticated(UserProvider userProvider, RealmProvider realmProvider, String realmName, String username, String password) {
@@ -336,7 +341,12 @@ public class ExportImportTest {
             return;
         }
 
-        Assert.assertFalse(userProvider.validCredentials(realm, user, UserCredentialModel.password(password)));
+        KeycloakSession session = keycloakRule.startSession();
+        try {
+            Assert.assertFalse(userProvider.validCredentials(session, realm, user, UserCredentialModel.password(password)));
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
     }
 
     private static void addUser(UserProvider userProvider, RealmModel appRealm, String username, String password) {
                diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
index b67ffa3..ae2e4be 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
@@ -678,7 +678,7 @@ public class FederationProvidersIntegrationTest {
             user.updateCredential(cred);
             UserCredentialValueModel userCredentialValueModel = user.getCredentialsDirectly().get(0);
             Assert.assertEquals(UserCredentialModel.PASSWORD, userCredentialValueModel.getType());
-            Assert.assertTrue(session.users().validCredentials(appRealm, user, cred));
+            Assert.assertTrue(session.users().validCredentials(session, appRealm, user, cred));
 
             // LDAP password is still unchanged
             LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, model);
                diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java
index 8c84581..435f221 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/AdapterTest.java
@@ -144,11 +144,11 @@ public class AdapterTest extends AbstractModelTest {
         cred.setType(CredentialRepresentation.PASSWORD);
         cred.setValue("geheim");
         user.updateCredential(cred);
-        Assert.assertTrue(userProvider.validCredentials(realmModel, user, UserCredentialModel.password("geheim")));
+        Assert.assertTrue(userProvider.validCredentials(session, realmModel, user, UserCredentialModel.password("geheim")));
         List<UserCredentialValueModel> creds = user.getCredentialsDirectly();
         Assert.assertEquals(creds.get(0).getHashIterations(), 1);
         realmModel.setPasswordPolicy(new PasswordPolicy("hashIterations(200)"));
-        Assert.assertTrue(userProvider.validCredentials(realmModel, user, UserCredentialModel.password("geheim")));
+        Assert.assertTrue(userProvider.validCredentials(session, realmModel, user, UserCredentialModel.password("geheim")));
         creds = user.getCredentialsDirectly();
         Assert.assertEquals(creds.get(0).getHashIterations(), 200);
         realmModel.setPasswordPolicy(new PasswordPolicy("hashIterations(1)"));
                diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java
index 1a4c660..0da22b0 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/MultipleRealmsTest.java
@@ -39,10 +39,10 @@ public class MultipleRealmsTest extends AbstractModelTest {
         r1user1.updateCredential(UserCredentialModel.password("pass1"));
         r2user1.updateCredential(UserCredentialModel.password("pass2"));
 
-        Assert.assertTrue(session.users().validCredentials(realm1, r1user1, UserCredentialModel.password("pass1")));
-        Assert.assertFalse(session.users().validCredentials(realm1, r1user1, UserCredentialModel.password("pass2")));
-        Assert.assertFalse(session.users().validCredentials(realm2, r2user1, UserCredentialModel.password("pass1")));
-        Assert.assertTrue(session.users().validCredentials(realm2, r2user1, UserCredentialModel.password("pass2")));
+        Assert.assertTrue(session.users().validCredentials(session, realm1, r1user1, UserCredentialModel.password("pass1")));
+        Assert.assertFalse(session.users().validCredentials(session, realm1, r1user1, UserCredentialModel.password("pass2")));
+        Assert.assertFalse(session.users().validCredentials(session, realm2, r2user1, UserCredentialModel.password("pass1")));
+        Assert.assertTrue(session.users().validCredentials(session, realm2, r2user1, UserCredentialModel.password("pass2")));
 
         // Test searching
         Assert.assertEquals(2, session.users().searchForUser("user", realm1).size());
                diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml
index 5884210..7ab4a37 100644
--- a/testsuite/integration-arquillian/pom.xml
+++ b/testsuite/integration-arquillian/pom.xml
@@ -41,5 +41,4 @@
         </pluginManagement>
     </build>
     
-    
 </project>
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/CustomerPortalExample.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/CustomerPortalExample.java
index beaa8fa..39c6517 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/CustomerPortalExample.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/CustomerPortalExample.java
@@ -5,7 +5,7 @@ import org.jboss.arquillian.container.test.api.OperateOnDeployment;
 import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
-import org.keycloak.testsuite.util.WaitUtils;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 
 /**
@@ -61,7 +61,7 @@ public class CustomerPortalExample extends AbstractPageWithInjectedUrl {
     }
 
     public void customerSession() {
-        WaitUtils.waitGuiForElement(customerSessionLink);
+        waitUntilElement(customerSessionLink).is().present();
         customerSessionLink.click();
     }
 
@@ -70,11 +70,11 @@ public class CustomerPortalExample extends AbstractPageWithInjectedUrl {
     }
 
     public void waitForCustomerListingHeader() {
-        WaitUtils.waitGuiForElementNotPresent(customerListingHeader);
+        waitUntilElement(customerListingHeader).is().not().present();
     }
 
     public void waitForCustomerSessionHeader() {
-        WaitUtils.waitGuiForElementNotPresent(customerSessionHeader);
+        waitUntilElement(customerSessionHeader).is().not().present();
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/ProductPortalExample.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/ProductPortalExample.java
index fd80e5d..29e692f 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/ProductPortalExample.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/ProductPortalExample.java
@@ -5,7 +5,7 @@ import org.jboss.arquillian.container.test.api.OperateOnDeployment;
 import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
-import org.keycloak.testsuite.util.WaitUtils;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 
 /**
@@ -48,7 +48,7 @@ public class ProductPortalExample extends AbstractPageWithInjectedUrl {
     }
 
     public void waitForProductListingHeader() {
-        WaitUtils.waitGuiForElementNotPresent(productListingHeader);
+        waitUntilElement(productListingHeader).is().not().present();
     }
 
     public void logOut() {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java
index f78d31a..559e0c7 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountFields.java
@@ -2,8 +2,7 @@ package org.keycloak.testsuite.auth.page.account;
 
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.page.Form;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElementNotPresent;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -49,11 +48,11 @@ public class AccountFields extends Form {
     }
 
     public void waitForUsernameInputPresent() {
-        waitAjaxForElement(usernameInput);
+        waitUntilElement(usernameInput).is().present();
     }
 
     public void waitForUsernameInputNotPresent() {
-        waitAjaxForElementNotPresent(usernameInput);
+        waitUntilElement(usernameInput).is().not().present();
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
index ae1816a..5f36e62 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/AccountManagement.java
@@ -21,7 +21,7 @@ import javax.ws.rs.core.UriBuilder;
 import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.testsuite.auth.page.AuthRealm;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElementPresent;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -66,10 +66,10 @@ public class AccountManagement extends AuthRealm {
     private WebElement error;
 
     public String getErrorMessage() {
-        waitGuiForElementPresent(error, "Error message should be visible");
+        waitUntilElement(error, "Error message should be present").is().present();
         return error.getText();
     }
-    
+
     public void backToReferer() {
         backToRefererLink.click();
     }
@@ -101,12 +101,12 @@ public class AccountManagement extends AuthRealm {
     public void save() {
         save.click();
     }
-    
+
     public RealmResource realmResource() {
         return keycloak().realm(getAuthRealm());
     }
-    
+
     public void waitForAccountLinkPresent() {
-        waitGuiForElementPresent(accountLink, "account link should be present");
+        waitUntilElement(accountLink, "account link should be present").is().present();
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/fragment/AccountManagementAlert.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/fragment/AccountManagementAlert.java
new file mode 100644
index 0000000..e4beb64
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/fragment/AccountManagementAlert.java
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * 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.auth.page.account.fragment;
+
+import org.keycloak.testsuite.page.AbstractAlert;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public class AccountManagementAlert extends AbstractAlert {
+
+    public boolean isError() {
+        return getAttributeClass().contains("alert-error");
+    }
+
+}
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/PasswordFields.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/PasswordFields.java
index ce05632..0666ae3 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/PasswordFields.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/PasswordFields.java
@@ -18,7 +18,7 @@
 package org.keycloak.testsuite.auth.page.account;
 
 import org.keycloak.testsuite.page.Form;
-import org.keycloak.testsuite.util.WaitUtils;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -54,6 +54,6 @@ public class PasswordFields extends Form {
     }
 
     public void waitForConfirmPasswordInputPresent() {
-        WaitUtils.waitGuiForElement(confirmPasswordInput);
+        waitUntilElement(confirmPasswordInput).is().present();
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/Login.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/Login.java
index e06c5b9..adb5759 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/Login.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/Login.java
@@ -20,8 +20,7 @@ package org.keycloak.testsuite.auth.page.login;
 import javax.ws.rs.core.UriBuilder;
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.testsuite.auth.page.AuthRealm;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElementNotPresent;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -62,11 +61,11 @@ public abstract class Login extends AuthRealm {
     private WebElement keycloakTheme;
 
     public void waitForKeycloakThemeNotPresent() {
-        waitGuiForElementNotPresent(keycloakTheme);
+        waitUntilElement(keycloakTheme).is().not().present();
     }
 
     public void waitForKeycloakThemePresent() {
-        waitGuiForElement(keycloakTheme);
+        waitUntilElement(keycloakTheme).is().present();
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginActions.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginActions.java
index 7308851..8610702 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginActions.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginActions.java
@@ -19,7 +19,7 @@ package org.keycloak.testsuite.auth.page.login;
 
 import javax.ws.rs.core.UriBuilder;
 import org.keycloak.testsuite.auth.page.AuthRealm;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElementPresent;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -45,7 +45,7 @@ public class LoginActions extends AuthRealm {
     private WebElement feedbackText;
     
     public String getFeedbackText() {
-        waitGuiForElementPresent(feedbackText, "Feedback message should be visible");
+        waitUntilElement(feedbackText, "Feedback message should be present").is().present();
         return feedbackText.getText();
     }
     
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java
index 8329abc..7a0ead7 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/LoginForm.java
@@ -70,20 +70,20 @@ public class LoginForm extends Form {
 
     public void register() {
         waitForUsernameInputPresent();
-        waitAjaxForElement(registerLink);
+        waitUntilElement(registerLink).is().present();
         registerLink.click();
     }
 
     public void login() {
-        waitAjaxForElement(loginButton);
+        waitUntilElement(loginButton).is().present();
         loginButton.click();
     }
-    
+
     public void forgotPassword() {
-        waitAjaxForElement(forgottenPassword);
+        waitUntilElement(forgottenPassword).is().present();
         forgottenPassword.click();
     }
-    
+
     public void rememberMe(boolean value) {
         waitForRememberMePresent();
         boolean selected = rememberMe.isSelected();
@@ -94,32 +94,31 @@ public class LoginForm extends Form {
 
 //    @Override
 //    public void cancel() {
-//        waitAjaxForElement(cancelButton);
+//        waitUntilElement(cancelButton).is().present();
 //        cancelButton.click();
 //    }
-    
     public void waitForUsernameInputPresent() {
         accountFields.waitForUsernameInputPresent();
     }
 
     public void waitForRegisterLinkNotPresent() {
-        waitAjaxForElementNotPresent(registerLink);
+        waitUntilElement(registerLink).is().not().present();
     }
 
     public void waitForResetPasswordLinkNotPresent() {
-        waitAjaxForElementNotPresent(forgottenPassword);
+        waitUntilElement(forgottenPassword).is().not().present();
     }
 
     public void waitForRememberMePresent() {
-        waitAjaxForElement(rememberMe);
+        waitUntilElement(rememberMe).is().present();
     }
 
     public void waitForRememberMeNotPresent() {
-        waitAjaxForElementNotPresent(rememberMe);
+        waitUntilElement(rememberMe).is().not().present();
     }
-    
+
     public void waitForLoginButtonPresent() {
-        waitGuiForElement(loginButton);
+        waitUntilElement(loginButton).is().present();
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/ResetCredentials.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/ResetCredentials.java
index 3b4c4e8..76b6436 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/ResetCredentials.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/ResetCredentials.java
@@ -21,7 +21,7 @@ import javax.ws.rs.core.UriBuilder;
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.testsuite.auth.page.account.AccountFields;
 import org.keycloak.testsuite.auth.page.account.PasswordFields;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElementPresent;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -57,7 +57,7 @@ public class ResetCredentials extends LoginActions {
     }
 
     public String getInfoMessage() {
-        waitGuiForElementPresent(info, "Info message should be visible");
+        waitUntilElement(info, "Info message should be visible").is().present();
         return info.getText();
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java
index 7a828ed..8caf9a6 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java
@@ -21,7 +21,7 @@
  */
 package org.keycloak.testsuite.auth.page.login;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -35,7 +35,7 @@ public class VerifyEmail extends Authenticate {
     private WebElement instruction;
     
     public String getInstructionMessage() {
-        waitGuiForElement(instruction);
+        waitUntilElement(instruction).is().present();
         return instruction.getText();
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
index 852133b..0c7596d 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/AdminConsoleRealm.java
@@ -3,8 +3,7 @@ package org.keycloak.testsuite.console.page;
 import org.keycloak.admin.client.resource.RealmResource;
 import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
 
-import org.keycloak.testsuite.util.WaitUtils;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -39,7 +38,7 @@ public class AdminConsoleRealm extends AdminConsoleRealmsRoot {
     private ConfigureMenu configureMenu;
 
     public ConfigureMenu configure() {
-        waitGuiForElement(By.xpath("//div[./h2[text()='Configure']]"));
+        waitUntilElement(By.xpath("//div[./h2[text()='Configure']]")).is().present();
         return configureMenu;
     }
 
@@ -92,7 +91,7 @@ public class AdminConsoleRealm extends AdminConsoleRealmsRoot {
     protected ManageMenu manageMenu;
 
     public ManageMenu manage() {
-        WaitUtils.waitGuiForElement(By.xpath("//div[./h2[text()='Manage']]"));
+        waitUntilElement(By.xpath("//div[./h2[text()='Manage']]")).is().present();
         return manageMenu;
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/Authentication.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/Authentication.java
index f15d37e..fd700ba 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/Authentication.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/Authentication.java
@@ -24,12 +24,12 @@ public class Authentication extends AdminConsoleRealm {
     private WebElement close;
     
     public String getSuccessMessage() {
-        waitAjaxForElement(success);
+        waitUntilElement(success).is().present();
         return success.getText();
     }
     
     public String getErrorMessage() {
-        waitAjaxForElement(error);
+        waitUntilElement(error).is().present();
         return error.getText();
     }
     
@@ -37,7 +37,7 @@ public class Authentication extends AdminConsoleRealm {
         if (close.isDisplayed()) {
             close.click();
         }
-        waitAjaxForElementNotVisible(close);
+        waitUntilElement(close).is().not().visible();
     }
     
     public AuthenticationTabs tabs() {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java
index ad64d37..03c008e 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/flows/FlowsTable.java
@@ -21,7 +21,7 @@
  */
 package org.keycloak.testsuite.console.page.authentication.flows;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -71,7 +71,7 @@ public class FlowsTable {
     
     private WebElement getRowByLabelText(String text) {
         WebElement row = tbody.findElement(By.xpath("//span[text() = '" + text + "']/../.."));
-        waitAjaxForElement(row);
+        waitUntilElement(row).is().present();
         return row;
     }
     
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java
index 818ff5d..81e0f2d 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/authentication/PasswordPolicy.java
@@ -8,7 +8,7 @@ import org.openqa.selenium.support.ui.Select;
 
 import java.util.List;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 /**
  * @author Petr Mensik
@@ -32,7 +32,7 @@ public class PasswordPolicy extends Authentication {
     private List<WebElement> allRows;
 
     public void addPolicy(PasswordPolicy.Type policy, String value) {
-        waitGuiForElement(addPolicySelectElement);
+        waitUntilElement(addPolicySelectElement).is().present();
         addPolicySelect.selectByVisibleText(policy.getName());
         setPolicyValue(policy, value);
         primaryButton.click();
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java
index 10fb7e5..cff0c23 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java
@@ -38,17 +38,17 @@ public class ClientMappers extends Client {
         }
 
         public void createMapper() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderLink(CREATE);
         }
 
         public void addBuiltin() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderLink(ADD_BUILTIN);
         }
 
         public void clickMapper(String mapperName) {
-            waitAjaxForBody();
+            waitForBody();
             body().findElement(By.linkText(mapperName)).click();
         }
 
@@ -57,7 +57,7 @@ public class ClientMappers extends Client {
         }
 
         private void clickMapperActionButton(String mapperName, String buttonText) {
-            waitAjaxForBody();
+            waitForBody();
             clickRowActionButton(getRowByLinkText(mapperName), buttonText);
         }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
index 6f9cccd..494b3fe 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java
@@ -62,32 +62,32 @@ public class Clients extends AdminConsoleRealm {
         }
 
         public void createClient() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderLink(CREATE);
         }
 
         public void importClient() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderLink(IMPORT);
         }
 
         public void clickClient(ClientRepresentation client) {
-            waitAjaxForBody();
+            waitForBody();
             clickClient(client.getClientId());
         }
 
         public void clickClient(String clientId) {
-            waitAjaxForBody();
+            waitForBody();
             body().findElement(linkText(clientId)).click();
         }
 
         public void editClient(String clientId) {
-            waitAjaxForBody();
+            waitForBody();
             clickRowActionButton(getRowByLinkText(clientId), EDIT);
         }
 
         public void deleteClient(String clientId) {
-            waitAjaxForBody();
+            waitForBody();
             clickRowActionButton(getRowByLinkText(clientId), DELETE);
         }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java
index 2be0435..88e6ed5 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java
@@ -8,7 +8,7 @@ import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
 import org.keycloak.testsuite.page.Form;
 import static org.keycloak.testsuite.page.Form.getInputValue;
 import static org.keycloak.testsuite.util.WaitUtils.pause;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.keycloak.testsuite.util.Timer;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -69,7 +69,7 @@ public class CreateClientForm extends Form {
     private List<WebElement> deleteRedirectUriIcons;
 
     public void setValues(ClientRepresentation client) {
-        waitAjaxForElement(clientIdInput);
+        waitUntilElement(clientIdInput).is().present();
 
         setClientId(client.getClientId());
         setName(client.getName());
@@ -230,7 +230,7 @@ public class CreateClientForm extends Form {
     }
 
     public String getProtocol() {
-        waitAjaxForElement(protocolSelect.getFirstSelectedOption());
+        waitUntilElement(protocolSelect.getFirstSelectedOption()).is().present();
         return protocolSelect.getFirstSelectedOption().getText();
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/AdminEvents.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/AdminEvents.java
index 8cf2afc..a0826e1 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/AdminEvents.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/AdminEvents.java
@@ -33,17 +33,17 @@ public class AdminEvents extends Events {
         private AdminEventsTableFilterForm filterForm;
 
         public void update() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderButton("Update");
         }
 
         public void reset() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderButton("Reset");
         }
 
         public void filter() {
-            waitAjaxForBody();
+            waitForBody();
             filterButton.click();
         }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/Config.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/Config.java
index fc22df1..49aa48a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/Config.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/Config.java
@@ -104,7 +104,7 @@ public class Config extends Events {
         }
         
         public void waitForClearEventsButtonPresent() {
-            waitAjaxForElement(clearLoginEventsButton);
+            waitUntilElement(clearLoginEventsButton).is().present();
         }
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/LoginEvents.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/LoginEvents.java
index 136e455..f519317 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/LoginEvents.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/events/LoginEvents.java
@@ -33,17 +33,17 @@ public class LoginEvents extends Events {
         private LoginEventsTableFilterForm filterForm;
 
         public void update() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderButton("Update");
         }
 
         public void reset() {
-            waitAjaxForBody();
+            waitForBody();
             clickHeaderButton("Reset");
         }
 
         public void filter() {
-            waitAjaxForBody();
+            waitForBody();
             filterButton.click();
         }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/KerberosUserProviderForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/KerberosUserProviderForm.java
index 1fb068f..41e62c9 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/KerberosUserProviderForm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/KerberosUserProviderForm.java
@@ -1,6 +1,6 @@
 package org.keycloak.testsuite.console.page.federation;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
 import org.keycloak.testsuite.page.Form;
@@ -50,7 +50,7 @@ public class KerberosUserProviderForm extends Form {
     }
 
     public void setKerberosRealmInput(String kerberosRealm) {
-        waitGuiForElement(By.id("kerberosRealm"));
+        waitUntilElement(By.id("kerberosRealm")).is().present();
         setInputValue(kerberosRealmInput, kerberosRealm);
     }
 
@@ -71,7 +71,7 @@ public class KerberosUserProviderForm extends Form {
     }
 
     public void selectEditMode(String mode) {
-        waitGuiForElement(By.id("editMode"));
+        waitUntilElement(By.id("editMode")).is().present();
         editModeSelect.selectByVisibleText(mode);
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/LdapUserProviderForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/LdapUserProviderForm.java
index 3acc5ec..5a34641 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/LdapUserProviderForm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/LdapUserProviderForm.java
@@ -1,7 +1,7 @@
 package org.keycloak.testsuite.console.page.federation;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
@@ -156,17 +156,14 @@ public class LdapUserProviderForm extends Form {
     }
 
     public void setKerberosRealmInput(String kerberosRealm) {
-        waitAjaxForElement(kerberosRealmInput);
         setInputValue(kerberosRealmInput, kerberosRealm);
     }
 
     public void setServerPrincipalInput(String serverPrincipal) {
-        waitAjaxForElement(serverPrincipalInput);
         setInputValue(serverPrincipalInput, serverPrincipal);
     }
 
     public void setKeyTabInput(String keyTab) {
-        waitAjaxForElement(keyTabInput);
         setInputValue(keyTabInput, keyTab);
     }
 
@@ -175,22 +172,22 @@ public class LdapUserProviderForm extends Form {
     }
 
     public void selectEditMode(String mode) {
-        waitGuiForElement(By.id("editMode"));
+        waitUntilElement(By.id("editMode")).is().present();
         editModeSelect.selectByVisibleText(mode);
     }
 
     public void selectVendor(String vendor) {
-        waitGuiForElement(By.id("vendor"));
+        waitUntilElement(By.id("vendor")).is().present();
         vendorSelect.selectByVisibleText(vendor);
     }
 
     public void selectAuthenticationType(String authenticationType) {
-        waitGuiForElement(By.id("authType"));
+        waitUntilElement(By.id("authType")).is().present();
         authTypeSelect.selectByVisibleText(authenticationType);
     }
 
     public void selectSearchScope(String searchScope) {
-        waitGuiForElement(By.id("searchScope"));
+        waitUntilElement(By.id("searchScope")).is().present();
         searchScopeSelect.selectByVisibleText(searchScope);
     }
 
@@ -248,7 +245,7 @@ public class LdapUserProviderForm extends Form {
     }
 
     public void synchronizeAllUsers() {
-        waitAjaxForElement(synchronizeAllUsersButton);
+        waitUntilElement(synchronizeAllUsersButton).is().present();
         synchronizeAllUsersButton.click();
     }
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/UserFederation.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/UserFederation.java
index b209b81..c0dd078 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/UserFederation.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/federation/UserFederation.java
@@ -5,7 +5,7 @@ import org.keycloak.testsuite.console.page.AdminConsoleRealm;
 import org.openqa.selenium.By;
 import org.openqa.selenium.support.ui.Select;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 
 /**
  * Created by fkiss.
@@ -21,7 +21,7 @@ public class UserFederation extends AdminConsoleRealm {
     private Select addProviderSelect;
 
     public void addProvider(String provider) {
-        waitGuiForElement(By.cssSelector("select[ng-model*='selectedProvider']"));
+        waitUntilElement(By.cssSelector("select[ng-model*='selectedProvider']")).is().present();
         addProviderSelect.selectByVisibleText(provider);
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java
index f6bbb1c..ed1212a 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/DataTable.java
@@ -7,7 +7,8 @@ import org.openqa.selenium.support.FindBy;
 import java.util.List;
 
 import static org.keycloak.testsuite.util.WaitUtils.pause;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+import org.openqa.selenium.By;
 import static org.openqa.selenium.By.xpath;
 
 /**
@@ -32,18 +33,18 @@ public class DataTable {
     private WebElement infoRow;
 
     public void search(String pattern) {
-        waitAjaxForBody();
+        waitForBody();
         searchInput.sendKeys(pattern);
         searchButton.click();
     }
 
     public void clickHeaderButton(String buttonText) {
-        waitAjaxForBody();
+        waitForBody();
         header.findElement(By.xpath(".//button[text()='" + buttonText + "']")).click();
     }
 
     public void clickHeaderLink(String linkText) {
-        waitAjaxForBody();
+        waitForBody();
         header.findElement(By.linkText(linkText)).click();
     }
 
@@ -51,19 +52,19 @@ public class DataTable {
         return body;
     }
 
-    public void waitAjaxForBody() {
-        waitAjaxForElement(body);
+    public void waitForBody() {
+        waitUntilElement(body).is().present();
     }
 
     public List<WebElement> rows() {
-        waitAjaxForBody();
+        waitForBody();
         pause(250);
         return rows;
     }
 
     public WebElement getRowByLinkText(String text) {
         WebElement row = body.findElement(By.xpath(".//tr[./td/a[text()='" + text + "']]"));
-        waitAjaxForElement(row);
+        waitUntilElement(row).is().present();
         return row;
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Menu.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Menu.java
index 577259c..1b4eaf8 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Menu.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/Menu.java
@@ -18,7 +18,7 @@
 package org.keycloak.testsuite.console.page.fragment;
 
 import java.util.List;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.By;
 
 import org.openqa.selenium.WebElement;
@@ -53,7 +53,7 @@ public class Menu {
     }
 
     public String getCurrentRealm() {
-        waitGuiForElement(By.cssSelector(MENU_LOCATOR));
+        waitUntilElement(By.cssSelector(MENU_LOCATOR)).is().present();
         return toggle.get(1).getText();
     }
 
@@ -67,7 +67,7 @@ public class Menu {
                 menuOrder = 0;
                 break;
         }
-        waitGuiForElement(By.cssSelector(MENU_LOCATOR));
+        waitUntilElement(By.cssSelector(MENU_LOCATOR)).is().present();
         if (!menuList.get(menuOrder).isDisplayed()) {
             toggle.get(menuOrder).click();
         }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java
index 36677b4..4db28a0 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java
@@ -1,6 +1,6 @@
 package org.keycloak.testsuite.console.page.fragment;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 
@@ -21,22 +21,22 @@ public class ModalDialog {
     private WebElement nameInput;
 
     public void ok() {
-        waitAjaxForElement(okButton);
+        waitUntilElement(okButton).is().present();
         okButton.click();
     }
     
     public void confirmDeletion() {
-        waitAjaxForElement(deleteButton);
+        waitUntilElement(deleteButton).is().present();
         deleteButton.click();
     }
 
     public void cancel() {
-        waitAjaxForElement(cancelButton);
+        waitUntilElement(cancelButton).is().present();
         cancelButton.click();
     }
     
     public void setName(String name) {
-        waitAjaxForElement(nameInput);
+        waitUntilElement(nameInput).is().present();
         nameInput.clear();
         nameInput.sendKeys(name);
     }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java
index 118e058..d8c595e 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java
@@ -19,7 +19,7 @@ package org.keycloak.testsuite.console.page.fragment;
 
 import org.jboss.arquillian.graphene.fragment.Root;
 import org.jboss.arquillian.test.api.ArquillianResource;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.interactions.Actions;
@@ -45,12 +45,12 @@ public class OnOffSwitch {
     }
 
     public boolean isOn() {
-        waitAjaxForElement(root);
+        waitUntilElement(root).is().present();
         return root.findElement(By.tagName("input")).isSelected();
     }
 
     private void click() {
-        waitAjaxForElement(root);
+        waitUntilElement(root).is().present();
         actions.moveToElement(root.findElements(By.tagName("span")).get(0))
                 .click().build().perform();
     }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/ThemeSettings.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/ThemeSettings.java
index 3a4acde..c716086 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/ThemeSettings.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/ThemeSettings.java
@@ -20,7 +20,7 @@ package org.keycloak.testsuite.console.page.realm;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.By;
 
 /**
@@ -47,7 +47,7 @@ public class ThemeSettings extends RealmSettings {
     private Select emailThemeSelect;
 
     public void changeLoginTheme(String themeName) {
-        waitGuiForElement(By.id("loginTheme"));
+        waitUntilElement(By.id("loginTheme")).is().present();
         loginThemeSelect.selectByVisibleText(themeName);
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/TokenSettings.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/TokenSettings.java
index fc9ad0a..abeddb5 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/TokenSettings.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/realm/TokenSettings.java
@@ -23,7 +23,7 @@ import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
 
 import static java.lang.String.valueOf;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import static org.apache.commons.lang3.text.WordUtils.capitalize;
 import org.jboss.arquillian.graphene.page.Page;
 import org.keycloak.testsuite.page.Form;
@@ -70,7 +70,7 @@ public class TokenSettings extends RealmSettings {
 
         private void setTimeout(Select timeoutElement, WebElement unitElement,
                 int timeout, TimeUnit unit) {
-            waitGuiForElement(sessionTimeout);
+            waitUntilElement(sessionTimeout).is().present();
             timeoutElement.selectByValue(capitalize(unit.name().toLowerCase()));
             unitElement.clear();
             unitElement.sendKeys(valueOf(timeout));
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java
index 876b45b..9dc25c7 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java
@@ -9,7 +9,7 @@ import java.util.Map;
 import java.util.Set;
 import org.keycloak.representations.idm.RoleRepresentation.Composites;
 import org.keycloak.testsuite.page.Form;
-import static org.keycloak.testsuite.util.WaitUtils.waitGuiForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -127,7 +127,7 @@ public class RoleCompositeRoles extends Form {
 
     // *** original methods ***
     public void addAvailableRole(String... roles) {
-        waitGuiForElement(By.id("available"));
+        waitUntilElement(By.id("available")).is().present();
         for (String role : roles) {
             availableRealmRolesSelect.selectByVisibleText(role);
             addSelectedRealmRolesButton.click();
@@ -135,13 +135,13 @@ public class RoleCompositeRoles extends Form {
     }
 
     public void removeAssignedRole(String role) {
-        waitGuiForElement(By.id("assigned"));
+        waitUntilElement(By.id("assigned")).is().present();
         assignedRealmRolesSelect.selectByVisibleText(role);
         removeSelectedRealmRolesButton.click();
     }
 
     public boolean isAssignedRole(String role) {
-        waitGuiForElement(By.id("assigned"));
+        waitUntilElement(By.id("assigned")).is().present();
         try {
             assignedRealmRolesSelect.selectByVisibleText(role);
         } catch (Exception ex) {
@@ -151,7 +151,7 @@ public class RoleCompositeRoles extends Form {
     }
 
     public boolean isAssignedClientRole(String role) {
-        waitGuiForElement(By.id("assigned"));
+        waitUntilElement(By.id("assigned")).is().present();
         try {
             assignedClientRolesSelect.selectByVisibleText(role);
         } catch (Exception ex) {
@@ -161,12 +161,12 @@ public class RoleCompositeRoles extends Form {
     }
 
     public void selectClientRole(String client) {
-        waitGuiForElement(By.id("clients"));
+        waitUntilElement(By.id("clients")).is().present();
         clientSelect.selectByVisibleText(client);
     }
 
     public void addAvailableClientRole(String... roles) {
-        waitGuiForElement(By.id("available-client"));
+        waitUntilElement(By.id("available-client")).is().present();
         for (String role : roles) {
             availableClientRolesSelect.selectByVisibleText(role);
             addSelectedClientRolesButton.click();
@@ -174,7 +174,7 @@ public class RoleCompositeRoles extends Form {
     }
 
     public void removeAssignedClientRole(String client) {
-        waitGuiForElement(By.id("assigned-client"));
+        waitUntilElement(By.id("assigned-client")).is().present();
         assignedClientRolesSelect.selectByVisibleText(client);
         removeSelectedClientRolesButton.click();
     }
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RolesTable.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RolesTable.java
index b215844..3bec08d 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RolesTable.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RolesTable.java
@@ -28,7 +28,7 @@ public class RolesTable extends DataTable {
     }
 
     public void clickRole(String name) {
-        waitAjaxForBody();
+        waitForBody();
         clickRowByLinkText(name);
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/UserAttributesForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/UserAttributesForm.java
index e508e71..4050f7d 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/UserAttributesForm.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/UserAttributesForm.java
@@ -4,7 +4,7 @@ import java.util.List;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
 import org.keycloak.testsuite.page.Form;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
 import org.openqa.selenium.support.ui.Select;
@@ -125,7 +125,7 @@ public class UserAttributesForm extends Form {
     }
 
     public void setValues(UserRepresentation user) {
-        waitAjaxForElement(usernameInput);
+        waitUntilElement(usernameInput).is().present();
         setUsername(user.getUsername());
         setEmail(user.getEmail());
         setFirstName(user.getFirstName());
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/Users.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
index 3b1d730..d5ffcb5 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/users/Users.java
@@ -27,7 +27,7 @@ import org.keycloak.representations.idm.UserRepresentation;
 
 import org.keycloak.testsuite.console.page.AdminConsoleRealm;
 import org.keycloak.testsuite.console.page.fragment.DataTable;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import static org.openqa.selenium.By.*;
 
 /**
@@ -73,7 +73,7 @@ public class Users extends AdminConsoleRealm {
         }
 
         public void clickUser(String username) {
-            waitAjaxForElement(body());
+            waitUntilElement(body()).is().present();
             body().findElement(linkText(username)).click();
         }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java
new file mode 100644
index 0000000..cad5e26
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java
@@ -0,0 +1,51 @@
+package org.keycloak.testsuite.page;
+
+import com.google.common.base.Predicate;
+import static org.jboss.arquillian.graphene.Graphene.waitModel;
+import org.jboss.arquillian.graphene.fragment.Root;
+import org.jboss.logging.Logger;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ *
+ * @author tkyjovsk
+ */
+public abstract class AbstractAlert {
+
+    protected final Logger log = Logger.getLogger(this.getClass());
+
+    @Root
+    protected WebElement root;
+
+    public void waitUntilPresent() {
+        waitUntilElement(root, "Flash message should be present.").is().present();
+    }
+
+    public void waitUntilPresentAndClassSet() {
+        waitUntilPresent();
+        waitModel().until(new Predicate<WebDriver>() {
+            @Override
+            public boolean apply(WebDriver input) {
+                return !getAttributeClass().endsWith("alert-");
+            }
+        });
+    }
+
+    public String getText() {
+        return root.getText();
+    }
+
+    public String getAttributeClass() {
+        String attrClass = root.getAttribute("class");
+        log.debug("Alert @class = '" + attrClass + "'");
+        return attrClass;
+    }
+
+    public boolean isSuccess() {
+        log.debug("Alert.isSuccess()");
+        return getAttributeClass().contains("alert-success");
+    }
+
+}
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java
index eee8a21..7f664c7 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/Form.java
@@ -3,7 +3,7 @@ package org.keycloak.testsuite.page;
 import org.jboss.arquillian.drone.api.annotation.Drone;
 import static org.jboss.arquillian.graphene.Graphene.guardAjax;
 import org.jboss.logging.Logger;
-import static org.keycloak.testsuite.util.WaitUtils.waitAjaxForElement;
+import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.FindBy;
@@ -36,14 +36,14 @@ public class Form {
     }
 
     public static String getInputValue(WebElement input) {
-        waitAjaxForElement(input);
+        waitUntilElement(input).is().present();
         return input.getAttribute(VALUE);
     }
 
     public static final String VALUE = "value";
 
     public static void setInputValue(WebElement input, String value) {
-        waitAjaxForElement(input);
+        waitUntilElement(input).is().present();
         if (input.isEnabled()) {
             input.clear();
             if (value != null) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
index 00aaed3..7c6a230 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/WaitUtils.java
@@ -17,11 +17,10 @@
  */
 package org.keycloak.testsuite.util;
 
-import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import static org.jboss.arquillian.graphene.Graphene.waitAjax;
 import static org.jboss.arquillian.graphene.Graphene.waitGui;
+import org.jboss.arquillian.graphene.wait.ElementBuilder;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
 
@@ -33,52 +32,19 @@ import org.openqa.selenium.WebElement;
 public final class WaitUtils {
 
     public static final String PAGELOAD_TIMEOUT_PROP = "pageload.timeout";
-    public static final String IMPLICIT_TIMEOUT_PROP = "implicit.timeout";
-    public static final String SCRIPT_TIMEOUT_PROP = "script.timeout";
-    public static final String POLLING_INTERVAL_PROP = "polling.interval";
 
-    public static final Integer PAGELOAD_TIMEOUT = Integer.parseInt(System.getProperty(PAGELOAD_TIMEOUT_PROP, "5000"));
-    public static final Integer IMPLICIT_TIMEOUT = Integer.parseInt(System.getProperty(IMPLICIT_TIMEOUT_PROP, "3000"));
-    public static final Integer SCRIPT_TIMEOUT = Integer.parseInt(System.getProperty(SCRIPT_TIMEOUT_PROP, "3000"));
+    public static final Integer PAGELOAD_TIMEOUT = Integer.parseInt(System.getProperty(PAGELOAD_TIMEOUT_PROP, "60000"));
 
-    public static final Integer POLLING_INTERVAL = Integer.parseInt(System.getProperty(POLLING_INTERVAL_PROP, "1000"));
-
-    public static void waitAjaxForElement(WebElement element) {
-        waitAjax().withTimeout(SCRIPT_TIMEOUT, TimeUnit.MILLISECONDS).pollingEvery(POLLING_INTERVAL, TimeUnit.MILLISECONDS)
-                .until().element(element).is().present();
-    }
-
-    public static void waitAjaxForElementNotPresent(WebElement element) {
-        waitAjax().withTimeout(SCRIPT_TIMEOUT, TimeUnit.MILLISECONDS).pollingEvery(POLLING_INTERVAL, TimeUnit.MILLISECONDS)
-                .until().element(element).is().not().present();
-    }
-
-    public static void waitAjaxForElementNotVisible(WebElement element) {
-        waitAjax().withTimeout(SCRIPT_TIMEOUT, TimeUnit.MILLISECONDS).pollingEvery(POLLING_INTERVAL, TimeUnit.MILLISECONDS)
-                .until().element(element).is().not().visible();
-    }
-
-    public static void waitGuiForElement(By element, String message) {
-        waitGui().withTimeout(IMPLICIT_TIMEOUT, TimeUnit.MILLISECONDS).pollingEvery(POLLING_INTERVAL, TimeUnit.MILLISECONDS)
-                .until(message).element(element).is().present();
-    }
-
-    public static void waitGuiForElement(By element) {
-        waitGuiForElement(element, null);
-    }
-
-    public static void waitGuiForElement(WebElement element) {
-        waitGuiForElementPresent(element, null);
+    public static ElementBuilder<Void> waitUntilElement(By by) {
+        return waitGui().until().element(by);
     }
 
-    public static void waitGuiForElementPresent(WebElement element, String message) {
-        waitGui().withTimeout(IMPLICIT_TIMEOUT, TimeUnit.MILLISECONDS).pollingEvery(POLLING_INTERVAL, TimeUnit.MILLISECONDS)
-                .until(message).element(element).is().present();
+    public static ElementBuilder<Void> waitUntilElement(WebElement element) {
+        return waitGui().until().element(element);
     }
 
-    public static void waitGuiForElementNotPresent(WebElement element) {
-        waitGui().withTimeout(IMPLICIT_TIMEOUT, TimeUnit.MILLISECONDS).pollingEvery(POLLING_INTERVAL, TimeUnit.MILLISECONDS)
-                .until().element(element).is().not().present();
+    public static ElementBuilder<Void> waitUntilElement(WebElement element, String failMessage) {
+        return waitGui().until(failMessage).element(element);
     }
 
     public static void pause(long millis) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
index 31c9b77..0fb0efe 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
@@ -19,9 +19,7 @@ package org.keycloak.testsuite;
 
 import java.text.MessageFormat;
 import java.util.List;
-import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.jboss.arquillian.graphene.page.Page;
-import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.keycloak.admin.client.resource.RealmResource;
 import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD;
@@ -32,7 +30,6 @@ import static org.keycloak.testsuite.admin.Users.setPasswordFor;
 import org.keycloak.testsuite.auth.page.AuthRealm;
 import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
 import org.keycloak.testsuite.auth.page.login.OIDCLogin;
-import org.keycloak.testsuite.console.page.fragment.FlashMessage;
 import org.openqa.selenium.Cookie;
 
 /**
@@ -48,9 +45,6 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest {
 
     protected UserRepresentation testUser;
 
-    @FindByJQuery(".alert")
-    protected FlashMessage flashMessage;
-
     @Override
     public void addTestRealms(List<RealmRepresentation> testRealms) {
         RealmRepresentation testRealmRep = new RealmRepresentation();
@@ -68,12 +62,12 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest {
 
         deleteAllCookiesForTestRealm();
     }
-    
+
     public void createTestUserWithAdminClient() {
         log.debug("creating test user");
         String id = createUserAndResetPasswordWithAdminClient(testRealmResource(), testUser, PASSWORD);
         testUser.setId(id);
-        
+
         assignClientRoles(testRealmResource(), id, "realm-management", "view-realm");
     }
 
@@ -101,21 +95,6 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest {
         }
     }
 
-    public void assertFlashMessageSuccess() {
-        flashMessage.waitUntilPresent();
-        assertTrue(flashMessage.getText(), flashMessage.isSuccess());
-    }
-
-    public void assertFlashMessageDanger() {
-        flashMessage.waitUntilPresent();
-        assertTrue(flashMessage.getText(), flashMessage.isDanger());
-    }
-
-    public void assertFlashMessageError() {
-        flashMessage.waitUntilPresent();
-        assertTrue(flashMessage.getText(), flashMessage.isError());
-    }
-
     public RealmResource testRealmResource() {
         return adminClient.realm(testRealmPage.getAuthRealm());
     }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
index e553b3d..063347a 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
@@ -118,8 +118,6 @@ public abstract class AbstractKeycloakTest {
 
     protected void driverSettings() {
         driver.manage().timeouts().pageLoadTimeout(WaitUtils.PAGELOAD_TIMEOUT, TimeUnit.MILLISECONDS);
-        driver.manage().timeouts().implicitlyWait(WaitUtils.IMPLICIT_TIMEOUT, TimeUnit.MILLISECONDS);
-        driver.manage().timeouts().setScriptTimeout(WaitUtils.SCRIPT_TIMEOUT, TimeUnit.MILLISECONDS);
         driver.manage().window().maximize();
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AbstractAccountManagementTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AbstractAccountManagementTest.java
index 6a7a4c1..97be6e6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AbstractAccountManagementTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AbstractAccountManagementTest.java
@@ -1,10 +1,13 @@
 package org.keycloak.testsuite.account;
 
 import org.jboss.arquillian.graphene.page.Page;
+import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.keycloak.testsuite.AbstractAuthTest;
 import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
 import org.keycloak.testsuite.auth.page.account.AccountManagement;
+import org.keycloak.testsuite.auth.page.account.fragment.AccountManagementAlert;
+import org.openqa.selenium.support.FindBy;
 
 /**
  *
@@ -15,6 +18,9 @@ public abstract class AbstractAccountManagementTest extends AbstractAuthTest {
     @Page
     protected AccountManagement testRealmAccountManagementPage;
 
+    @FindBy(className = "alert")
+    protected AccountManagementAlert alert;
+
     @Override
     public void setDefaultPageUriParameters() {
         super.setDefaultPageUriParameters();
@@ -27,5 +33,15 @@ public abstract class AbstractAccountManagementTest extends AbstractAuthTest {
         // make user test user exists in test realm
         createTestUserWithAdminClient();
     }
-    
+
+    public void assertAlertSuccess() {
+        alert.waitUntilPresentAndClassSet();
+        assertTrue(alert.isSuccess());
+    }
+
+    public void assertAlertError() {
+        alert.waitUntilPresentAndClassSet();
+        assertTrue(alert.isError());
+    }
+
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index e509276..b9f60ee 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -66,7 +66,7 @@ public class AccountTest extends AbstractAccountManagementTest {
         testRealmAccountPage.setFirstName(NEW_FIRST_NAME);
         testRealmAccountPage.setLastName(NEW_LAST_NAME);
         testRealmAccountPage.save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountManagementPage.signOut();
         testRealmLoginPage.form().login(testUser);
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ChangePasswordTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ChangePasswordTest.java
index 5787903..f3619ee 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ChangePasswordTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/ChangePasswordTest.java
@@ -38,20 +38,20 @@ public class ChangePasswordTest extends AbstractAccountManagementTest {
     @Test
     public void invalidChangeAttempts() {
         testRealmChangePasswordPage.save();
-        assertFlashMessageError();
+        assertAlertError();
 
         testRealmChangePasswordPage.changePasswords(WRONG_PASSWORD, NEW_PASSWORD, NEW_PASSWORD);
-        assertFlashMessageError();
+        assertAlertError();
 
         testRealmChangePasswordPage.changePasswords(correctPassword, NEW_PASSWORD, NEW_PASSWORD + "-mismatch");
-        assertFlashMessageError();
+        assertAlertError();
     }
 
     @Test
     public void successfulChangeAttempts() {
         // change password successfully
         testRealmChangePasswordPage.changePasswords(correctPassword, NEW_PASSWORD, NEW_PASSWORD);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         // login using new password
         testRealmAccountManagementPage.signOut();
@@ -61,7 +61,7 @@ public class ChangePasswordTest extends AbstractAccountManagementTest {
         // change password back
         testRealmAccountManagementPage.password();
         testRealmChangePasswordPage.changePasswords(NEW_PASSWORD, correctPassword, correctPassword);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
index 573363a..eb2fb5b 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/AbstractConsoleTest.java
@@ -17,7 +17,9 @@
  */
 package org.keycloak.testsuite.console;
 
+import org.jboss.arquillian.graphene.findby.FindByJQuery;
 import org.jboss.arquillian.graphene.page.Page;
+import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.AbstractAuthTest;
@@ -27,6 +29,7 @@ import org.keycloak.testsuite.console.page.AdminConsoleRealm.ConfigureMenu;
 import org.keycloak.testsuite.console.page.AdminConsoleRealm.ManageMenu;
 import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
 import org.keycloak.testsuite.auth.page.login.Login;
+import org.keycloak.testsuite.console.page.fragment.AdminConsoleAlert;
 import org.keycloak.testsuite.console.page.fragment.ModalDialog;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
 import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
@@ -46,10 +49,13 @@ public abstract class AbstractConsoleTest extends AbstractAuthTest {
 
     @Page
     protected AdminConsole testRealmAdminConsolePage;
-    
+
     @FindBy(xpath = "//div[@class='modal-dialog']")
     protected ModalDialog modalDialog;
 
+    @FindBy(className = "alert")
+    protected AdminConsoleAlert alert;
+
     protected boolean adminLoggedIn = false;
 
     @Override
@@ -100,6 +106,18 @@ public abstract class AbstractConsoleTest extends AbstractAuthTest {
         assertCurrentUrlStartsWithLoginUrlOf(adminConsole);
     }
 
+    public void assertAlertSuccess() {
+        alert.waitUntilPresentAndClassSet();
+        assertTrue(alert.isSuccess());
+        alert.close();
+    }
+
+    public void assertAlertDanger() {
+        alert.waitUntilPresentAndClassSet();
+        assertTrue(alert.isDanger());
+        alert.close();
+    }
+
     public ConfigureMenu configure() {
         return adminConsoleRealmPage.configure();
     }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/PasswordPolicyTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/PasswordPolicyTest.java
index b48cf84..f904613 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/PasswordPolicyTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/PasswordPolicyTest.java
@@ -50,18 +50,18 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
         passwordPolicyPage.navigateTo();
         passwordPolicyPage.addPolicy(HASH_ITERATIONS, 5);
         passwordPolicyPage.removePolicy(HASH_ITERATIONS);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
     public void testInvalidPolicyValues() {
         passwordPolicyPage.navigateTo();
         passwordPolicyPage.addPolicy(HASH_ITERATIONS, "asd");
-        assertFlashMessageDanger();
+        assertAlertDanger();
         passwordPolicyPage.removePolicy(HASH_ITERATIONS);
 
         passwordPolicyPage.addPolicy(REGEX_PATTERN, "([");
-        assertFlashMessageDanger();
+        assertAlertDanger();
     }
 
     @Test
@@ -72,10 +72,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("1234567");
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("12345678");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -86,10 +86,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("invalidPassword1");
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("validPassword12");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -100,10 +100,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("iNVALIDPASSWORD");
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("vaLIDPASSWORD");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -114,10 +114,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("Invalidpassword");
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("VAlidpassword");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -128,10 +128,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("invalidPassword*");
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("validPassword*#");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -142,10 +142,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword(testUser.getUsername());
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("validpassword");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -156,10 +156,10 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("invalidPassword");
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         testUserCredentialsPage.resetPassword("VALID#password");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -170,13 +170,13 @@ public class PasswordPolicyTest extends AbstractConsoleTest {
 
         testUserCredentialsPage.navigateTo();
         testUserCredentialsPage.resetPassword("firstPassword");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testUserCredentialsPage.resetPassword("secondPassword");
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testUserCredentialsPage.resetPassword("firstPassword");
-        assertFlashMessageDanger();
+        assertAlertDanger();
     }
 
 }
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java
index c45b792..b8217f8 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/authentication/RequiredActionsTest.java
@@ -60,7 +60,7 @@ public class RequiredActionsTest extends AbstractConsoleTest {
     public void termsAndConditionsDefaultActionTest() {
         requiredActionsPage.setTermsAndConditionEnabled(true);
         requiredActionsPage.setTermsAndConditionDefaultAction(true);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         allowTestRealmUserRegistration();
 
@@ -74,7 +74,7 @@ public class RequiredActionsTest extends AbstractConsoleTest {
     @Test
     public void configureTotpDefaultActionTest() {
         requiredActionsPage.setConfigureTotpDefaultAction(true);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         allowTestRealmUserRegistration();
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java
index a8a4c35..0142911 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java
@@ -36,7 +36,7 @@ public class ClientRolesTest extends AbstractClientTest {
 //        assertCurrentUrl(createClientRole); // can't do this, need client id to build uri
         createClientRolePage.form().setBasicAttributes(roleRep);
         createClientRolePage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         createClientRolePage.form().setCompositeRoles(roleRep);
         // TODO add verification of notification message when KEYCLOAK-1497 gets resolved
     }
@@ -47,11 +47,10 @@ public class ClientRolesTest extends AbstractClientTest {
         RoleRepresentation newRole = new RoleRepresentation("client-role", "", false);
 
         createClient(newClient);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         clientPage.tabs().roles();
         addClientRole(newRole);
-        assertFlashMessageSuccess();
 
         clientRolePage.backToClientRolesViaBreadcrumb();
         assertFalse(clientRolesPage.roles().getRolesFromTableRows().isEmpty());
@@ -60,7 +59,7 @@ public class ClientRolesTest extends AbstractClientTest {
         clientsPage.table().search(newClient.getClientId());
         clientsPage.table().deleteClient(newClient.getClientId());
         modalDialog.confirmDeletion();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         assertNull(clientsPage.table().findClient(newClient.getClientId()));
     }
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
index d259adf..9f1fd62 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java
@@ -48,7 +48,7 @@ public class ClientSettingsTest extends AbstractClientTest {
     public void crudOIDCConfidential() {
         newClient = createClientRepresentation("oidc-confidential", "http://example.test/app/*");
         createClient(newClient);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         clientPage.backToClientsViaBreadcrumb();
         assertCurrentUrlEquals(clientsPage);
@@ -70,7 +70,7 @@ public class ClientSettingsTest extends AbstractClientTest {
         newClient = createClientRepresentation("oidc-public", "http://example.test/app/*");
         newClient.setPublicClient(true);
         createClient(newClient);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         clientPage.backToClientsViaBreadcrumb();
         assertCurrentUrlEquals(clientsPage);
@@ -81,7 +81,7 @@ public class ClientSettingsTest extends AbstractClientTest {
         newClient = createClientRepresentation("oidc-bearer-only", "http://example.test/app/*");
         newClient.setBearerOnly(true);
         createClient(newClient);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         clientPage.backToClientsViaBreadcrumb();
         assertCurrentUrlEquals(clientsPage);
@@ -99,11 +99,11 @@ public class ClientSettingsTest extends AbstractClientTest {
     public void invalidSettings() {
         clientsPage.table().createClient();
         createClientPage.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         createClientPage.form().setClientId("test-client");
         createClientPage.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
     }
 
     public void assertClientSettingsEqual(ClientRepresentation c1, ClientRepresentation c2) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java
index eebb8a2..2c44e5a 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java
@@ -30,7 +30,7 @@ public class ConfigTest extends AbstractConsoleTest {
         configPage.form().removeSaveType("LOGIN");
         configPage.form().setExpiration("50", "Days");
         configPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         RealmRepresentation realm = testRealmResource().toRepresentation();
         assertTrue(realm.isEventsEnabled());
@@ -44,7 +44,7 @@ public class ConfigTest extends AbstractConsoleTest {
         configPage.form().setSaveAdminEvents(true);
         configPage.form().setIncludeRepresentation(true);
         configPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         RealmRepresentation realm = testRealmResource().toRepresentation();
         assertTrue(realm.isAdminEventsEnabled());
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/KerberosUserFederationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/KerberosUserFederationTest.java
index 47521e5..7eff162 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/KerberosUserFederationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/KerberosUserFederationTest.java
@@ -33,7 +33,7 @@ public class KerberosUserFederationTest extends AbstractConsoleTest {
 		createKerberosUserProvider.form().selectEditMode(READ_ONLY);
 		createKerberosUserProvider.form().setUpdateProfileFirstLogin(true);
 		createKerberosUserProvider.form().save();
-		assertFlashMessageSuccess();
+		assertAlertSuccess();
 		RealmRepresentation realm = testRealmResource().toRepresentation();
 		UserFederationProviderRepresentation ufpr = realm.getUserFederationProviders().get(0);
 		assertKerberosSetings(ufpr, "KEYCLOAK.ORG", "HTTP/localhost@KEYCLOAK.ORG", "http.keytab", "true", "true", "true");
@@ -50,18 +50,18 @@ public class KerberosUserFederationTest extends AbstractConsoleTest {
 		createKerberosUserProvider.form().selectEditMode(UNSYNCED);
 		createKerberosUserProvider.form().setUpdateProfileFirstLogin(true);
 		createKerberosUserProvider.form().save();
-		assertFlashMessageDanger();
+		assertAlertDanger();
 		createKerberosUserProvider.form().setServerPrincipalInput("");
 		createKerberosUserProvider.form().setKerberosRealmInput("KEYCLOAK.ORG");;
 		createKerberosUserProvider.form().save();
-		assertFlashMessageDanger();
+		assertAlertDanger();
 		createKerberosUserProvider.form().setServerPrincipalInput("HTTP/localhost@KEYCLOAK.ORG");;
 		createKerberosUserProvider.form().setKeyTabInput("");
 		createKerberosUserProvider.form().save();
-		assertFlashMessageDanger();		
+		assertAlertDanger();		
 		createKerberosUserProvider.form().setKeyTabInput("http.keytab");;
 		createKerberosUserProvider.form().save();
-		assertFlashMessageSuccess();
+		assertAlertSuccess();
 	}
 
 	private void assertKerberosSetings(UserFederationProviderRepresentation ufpr, String kerberosRealm, String serverPrincipal, String keyTab, String debug, String useKerberosForPasswordAuthentication, String updateProfileFirstLogin) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/LdapUserFederationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/LdapUserFederationTest.java
index 8d40845..7dc7ab2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/LdapUserFederationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/federation/LdapUserFederationTest.java
@@ -49,7 +49,7 @@ public class LdapUserFederationTest extends AbstractConsoleTest {
         createLdapUserProvider.form().setKeyTabInput("http.keytab");
         createLdapUserProvider.form().setDebugEnabled(true);
         createLdapUserProvider.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         RealmRepresentation realm = testRealmResource().toRepresentation();
         UserFederationProviderRepresentation ufpr = realm.getUserFederationProviders().get(0);
@@ -71,7 +71,7 @@ public class LdapUserFederationTest extends AbstractConsoleTest {
         createLdapUserProvider.form().setLdapUserDnInput("ou=People,dc=keycloak,dc=org");
         createLdapUserProvider.form().setLdapBindCredentialInput("secret");
         createLdapUserProvider.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         RealmRepresentation realm = testRealmResource().toRepresentation();
         UserFederationProviderRepresentation ufpr = realm.getUserFederationProviders().get(0);
@@ -92,22 +92,22 @@ public class LdapUserFederationTest extends AbstractConsoleTest {
         createLdapUserProvider.form().setLdapUserDnInput("ou=People,dc=keycloak,dc=org");
         createLdapUserProvider.form().setLdapBindCredentialInput("secret");
         createLdapUserProvider.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
         createLdapUserProvider.form().setLdapUserDnInput("");
         createLdapUserProvider.form().setLdapConnectionUrlInput("ldap://localhost:389");
         createLdapUserProvider.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
         createLdapUserProvider.form().setLdapUserDnInput("ou=People,dc=keycloak,dc=org");
         createLdapUserProvider.form().setLdapBindDnInput("");
         createLdapUserProvider.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
         createLdapUserProvider.form().setLdapBindDnInput("uid=admin,ou=system");
         createLdapUserProvider.form().setLdapBindCredentialInput("");
         createLdapUserProvider.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
         createLdapUserProvider.form().setLdapBindCredentialInput("secret");
         createLdapUserProvider.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
     }
 
     @Test
@@ -122,19 +122,19 @@ public class LdapUserFederationTest extends AbstractConsoleTest {
         createLdapUserProvider.form().setLdapBindCredentialInput("secret");
         createLdapUserProvider.form().setAccountAfterPasswordUpdateEnabled(true);
         createLdapUserProvider.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         LDAPEmbeddedServer ldapServer = null;
         try {
             ldapServer = startEmbeddedLdapServer();
             createLdapUserProvider.form().testConnection();
-            assertFlashMessageSuccess();
+            assertAlertSuccess();
             createLdapUserProvider.form().testAuthentication();
-            assertFlashMessageSuccess();
+            assertAlertSuccess();
             createLdapUserProvider.form().synchronizeAllUsers();
-            assertFlashMessageSuccess();
+            assertAlertSuccess();
             createLdapUserProvider.form().setLdapBindCredentialInput("secret1");
             createLdapUserProvider.form().testAuthentication();
-            assertFlashMessageDanger();
+            assertAlertDanger();
         } finally {
             if (ldapServer != null) {
                 ldapServer.stop();
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/idp/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/idp/IdentityProviderTest.java
index d31ec07..e4f7f84 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/idp/IdentityProviderTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/idp/IdentityProviderTest.java
@@ -38,8 +38,7 @@ public class IdentityProviderTest extends AbstractConsoleTest {
 //	@Test
     public void testAddNewProvider() {
         idpSettingsPage.addNewProvider(new Provider(SocialProvider.FACEBOOK, "klic", "secret"));
-        flashMessage.waitUntilPresent();
-        assertTrue("Success message should be displayed", flashMessage.isSuccess());
+        assertAlertSuccess();
     }
 
 //	@Test(expected = NoSuchElementException.class)
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/realm/SecurityDefensesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/realm/SecurityDefensesTest.java
index 96d8c9c..e5b8e74 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/realm/SecurityDefensesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/realm/SecurityDefensesTest.java
@@ -74,7 +74,7 @@ public class SecurityDefensesTest extends AbstractRealmTest {
         bruteForceDetectionPage.form().setWaitIncrementSelect(BruteForceDetection.TimeSelectValues.SECONDS);
         bruteForceDetectionPage.form().setWaitIncrementInput(String.valueOf(secondsToWait));
         bruteForceDetectionPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
@@ -115,7 +115,7 @@ public class SecurityDefensesTest extends AbstractRealmTest {
         bruteForceDetectionPage.form().setMinQuickLoginWaitSelect(BruteForceDetection.TimeSelectValues.SECONDS);
         bruteForceDetectionPage.form().setMinQuickLoginWaitInput(String.valueOf(secondsToWait));
         bruteForceDetectionPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
@@ -195,7 +195,7 @@ public class SecurityDefensesTest extends AbstractRealmTest {
         bruteForceDetectionPage.form().setFailureResetTimeSelect(BruteForceDetection.TimeSelectValues.SECONDS);
         bruteForceDetectionPage.form().setFailureResetTimeInput(String.valueOf(secondsToWait));
         bruteForceDetectionPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
@@ -228,7 +228,7 @@ public class SecurityDefensesTest extends AbstractRealmTest {
         bruteForceDetectionPage.form().setWaitIncrementSelect(BruteForceDetection.TimeSelectValues.MINUTES);
         bruteForceDetectionPage.form().setWaitIncrementInput("10");
         bruteForceDetectionPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
index e156c39..67baad2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/DefaultRolesTest.java
@@ -44,7 +44,7 @@ public class DefaultRolesTest extends AbstractRolesTest {
         String defaultRoleName = defaultRoleRep.getName();
 
         defaultRolesPage.form().addAvailableRole(defaultRoleName);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         UserRepresentation newUser = new UserRepresentation();
         newUser.setUsername("new_user");
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/RealmRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/RealmRolesTest.java
index 0df9c15..d0b54bc 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/RealmRolesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/roles/RealmRolesTest.java
@@ -42,7 +42,7 @@ public class RealmRolesTest extends AbstractRolesTest {
         assertCurrentUrlEquals(createRolePage);
         createRolePage.form().setBasicAttributes(roleRep);
         createRolePage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         createRolePage.form().setCompositeRoles(roleRep);
         // TODO add verification of notification message when KEYCLOAK-1497 gets resolved
     }
@@ -53,7 +53,7 @@ public class RealmRolesTest extends AbstractRolesTest {
 //        assertCurrentUrl(role); // can't do this, role id needed as uri param
         rolePage.form().setBasicAttributes(roleRep);
         rolePage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         rolePage.form().setCompositeRoles(roleRep);
     }
     
@@ -64,6 +64,7 @@ public class RealmRolesTest extends AbstractRolesTest {
     }
     
     @Test
+    @Ignore
     public void crudRole() {
         addRole(testRole);
         
@@ -77,7 +78,7 @@ public class RealmRolesTest extends AbstractRolesTest {
         testRole.setDescription("updated role description");
         rolePage.form().setDescription(testRole.getDescription());
         rolePage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         
         configure().roles();
         foundRole = realmRolesPage.table().findRole(testRole.getName()); // search & get role from table
@@ -111,13 +112,12 @@ public class RealmRolesTest extends AbstractRolesTest {
     @Test
     public void testAddExistingRole() {
         addRole(testRole);
-        assertFlashMessageSuccess();
         
         configure().roles();
         realmRolesPage.table().addRole();
         createRolePage.form().setBasicAttributes(testRole);
         createRolePage.form().save();
-        assertFlashMessageDanger();
+        assertAlertDanger();
     }
     
     public void createTestRoles(String namePrefix, int count) {
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/RequiredUserActionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/RequiredUserActionsTest.java
index d532ae6..787303f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/RequiredUserActionsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/RequiredUserActionsTest.java
@@ -67,7 +67,7 @@ public class RequiredUserActionsTest extends AbstractUserTest {
     public void updatePassword() {
         userAttributesPage.form().addRequiredAction(UPDATE_PASSWORD.getActionName());
         userAttributesPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
@@ -91,7 +91,7 @@ public class RequiredUserActionsTest extends AbstractUserTest {
     public void updateProfile() {
         userAttributesPage.form().addRequiredAction(UPDATE_PROFILE.getActionName());
         userAttributesPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
@@ -128,7 +128,7 @@ public class RequiredUserActionsTest extends AbstractUserTest {
 
         userAttributesPage.form().addRequiredAction(TERMS_AND_CONDITIONS.getActionName());
         userAttributesPage.form().save();
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         testRealmAccountPage.navigateTo();
 
                diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/UserAttributesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/UserAttributesTest.java
index 9d99c85..a2857b2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/UserAttributesTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/users/UserAttributesTest.java
@@ -49,7 +49,7 @@ public class UserAttributesTest extends AbstractUserTest {
         setPasswordFor(newTestRealmUser, "pass");
         newTestRealmUser.setEmail(invalidEmail);
         createUser(newTestRealmUser);
-        assertFlashMessageDanger();
+        assertAlertDanger();
 
         userAttributesPage.backToUsersViaBreadcrumb();
         assertNull(usersPage.table().findUser(testUsername));
@@ -58,7 +58,7 @@ public class UserAttributesTest extends AbstractUserTest {
     @Test
     public void noUsername() {
         createUser(newTestRealmUser);
-        assertFlashMessageDanger();
+        assertAlertDanger();
     }
 
     @Test
@@ -66,7 +66,7 @@ public class UserAttributesTest extends AbstractUserTest {
         String testUsername = "test_duplicated_user";
         newTestRealmUser.setUsername(testUsername);
         createUser(newTestRealmUser);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
 
         userAttributesPage.backToUsersViaBreadcrumb();
         assertNotNull(usersPage.table().findUser(testUsername));
@@ -74,7 +74,7 @@ public class UserAttributesTest extends AbstractUserTest {
         UserRepresentation testUser2 = new UserRepresentation();
         testUser2.setUsername(testUsername);
         createUser(testUser2);
-        assertFlashMessageDanger();
+        assertAlertDanger();
     }
 
     @Test
@@ -83,7 +83,7 @@ public class UserAttributesTest extends AbstractUserTest {
         disabledUser.setEnabled(false);
         disabledUser.setUsername("disabled_user");
         createUser(disabledUser);
-        assertFlashMessageSuccess();
+        assertAlertSuccess();
         // TODO try to log in
     }
 
                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 ad3f626..e347903 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml
@@ -9,6 +9,13 @@
         <property name="browser">${browser}</property>
     </extension>
     
+    <extension qualifier="graphene">
+        <property name="waitGuiInterval">5</property>
+        <property name="waitAjaxInterval">5</property>
+        <property name="waitModelInterval">10</property>
+        <property name="waitGuardInterval">5</property>
+    </extension>
+    
     <extension qualifier="graphene-secondbrowser">
         <property name="browser">${browser}</property>
     </extension>
                diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 064e588..e9473ad 100644
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -609,6 +609,7 @@
                 </pluginManagement>
             </build>
         </profile>
+        
     </profiles>
     
 </project>
                diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
index 3f4a23b..37e36e0 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
@@ -102,7 +102,7 @@ public class ReadUsersWorker implements Worker {
 
             // Validate password (shoould be same as username)
             if (readPassword) {
-                session.users().validCredentials(realm, user, UserCredentialModel.password(username));
+                session.users().validCredentials(session, realm, user, UserCredentialModel.password(username));
             }
 
             // Read federatedIdentities of user
                diff --git a/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java b/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
index 7be53c6..d741333 100644
--- a/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
+++ b/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
@@ -12,8 +12,8 @@ import org.jboss.aesh.console.command.invocation.CommandInvocation;
 import org.jboss.aesh.console.command.registry.AeshCommandRegistryBuilder;
 import org.jboss.aesh.console.command.registry.CommandRegistry;
 import org.keycloak.common.util.Base64;
-import org.keycloak.models.Constants;
-import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
+import org.keycloak.hash.Pbkdf2PasswordHashProvider;
+import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
@@ -138,14 +138,14 @@ public class AddUser {
         user.setUsername(userName);
         user.setCredentials(new LinkedList<CredentialRepresentation>());
 
-        byte[] salt = Pbkdf2PasswordEncoder.getSalt();
-        iterations = iterations > 0 ? iterations : DEFAULT_HASH_ITERATIONS;
+        UserCredentialValueModel credentialValueModel = new Pbkdf2PasswordHashProvider().encode(password, iterations > 0 ? iterations : DEFAULT_HASH_ITERATIONS);
 
         CredentialRepresentation credentials = new CredentialRepresentation();
-        credentials.setType(CredentialRepresentation.PASSWORD);
-        credentials.setHashIterations(iterations);
-        credentials.setSalt(Base64.encodeBytes(salt));
-        credentials.setHashedSaltedValue(new Pbkdf2PasswordEncoder(salt).encode(password, iterations));
+        credentials.setType(credentialValueModel.getType());
+        credentials.setAlgorithm(credentialValueModel.getAlgorithm());
+        credentials.setHashIterations(credentialValueModel.getHashIterations());
+        credentials.setSalt(Base64.encodeBytes(credentialValueModel.getSalt()));
+        credentials.setHashedSaltedValue(credentialValueModel.getValue());
 
         user.getCredentials().add(credentials);
 
@@ -289,4 +289,4 @@ public class AddUser {
         }
     }
 
-}
\ No newline at end of file
+}