keycloak-memoizeit

user provider refactor complete

7/15/2014 4:25:06 PM

Changes

export-import/export-import-impl/pom.xml 236(+0 -236)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportPropertiesManager.java 152(+0 -152)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java 83(+0 -83)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportUtils.java 20(+0 -20)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirImportReader.java 67(+0 -67)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ExportWriter.java 13(+0 -13)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ImportReader.java 13(+0 -13)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPImportReader.java 70(+0 -70)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPIOProvider.java 48(+0 -48)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java 336(+0 -336)

export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java 328(+0 -328)

export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportImportProvider 1(+0 -1)

export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.io.ExportImportIOProvider 2(+0 -2)

export-import/export-import-impl/src/test/java/org/keycloak/exportimport/ExportImportTestBase.java 115(+0 -115)

export-import/export-import-impl/src/test/java/org/keycloak/exportimport/JPAToMongoExportImportTest.java 38(+0 -38)

export-import/export-import-impl/src/test/java/org/keycloak/exportimport/MongoToJPAExportImportTest.java 71(+0 -71)

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

server/pom.xml 12(+11 -1)

services/src/main/java/org/keycloak/services/managers/ClaimManager.java 66(+0 -66)

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
index b0c37ac..99237ee 100755
--- a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
@@ -11,9 +11,16 @@ public class CredentialRepresentation {
     public static final String CLIENT_CERT = "cert";
 
     protected String type;
-    protected String value;
     protected String device;
 
+    // Plain-text value of credential (used for example during import from manually created JSON file)
+    protected String value;
+
+    // Value stored in DB (used for example during export/import)
+    protected String hashedSaltedValue;
+    protected String salt;
+    protected Integer hashIterations;
+
     public String getType() {
         return type;
     }
@@ -37,4 +44,28 @@ public class CredentialRepresentation {
     public void setDevice(String device) {
         this.device = device;
     }
+
+    public String getHashedSaltedValue() {
+        return hashedSaltedValue;
+    }
+
+    public void setHashedSaltedValue(String hashedSaltedValue) {
+        this.hashedSaltedValue = hashedSaltedValue;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    public Integer getHashIterations() {
+        return hashIterations;
+    }
+
+    public void setHashIterations(Integer hashIterations) {
+        this.hashIterations = hashIterations;
+    }
 }
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index 8751a38..7511de6 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -9,7 +9,6 @@ import java.util.List;
 public class OAuthClientRepresentation {
     protected String id;
     protected String name;
-    protected String baseUrl;
     protected List<String> redirectUris;
     protected List<String> webOrigins;
     protected Boolean enabled;
@@ -44,14 +43,6 @@ public class OAuthClientRepresentation {
         this.enabled = enabled;
     }
 
-    public String getBaseUrl() {
-        return baseUrl;
-    }
-
-    public void setBaseUrl(String baseUrl) {
-        this.baseUrl = baseUrl;
-    }
-
     public List<String> getRedirectUris() {
         return redirectUris;
     }
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 4b5380d..6d85877 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -423,4 +423,28 @@ public class RealmRepresentation {
     public void setFailureFactor(Integer failureFactor) {
         this.failureFactor = failureFactor;
     }
+
+    public boolean isAuditEnabled() {
+        return auditEnabled;
+    }
+
+    public void setAuditEnabled(boolean auditEnabled) {
+        this.auditEnabled = auditEnabled;
+    }
+
+    public long getAuditExpiration() {
+        return auditExpiration;
+    }
+
+    public void setAuditExpiration(long auditExpiration) {
+        this.auditExpiration = auditExpiration;
+    }
+
+    public List<String> getAuditListeners() {
+        return auditListeners;
+    }
+
+    public void setAuditListeners(List<String> auditListeners) {
+        this.auditListeners = auditListeners;
+    }
 }
diff --git a/export-import/export-import-api/pom.xml b/export-import/export-import-api/pom.xml
index 19db6e5..1b4dc0a 100755
--- a/export-import/export-import-api/pom.xml
+++ b/export-import/export-import-api/pom.xml
@@ -26,6 +26,32 @@
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-invalidation-cache-model</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.iharder</groupId>
+            <artifactId>base64</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportImportManager.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportImportManager.java
new file mode 100644
index 0000000..caedb36
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportImportManager.java
@@ -0,0 +1,63 @@
+package org.keycloak.exportimport;
+
+
+import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ExportImportManager {
+
+    private static final Logger logger = Logger.getLogger(ExportImportManager.class);
+
+    public void checkExportImport(KeycloakSessionFactory sessionFactory) {
+        String exportImportAction = ExportImportConfig.getAction();
+        String realmName = ExportImportConfig.getRealmName();
+
+        boolean export = false;
+        boolean importt = false;
+        if (ExportImportConfig.ACTION_EXPORT.equals(exportImportAction)) {
+            export = true;
+        } else if (ExportImportConfig.ACTION_IMPORT.equals(exportImportAction)) {
+            importt = true;
+        }
+
+        if (export || importt) {
+            String exportImportProviderId = ExportImportConfig.getProvider();
+            logger.debug("Will use provider: " + exportImportProviderId);
+            KeycloakSession session = sessionFactory.create();
+
+            try {
+                if (export) {
+                    ExportProvider exportProvider = session.getProvider(ExportProvider.class, exportImportProviderId);
+
+                    if (realmName == null) {
+                        logger.info("Full model export requested");
+                        exportProvider.exportModel(sessionFactory);
+                    } else {
+                        logger.infof("Export of realm '%s' requested", realmName);
+                        exportProvider.exportRealm(sessionFactory, realmName);
+                    }
+                    logger.info("Export finished successfully");
+                } else {
+                    ImportProvider importProvider = session.getProvider(ImportProvider.class, exportImportProviderId);
+                    Strategy strategy = ExportImportConfig.getStrategy();
+                    if (realmName == null) {
+                        logger.infof("Full model import requested. Strategy: %s", strategy.toString());
+                        importProvider.importModel(sessionFactory, strategy);
+                    } else {
+                        logger.infof("Import of realm '%s' requested. Strategy: %s", realmName, strategy.toString());
+                        importProvider.importRealm(sessionFactory, realmName, strategy);
+                    }
+                    logger.info("Import finished successfully");
+                }
+            } catch (Throwable ioe) {
+                logger.error("Error during export/import", ioe);
+            } finally {
+                session.close();
+            }
+        }
+    }
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportProvider.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportProvider.java
new file mode 100644
index 0000000..1a0d6a0
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportProvider.java
@@ -0,0 +1,18 @@
+package org.keycloak.exportimport;
+
+import java.io.IOException;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.provider.Provider;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface ExportProvider extends Provider {
+
+    void exportModel(KeycloakSessionFactory factory) throws IOException;
+
+    void exportRealm(KeycloakSessionFactory factory, String realmName) throws IOException;
+
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportSpi.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportSpi.java
new file mode 100644
index 0000000..6ec2960
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ExportSpi.java
@@ -0,0 +1,26 @@
+package org.keycloak.exportimport;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ExportSpi implements Spi {
+
+    @Override
+    public String getName() {
+        return "export";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return ExportProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return ExportProviderFactory.class;
+    }
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ImportProvider.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ImportProvider.java
new file mode 100644
index 0000000..9134516
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ImportProvider.java
@@ -0,0 +1,17 @@
+package org.keycloak.exportimport;
+
+import java.io.IOException;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.provider.Provider;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface ImportProvider extends Provider {
+
+    void importModel(KeycloakSessionFactory factory, Strategy strategy) throws IOException;
+
+    void importRealm(KeycloakSessionFactory factory, String realmName, Strategy strategy) throws IOException;
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ImportSpi.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ImportSpi.java
new file mode 100644
index 0000000..b562f3f
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/ImportSpi.java
@@ -0,0 +1,26 @@
+package org.keycloak.exportimport;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ImportSpi implements Spi {
+
+    @Override
+    public String getName() {
+        return "import";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return ImportProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return ImportProviderFactory.class;
+    }
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/Strategy.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/Strategy.java
new file mode 100644
index 0000000..6bbd70d
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/Strategy.java
@@ -0,0 +1,10 @@
+package org.keycloak.exportimport;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public enum Strategy {
+
+    IGNORE_EXISTING,         // Ignore existing user entries
+    OVERWRITE_EXISTING       // Overwrite existing user entries
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportImportJob.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportImportJob.java
new file mode 100644
index 0000000..748fe1f
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportImportJob.java
@@ -0,0 +1,15 @@
+package org.keycloak.exportimport.util;
+
+import java.io.IOException;
+
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * Task to be executed inside transaction
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface ExportImportJob {
+
+    public void run(KeycloakSession session) throws IOException;
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportImportUtils.java
new file mode 100644
index 0000000..b73a4c0
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportImportUtils.java
@@ -0,0 +1,47 @@
+package org.keycloak.exportimport.util;
+
+import java.io.IOException;
+
+import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ExportImportUtils {
+
+    /**
+     * Wrap given runnable job into KeycloakTransaction.
+     *
+     * @param factory
+     * @param job
+     */
+    public static void runJobInTransaction(KeycloakSessionFactory factory, ExportImportJob job) throws IOException {
+        KeycloakSession session = factory.create();
+        KeycloakTransaction tx = session.getTransaction();
+        try {
+            tx.begin();
+            job.run(session);
+
+            if (tx.isActive()) {
+                if (tx.getRollbackOnly()) {
+                    tx.rollback();
+                } else {
+                    tx.commit();
+                }
+            }
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
+            session.close();
+        }
+    }
+
+    public static String getMasterRealmAdminApplicationName(RealmModel realm) {
+        return realm.getName() + "-realm";
+    }
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
new file mode 100755
index 0000000..dd3c5dd
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -0,0 +1,366 @@
+package org.keycloak.exportimport.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.iharder.Base64;
+import org.codehaus.jackson.JsonEncoding;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.keycloak.exportimport.Strategy;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.AuthenticationLinkModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialValueModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
+import org.keycloak.representations.idm.ClaimRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.OAuthClientRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.RolesRepresentation;
+import org.keycloak.representations.idm.ScopeMappingRepresentation;
+import org.keycloak.representations.idm.SocialLinkRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ExportUtils {
+
+    public static RealmRepresentation exportRealm(KeycloakSession session, RealmModel realm, boolean includeUsers) {
+        RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
+
+        // Audit
+        rep.setAuditEnabled(realm.isAuditEnabled());
+        if (realm.getAuditExpiration() != 0) {
+            rep.setAuditExpiration(realm.getAuditExpiration());
+        }
+
+        if (realm.getAuditListeners() != null) {
+            rep.setAuditListeners(new LinkedList<String>(realm.getAuditListeners()));
+        }
+
+        // Applications
+        List<ApplicationModel> applications = realm.getApplications();
+        List<ApplicationRepresentation> appReps = new ArrayList<ApplicationRepresentation>();
+        for (ApplicationModel app : applications) {
+            ApplicationRepresentation appRep = exportApplication(app);
+            appReps.add(appRep);
+        }
+        rep.setApplications(appReps);
+
+        // OAuth clients
+        List<OAuthClientModel> oauthClients = realm.getOAuthClients();
+        List<OAuthClientRepresentation> oauthClientReps = new ArrayList<OAuthClientRepresentation>();
+        for (OAuthClientModel oauthClient : oauthClients) {
+            OAuthClientRepresentation clientRep = ModelToRepresentation.toRepresentation(oauthClient);
+            oauthClientReps.add(clientRep);
+        }
+        rep.setOauthClients(oauthClientReps);
+
+        // Roles
+        List<RoleRepresentation> realmRoleReps = null;
+        Map<String, List<RoleRepresentation>> appRolesReps = new HashMap<String, List<RoleRepresentation>>();
+
+        Set<RoleModel> realmRoles = realm.getRoles();
+        if (realmRoles != null && realmRoles.size() > 0) {
+            realmRoleReps = exportRoles(realmRoles);
+        }
+        for (ApplicationModel app : applications) {
+            Set<RoleModel> currentAppRoles = app.getRoles();
+            List<RoleRepresentation> currentAppRoleReps = exportRoles(currentAppRoles);
+            appRolesReps.put(app.getName(), currentAppRoleReps);
+        }
+
+        RolesRepresentation rolesRep = new RolesRepresentation();
+        if (realmRoleReps != null) {
+            rolesRep.setRealm(realmRoleReps);
+        }
+        if (appRolesReps.size() > 0) {
+            rolesRep.setApplication(appRolesReps);
+        }
+        rep.setRoles(rolesRep);
+
+        // Scopes
+        List<ClientModel> allClients = new ArrayList<ClientModel>(applications);
+        allClients.addAll(realm.getOAuthClients());
+        Map<String, List<ScopeMappingRepresentation>> appScopeReps = new HashMap<String, List<ScopeMappingRepresentation>>();
+
+        for (ClientModel client : allClients) {
+            Set<RoleModel> clientScopes = client.getScopeMappings();
+            ScopeMappingRepresentation scopeMappingRep = null;
+            for (RoleModel scope : clientScopes) {
+                if (scope.getContainer() instanceof RealmModel) {
+                    if (scopeMappingRep == null) {
+                        scopeMappingRep = rep.scopeMapping(client.getClientId());
+                    }
+                    scopeMappingRep.role(scope.getName());
+                } else {
+                    ApplicationModel app = (ApplicationModel)scope.getContainer();
+                    String appName = app.getName();
+                    List<ScopeMappingRepresentation> currentAppScopes = appScopeReps.get(appName);
+                    if (currentAppScopes == null) {
+                        currentAppScopes = new ArrayList<ScopeMappingRepresentation>();
+                        appScopeReps.put(appName, currentAppScopes);
+                    }
+
+                    ScopeMappingRepresentation currentClientScope = null;
+                    for (ScopeMappingRepresentation scopeMapping : currentAppScopes) {
+                        if (scopeMapping.getClient().equals(client.getClientId())) {
+                            currentClientScope = scopeMapping;
+                            break;
+                        }
+                    }
+                    if (currentClientScope == null) {
+                        currentClientScope = new ScopeMappingRepresentation();
+                        currentClientScope.setClient(client.getClientId());
+                        currentAppScopes.add(currentClientScope);
+                    }
+                    currentClientScope.role(scope.getName());
+                }
+            }
+        }
+
+        if (appScopeReps.size() > 0) {
+            rep.setApplicationScopeMappings(appScopeReps);
+        }
+
+        // Finally users if needed
+        if (includeUsers) {
+            List<UserModel> allUsers = session.users().getUsers(realm);
+            List<UserRepresentation> users = new ArrayList<UserRepresentation>();
+            for (UserModel user : allUsers) {
+                UserRepresentation userRep = exportUser(session, realm, user);
+                users.add(userRep);
+            }
+
+            if (users.size() > 0) {
+                rep.setUsers(users);
+            }
+        }
+
+        return rep;
+    }
+
+    /**
+     * Full export of application including claims and secret
+     * @param app
+     * @return full ApplicationRepresentation
+     */
+    public static ApplicationRepresentation exportApplication(ApplicationModel app) {
+        ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app);
+
+        appRep.setSecret(app.getSecret());
+        ClaimRepresentation claimRep = ModelToRepresentation.toRepresentation((ClientModel)app);
+        appRep.setClaims(claimRep);
+        return appRep;
+    }
+
+    public static List<RoleRepresentation> exportRoles(Collection<RoleModel> roles) {
+        List<RoleRepresentation> roleReps = new ArrayList<RoleRepresentation>();
+
+        for (RoleModel role : roles) {
+            RoleRepresentation roleRep = exportRole(role);
+            roleReps.add(roleRep);
+        }
+        return roleReps;
+    }
+
+    public static List<String> getRoleNames(Collection<RoleModel> roles) {
+        List<String> roleNames = new ArrayList<String>();
+        for (RoleModel role : roles) {
+            roleNames.add(role.getName());
+        }
+        return roleNames;
+    }
+
+    /**
+     * Full export of role including composite roles
+     * @param role
+     * @return RoleRepresentation with all stuff filled (including composite roles)
+     */
+    public static RoleRepresentation exportRole(RoleModel role) {
+        RoleRepresentation roleRep = ModelToRepresentation.toRepresentation(role);
+
+        Set<RoleModel> composites = role.getComposites();
+        if (composites != null && composites.size() > 0) {
+            Set<String> compositeRealmRoles = null;
+            Map<String, List<String>> compositeAppRoles = null;
+
+            for (RoleModel composite : composites) {
+                RoleContainerModel crContainer = composite.getContainer();
+                if (crContainer instanceof RealmModel) {
+
+                    if (compositeRealmRoles == null) {
+                        compositeRealmRoles = new HashSet<String>();
+                    }
+                    compositeRealmRoles.add(composite.getName());
+                } else {
+                    if (compositeAppRoles == null) {
+                        compositeAppRoles = new HashMap<String, List<String>>();
+                    }
+
+                    ApplicationModel app = (ApplicationModel)crContainer;
+                    String appName = app.getName();
+                    List<String> currentAppComposites = compositeAppRoles.get(appName);
+                    if (currentAppComposites == null) {
+                        currentAppComposites = new ArrayList<String>();
+                        compositeAppRoles.put(appName, currentAppComposites);
+                    }
+                    currentAppComposites.add(composite.getName());
+                }
+            }
+
+            RoleRepresentation.Composites compRep = new RoleRepresentation.Composites();
+            if (compositeRealmRoles != null) {
+                compRep.setRealm(compositeRealmRoles);
+            }
+            if (compositeAppRoles != null) {
+                compRep.setApplication(compositeAppRoles);
+            }
+
+            roleRep.setComposites(compRep);
+        }
+
+        return roleRep;
+    }
+
+    /**
+     * Full export of user (including role mappings and credentials)
+     *
+     * @param user
+     * @return fully exported user representation
+     */
+    public static UserRepresentation exportUser(KeycloakSession session, RealmModel realm, UserModel user) {
+        UserRepresentation userRep = ModelToRepresentation.toRepresentation(user);
+
+        // AuthenticationLink
+        AuthenticationLinkModel authLink = user.getAuthenticationLink();
+        if (authLink != null) {
+            AuthenticationLinkRepresentation authLinkRepresentation = exportAuthLink(authLink);
+            userRep.setAuthenticationLink(authLinkRepresentation);
+        }
+
+        // Social links
+        Set<SocialLinkModel> socialLinks = session.users().getSocialLinks(user, realm);
+        List<SocialLinkRepresentation> socialLinkReps = new ArrayList<SocialLinkRepresentation>();
+        for (SocialLinkModel socialLink : socialLinks) {
+            SocialLinkRepresentation socialLinkRep = exportSocialLink(socialLink);
+            socialLinkReps.add(socialLinkRep);
+        }
+        if (socialLinkReps.size() > 0) {
+            userRep.setSocialLinks(socialLinkReps);
+        }
+
+        // Role mappings
+        Set<RoleModel> roles = user.getRoleMappings();
+        List<String> realmRoleNames = new ArrayList<String>();
+        Map<String, List<String>> appRoleNames = new HashMap<String, List<String>>();
+        for (RoleModel role : roles) {
+            if (role.getContainer() instanceof RealmModel) {
+                realmRoleNames.add(role.getName());
+            } else {
+                ApplicationModel app = (ApplicationModel)role.getContainer();
+                String appName = app.getName();
+                List<String> currentAppRoles = appRoleNames.get(appName);
+                if (currentAppRoles == null) {
+                    currentAppRoles = new ArrayList<String>();
+                    appRoleNames.put(appName, currentAppRoles);
+                }
+
+                currentAppRoles.add(role.getName());
+            }
+        }
+
+        if (realmRoleNames.size() > 0) {
+            userRep.setRealmRoles(realmRoleNames);
+        }
+        if (appRoleNames.size() > 0) {
+            userRep.setApplicationRoles(appRoleNames);
+        }
+
+        // Credentials
+        List<UserCredentialValueModel> creds = user.getCredentialsDirectly();
+        List<CredentialRepresentation> credReps = new ArrayList<CredentialRepresentation>();
+        for (UserCredentialValueModel cred : creds) {
+            CredentialRepresentation credRep = exportCredential(cred);
+            credReps.add(credRep);
+        }
+        userRep.setCredentials(credReps);
+
+        return userRep;
+    }
+
+    public static AuthenticationLinkRepresentation exportAuthLink(AuthenticationLinkModel authLinkModel) {
+        AuthenticationLinkRepresentation authLinkRep = new AuthenticationLinkRepresentation();
+        authLinkRep.setAuthProvider(authLinkModel.getAuthProvider());
+        authLinkRep.setAuthUserId(authLinkModel.getAuthUserId());
+        return authLinkRep;
+    }
+
+    public static SocialLinkRepresentation exportSocialLink(SocialLinkModel socialLink) {
+        SocialLinkRepresentation socialLinkRep = new SocialLinkRepresentation();
+        socialLinkRep.setSocialProvider(socialLink.getSocialProvider());
+        socialLinkRep.setSocialUserId(socialLink.getSocialUserId());
+        socialLinkRep.setSocialUsername(socialLink.getSocialUsername());
+        return socialLinkRep;
+    }
+
+    public static CredentialRepresentation exportCredential(UserCredentialValueModel userCred) {
+        CredentialRepresentation credRep = new CredentialRepresentation();
+        credRep.setType(userCred.getType());
+        credRep.setDevice(userCred.getDevice());
+        credRep.setHashedSaltedValue(userCred.getValue());
+        credRep.setSalt(Base64.encodeBytes(userCred.getSalt()));
+        credRep.setHashIterations(userCred.getHashIterations());
+        return credRep;
+    }
+
+    // Streaming API
+
+    public static void exportUsersToStream(KeycloakSession session, RealmModel realm, List<UserModel> usersToExport, ObjectMapper mapper, OutputStream os) throws IOException {
+        JsonFactory factory = mapper.getJsonFactory();
+        JsonGenerator generator = factory.createJsonGenerator(os, JsonEncoding.UTF8);
+        try {
+            if (mapper.isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {
+                generator.useDefaultPrettyPrinter();
+            }
+            generator.writeStartObject();
+            generator.writeStringField("realm", realm.getName());
+            // generator.writeStringField("strategy", strategy.toString());
+            generator.writeFieldName("users");
+            generator.writeStartArray();
+
+            for (UserModel user : usersToExport) {
+                UserRepresentation userRep = ExportUtils.exportUser(session, realm, user);
+                generator.writeObject(userRep);
+            }
+
+            generator.writeEndArray();
+            generator.writeEndObject();
+        } finally {
+            generator.close();
+        }
+    }
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
new file mode 100755
index 0000000..6487a01
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
@@ -0,0 +1,211 @@
+package org.keycloak.exportimport.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.jackson.JsonEncoding;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.io.SerializedString;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.jboss.logging.Logger;
+import org.keycloak.Config;
+import org.keycloak.exportimport.Strategy;
+import org.keycloak.models.AdminRoles;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ImportUtils {
+
+    private static final Logger logger = Logger.getLogger(ImportUtils.class);
+
+    /**
+     * Fully import realm from representation, save it to model and return model of newly created realm
+     *
+     * @param session
+     * @param rep
+     * @param strategy specifies whether to overwrite or ignore existing realm or user entries
+     * @return newly imported realm (or existing realm if ignoreExisting is true and realm of this name already exists)
+     */
+    public static RealmModel importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy) {
+        String realmName = rep.getRealm();
+        ModelProvider model = session.model();
+        RealmModel realm = model.getRealmByName(realmName);
+
+        if (realm != null) {
+            if (strategy == Strategy.IGNORE_EXISTING) {
+                logger.infof("Realm '%s' already exists. Import skipped", realmName);
+                return realm;
+            } else {
+                logger.infof("Realm '%s' already exists. Removing it before import", realmName);
+                if (Config.getAdminRealm().equals(realm.getId())) {
+                    realm.setMasterAdminApp(null);
+                }
+                model.removeRealm(realm.getId());
+            }
+        }
+
+        realm = rep.getId() != null ? model.createRealm(rep.getId(), realmName) : model.createRealm(realmName);
+
+        RepresentationToModel.importRealm(session, rep, realm);
+
+        refreshMasterAdminApps(model, realm);
+
+        logger.infof("Realm '%s' imported", realmName);
+        return realm;
+    }
+
+    private static void refreshMasterAdminApps(ModelProvider model, RealmModel realm) {
+        String adminRealmId = Config.getAdminRealm();
+        if (adminRealmId.equals(realm.getId())) {
+            // We just imported master realm. All 'masterAdminApps' need to be refreshed
+            RealmModel adminRealm = realm;
+            for (RealmModel currentRealm : model.getRealms()) {
+                ApplicationModel masterApp = adminRealm.getApplicationByName(ExportImportUtils.getMasterRealmAdminApplicationName(currentRealm));
+                if (masterApp != null) {
+                    currentRealm.setMasterAdminApp(masterApp);
+                }  else {
+                    setupMasterAdminManagement(model, currentRealm);
+                }
+            }
+        } else {
+            // Need to refresh masterApp for current realm
+            RealmModel adminRealm = model.getRealm(adminRealmId);
+            ApplicationModel masterApp = adminRealm.getApplicationByName(ExportImportUtils.getMasterRealmAdminApplicationName(realm));
+            if (masterApp != null) {
+                realm.setMasterAdminApp(masterApp);
+            }  else {
+                setupMasterAdminManagement(model, realm);
+            }
+        }
+    }
+
+    // TODO: We need method here, so we are able to refresh masterAdmin applications after import. Should be RealmManager moved to model/api instead?
+    public static void setupMasterAdminManagement(ModelProvider model, RealmModel realm) {
+        RealmModel adminRealm;
+        RoleModel adminRole;
+
+        if (realm.getName().equals(Config.getAdminRealm())) {
+            adminRealm = realm;
+
+            adminRole = realm.addRole(AdminRoles.ADMIN);
+
+            RoleModel createRealmRole = realm.addRole(AdminRoles.CREATE_REALM);
+            adminRole.addCompositeRole(createRealmRole);
+        } else {
+            adminRealm = model.getRealmByName(Config.getAdminRealm());
+            adminRole = adminRealm.getRole(AdminRoles.ADMIN);
+        }
+
+        ApplicationModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, ExportImportUtils.getMasterRealmAdminApplicationName(realm));
+        realmAdminApp.setBearerOnly(true);
+        realm.setMasterAdminApp(realmAdminApp);
+
+        for (String r : AdminRoles.ALL_REALM_ROLES) {
+            RoleModel role = realmAdminApp.addRole(r);
+            adminRole.addCompositeRole(role);
+        }
+    }
+
+
+    /**
+     * Fully import realm (or more realms from particular stream)
+     *
+     * @param session
+     * @param mapper
+     * @param is
+     * @param strategy
+     * @throws IOException
+     */
+    public static void importFromStream(KeycloakSession session, ObjectMapper mapper, InputStream is, Strategy strategy) throws IOException {
+        JsonFactory factory = mapper.getJsonFactory();
+        JsonParser parser = factory.createJsonParser(is);
+        try {
+            parser.nextToken();
+
+            if (parser.getCurrentToken() == JsonToken.START_ARRAY) {
+                // Case with more realms in stream
+                parser.nextToken();
+                while (parser.getCurrentToken() == JsonToken.START_OBJECT) {
+                    RealmRepresentation realmRep = parser.readValueAs(RealmRepresentation.class);
+                    parser.nextToken();
+                    importRealm(session, realmRep, strategy);
+                }
+            } else if (parser.getCurrentToken() == JsonToken.START_OBJECT) {
+                // Case with single realm in stream
+                RealmRepresentation realmRep = parser.readValueAs(RealmRepresentation.class);
+                importRealm(session, realmRep, strategy);
+            }
+        } finally {
+            parser.close();
+        }
+    }
+
+    // Assuming that it's invoked inside transaction
+    public static void importUsersFromStream(KeycloakSession session, String realmName, ObjectMapper mapper, InputStream is) throws IOException {
+        ModelProvider model = session.model();
+        JsonFactory factory = mapper.getJsonFactory();
+        JsonParser parser = factory.createJsonParser(is);
+        try {
+            parser.nextToken();
+
+            while (parser.nextToken() == JsonToken.FIELD_NAME) {
+                if ("realm".equals(parser.getText())) {
+                    parser.nextToken();
+                    String currRealmName = parser.getText();
+                    if (!currRealmName.equals(realmName)) {
+                        throw new IllegalStateException("Trying to import users into invalid realm. Realm name: " + realmName + ", Expected realm name: " + realmName);
+                    }
+                } else if ("users".equals(parser.getText())) {
+                    parser.nextToken();
+
+                    if (parser.getCurrentToken() == JsonToken.START_ARRAY) {
+                        parser.nextToken();
+                    }
+
+                    // TODO: support for more transactions per single users file (if needed)
+                    List<UserRepresentation> userReps = new ArrayList<UserRepresentation>();
+                    while (parser.getCurrentToken() == JsonToken.START_OBJECT) {
+                        UserRepresentation user = parser.readValueAs(UserRepresentation.class);
+                        userReps.add(user);
+                        parser.nextToken();
+                    }
+
+                    importUsers(session, model, realmName, userReps);
+
+                    if (parser.getCurrentToken() == JsonToken.END_ARRAY) {
+                        parser.nextToken();
+                    }
+                }
+            }
+        } finally {
+            parser.close();
+        }
+    }
+
+    private static void importUsers(KeycloakSession session, ModelProvider model, String realmName, List<UserRepresentation> userReps) {
+        RealmModel realm = model.getRealmByName(realmName);
+        Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
+        for (UserRepresentation user : userReps) {
+            RepresentationToModel.createUser(session, realm, user, apps);
+        }
+    }
+
+}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
new file mode 100755
index 0000000..19134ab
--- /dev/null
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
@@ -0,0 +1,116 @@
+package org.keycloak.exportimport.util;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.jboss.logging.Logger;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ExportProvider;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public abstract class MultipleStepsExportProvider implements ExportProvider {
+
+    protected final Logger logger = Logger.getLogger(getClass());
+
+    @Override
+    public void exportModel(KeycloakSessionFactory factory) throws IOException {
+        final RealmsHolder holder = new RealmsHolder();
+
+        // Import users into same file with realm
+        ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+            @Override
+            public void run(KeycloakSession session) {
+                List<RealmModel> realms = session.model().getRealms();
+                holder.realms = realms;
+            }
+
+        });
+
+        for (RealmModel realm : holder.realms) {
+            exportRealm(factory, realm.getName());
+        }
+    }
+
+    @Override
+    public void exportRealm(KeycloakSessionFactory factory, final String realmName) throws IOException {
+        final int usersPerFile = ExportImportConfig.getUsersPerFile();
+        final UsersHolder usersHolder = new UsersHolder();
+        final boolean exportUsersIntoSameFile = usersPerFile < 0;
+
+        ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+            @Override
+            public void run(KeycloakSession session) throws IOException {
+                RealmModel realm = session.model().getRealmByName(realmName);
+                RealmRepresentation rep = ExportUtils.exportRealm(session, realm, exportUsersIntoSameFile);
+                writeRealm(realmName + "-realm.json", rep);
+                logger.info("Realm '" + realmName + "' - data exported");
+
+                // Count total number of users
+                if (!exportUsersIntoSameFile) {
+                    // TODO: getUsersCount method on model
+                    usersHolder.totalCount = session.users().getUsers(realm).size();
+                }
+            }
+
+        });
+
+        if (!exportUsersIntoSameFile) {
+
+            usersHolder.currentPageStart = 0;
+
+            // usersPerFile==0 means exporting all users into single file (but separate to realm)
+            final int countPerPage = usersPerFile == 0 ? usersHolder.totalCount : usersPerFile;
+
+            while (usersHolder.currentPageStart < usersHolder.totalCount) {
+                if (usersHolder.currentPageStart + countPerPage < usersHolder.totalCount) {
+                    usersHolder.currentPageEnd = usersHolder.currentPageStart + countPerPage;
+                } else {
+                    usersHolder.currentPageEnd = usersHolder.totalCount;
+                }
+
+                ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+                    @Override
+                    public void run(KeycloakSession session) throws IOException {
+                        RealmModel realm = session.model().getRealmByName(realmName);
+                        // TODO: pagination
+                        List<UserModel> users = session.users().getUsers(realm);
+                        usersHolder.users = users.subList(usersHolder.currentPageStart, usersHolder.currentPageEnd);
+
+                        writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
+
+                        logger.info("Users " + usersHolder.currentPageStart + "-" + usersHolder.currentPageEnd + " exported");
+                    }
+
+                });
+
+                usersHolder.currentPageStart = usersHolder.currentPageEnd;
+            }
+        }
+    }
+
+    protected abstract void writeRealm(String fileName, RealmRepresentation rep) throws IOException;
+
+    protected abstract void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException;
+
+    public static class RealmsHolder {
+        List<RealmModel> realms;
+
+    }
+
+    public static class UsersHolder {
+        List<UserModel> users;
+        int totalCount;
+        int currentPageStart;
+        int currentPageEnd;
+    }
+}
diff --git a/export-import/export-import-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/export-import/export-import-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
new file mode 100644
index 0000000..9302943
--- /dev/null
+++ b/export-import/export-import-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -0,0 +1,2 @@
+org.keycloak.exportimport.ExportSpi
+org.keycloak.exportimport.ImportSpi
\ No newline at end of file
diff --git a/export-import/export-import-dir/pom.xml b/export-import/export-import-dir/pom.xml
new file mode 100644
index 0000000..4cd8dc1
--- /dev/null
+++ b/export-import/export-import-dir/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <artifactId>keycloak-export-import-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.0-beta-4-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-export-import-dir</artifactId>
+    <name>Keycloak Export Import To Directory</name>
+    <description/>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java b/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
new file mode 100644
index 0000000..ef29af9
--- /dev/null
+++ b/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
@@ -0,0 +1,107 @@
+package org.keycloak.exportimport.dir;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+
+import org.jboss.logging.Logger;
+import org.keycloak.exportimport.ImportProvider;
+import org.keycloak.exportimport.Strategy;
+import org.keycloak.exportimport.util.ExportImportJob;
+import org.keycloak.exportimport.util.ExportImportUtils;
+import org.keycloak.exportimport.util.ImportUtils;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.util.JsonSerialization;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class DirImportProvider implements ImportProvider {
+
+    private static final Logger logger = Logger.getLogger(DirImportProvider.class);
+
+    private final File rootDirectory;
+
+    public DirImportProvider() {
+        // Determine system tmp directory
+        String tempDir = System.getProperty("java.io.tmpdir");
+
+        // Delete and recreate directory inside tmp
+        this.rootDirectory = new File(tempDir + "/keycloak-export");
+        if (!this.rootDirectory .exists()) {
+            throw new IllegalStateException("Directory " + this.rootDirectory + " doesn't exists");
+        }
+
+        logger.infof("Importing from directory %s", this.rootDirectory.getAbsolutePath());
+    }
+
+    public DirImportProvider(File rootDirectory) {
+        this.rootDirectory = rootDirectory;
+
+        logger.infof("Importing from directory %s", this.rootDirectory.getAbsolutePath());
+    }
+
+    @Override
+    public void importModel(KeycloakSessionFactory factory, Strategy strategy) throws IOException {
+        File[] realmFiles = this.rootDirectory.listFiles(new FilenameFilter() {
+
+            @Override
+            public boolean accept(File dir, String name) {
+                return (name.endsWith("-realm.json"));
+            }
+        });
+
+        for (File file : realmFiles) {
+            String fileName = file.getName();
+
+            // Parse "foo" from "foo-realm.json"
+            String realmName = fileName.substring(0, fileName.length() - 11);
+            importRealm(factory, realmName, strategy);
+        }
+    }
+
+    @Override
+    public void importRealm(KeycloakSessionFactory factory, final String realmName, final Strategy strategy) throws IOException {
+        File realmFile = new File(this.rootDirectory + File.separator + realmName + "-realm.json");
+        File[] userFiles = this.rootDirectory.listFiles(new FilenameFilter() {
+
+            @Override
+            public boolean accept(File dir, String name) {
+                return (name.startsWith(realmName)) && (name.endsWith(".json")) && (name.substring(realmName.length()).contains("-users-") );
+            }
+        });
+
+        // Import realm first
+        FileInputStream is = new FileInputStream(realmFile);
+        final RealmRepresentation realmRep = JsonSerialization.readValue(is, RealmRepresentation.class);
+
+        ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+            @Override
+            public void run(KeycloakSession session) throws IOException {
+                ImportUtils.importRealm(session, realmRep, strategy);
+            }
+
+        });
+
+        // Import users
+        for (File userFile : userFiles) {
+            final FileInputStream fis = new FileInputStream(userFile);
+            ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+                @Override
+                public void run(KeycloakSession session) throws IOException {
+                    ImportUtils.importUsersFromStream(session, realmName, JsonSerialization.mapper, fis);
+                }
+            });
+        }
+    }
+
+    @Override
+    public void close() {
+
+    }
+}
diff --git a/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirImportProviderFactory.java b/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirImportProviderFactory.java
new file mode 100644
index 0000000..3e39a77
--- /dev/null
+++ b/export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirImportProviderFactory.java
@@ -0,0 +1,34 @@
+package org.keycloak.exportimport.dir;
+
+import java.io.File;
+
+import org.keycloak.Config;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ImportProvider;
+import org.keycloak.exportimport.ImportProviderFactory;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class DirImportProviderFactory implements ImportProviderFactory {
+
+    @Override
+    public ImportProvider create(KeycloakSession session) {
+        String dir = ExportImportConfig.getDir();
+        return dir!=null ? new DirImportProvider(new File(dir)) : new DirImportProvider();
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return DirExportProviderFactory.PROVIDER_ID;
+    }
+}
diff --git a/export-import/export-import-dir/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory b/export-import/export-import-dir/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory
new file mode 100644
index 0000000..8a8fea4
--- /dev/null
+++ b/export-import/export-import-dir/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory
@@ -0,0 +1 @@
+org.keycloak.exportimport.dir.DirExportProviderFactory
\ No newline at end of file
diff --git a/export-import/export-import-dir/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory b/export-import/export-import-dir/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory
new file mode 100644
index 0000000..ba9874e
--- /dev/null
+++ b/export-import/export-import-dir/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory
@@ -0,0 +1 @@
+org.keycloak.exportimport.dir.DirImportProviderFactory
\ No newline at end of file
diff --git a/export-import/export-import-single-file/pom.xml b/export-import/export-import-single-file/pom.xml
new file mode 100644
index 0000000..25d65c0
--- /dev/null
+++ b/export-import/export-import-single-file/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <artifactId>keycloak-export-import-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.0-beta-4-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-export-import-single-file</artifactId>
+    <name>Keycloak Export Import To Single File</name>
+    <description/>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
new file mode 100755
index 0000000..724152b
--- /dev/null
+++ b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
@@ -0,0 +1,85 @@
+package org.keycloak.exportimport.singlefile;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.jboss.logging.Logger;
+import org.keycloak.exportimport.ExportProvider;
+import org.keycloak.exportimport.util.ExportImportJob;
+import org.keycloak.exportimport.util.ExportImportUtils;
+import org.keycloak.exportimport.util.ExportUtils;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.util.JsonSerialization;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SingleFileExportProvider implements ExportProvider {
+
+    private static final Logger logger = Logger.getLogger(SingleFileExportProvider.class);
+
+    private File file;
+
+    public SingleFileExportProvider(File file) {
+        this.file = file;
+    }
+
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    @Override
+    public void exportModel(KeycloakSessionFactory factory) throws IOException {
+        logger.infof("Exporting model into file %s", this.file.getAbsolutePath());
+        ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+            @Override
+            public void run(KeycloakSession session) throws IOException {
+                List<RealmModel> realms = session.model().getRealms();
+                List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
+                for (RealmModel realm : realms) {
+                    reps.add(ExportUtils.exportRealm(session, realm, true));
+                }
+
+                writeToFile(reps);
+            }
+
+        });
+
+    }
+
+    @Override
+    public void exportRealm(KeycloakSessionFactory factory, final String realmName) throws IOException {
+        logger.infof("Exporting realm '%s' into file %s", realmName, this.file.getAbsolutePath());
+        ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+            @Override
+            public void run(KeycloakSession session) throws IOException {
+                RealmModel realm = session.model().getRealmByName(realmName);
+                RealmRepresentation realmRep = ExportUtils.exportRealm(session, realm, true);
+                writeToFile(realmRep);
+            }
+
+        });
+    }
+
+    @Override
+    public void close() {
+    }
+
+    private ObjectMapper getObjectMapper() {
+        return JsonSerialization.prettyMapper;
+    }
+
+    private void writeToFile(Object reps) throws IOException {
+        FileOutputStream stream = new FileOutputStream(this.file);
+        getObjectMapper().writeValue(stream, reps);
+    }
+}
diff --git a/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProviderFactory.java b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProviderFactory.java
new file mode 100644
index 0000000..614c3ba
--- /dev/null
+++ b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProviderFactory.java
@@ -0,0 +1,36 @@
+package org.keycloak.exportimport.singlefile;
+
+import java.io.File;
+
+import org.keycloak.Config;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ExportProvider;
+import org.keycloak.exportimport.ExportProviderFactory;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SingleFileExportProviderFactory implements ExportProviderFactory {
+
+    public static final String PROVIDER_ID = "singleFile";
+
+    @Override
+    public ExportProvider create(KeycloakSession session) {
+        String fileName = ExportImportConfig.getFile();
+        return new SingleFileExportProvider(new File(fileName));
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+}
diff --git a/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProvider.java b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProvider.java
new file mode 100644
index 0000000..07e8cb2
--- /dev/null
+++ b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProvider.java
@@ -0,0 +1,59 @@
+package org.keycloak.exportimport.singlefile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.logging.Logger;
+import org.keycloak.exportimport.ImportProvider;
+import org.keycloak.exportimport.Strategy;
+import org.keycloak.exportimport.util.ExportImportJob;
+import org.keycloak.exportimport.util.ExportImportUtils;
+import org.keycloak.exportimport.util.ExportUtils;
+import org.keycloak.exportimport.util.ImportUtils;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.util.JsonSerialization;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SingleFileImportProvider implements ImportProvider {
+
+    private static final Logger logger = Logger.getLogger(SingleFileImportProvider.class);
+
+    private File file;
+
+    public SingleFileImportProvider(File file) {
+        this.file = file;
+    }
+
+    @Override
+    public void importModel(KeycloakSessionFactory factory, final Strategy strategy) throws IOException {
+        logger.infof("Full importing from file %s", this.file.getAbsolutePath());
+        ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+            @Override
+            public void run(KeycloakSession session) throws IOException {
+                FileInputStream is = new FileInputStream(file);
+                ImportUtils.importFromStream(session, JsonSerialization.mapper, is, strategy);
+            }
+
+        });
+    }
+
+    @Override
+    public void importRealm(KeycloakSessionFactory factory, String realmName, Strategy strategy) throws IOException {
+        // TODO: import just that single realm in case that file contains many realms?
+        importModel(factory, strategy);
+    }
+
+    @Override
+    public void close() {
+
+    }
+}
diff --git a/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java
new file mode 100644
index 0000000..6e3e732
--- /dev/null
+++ b/export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileImportProviderFactory.java
@@ -0,0 +1,34 @@
+package org.keycloak.exportimport.singlefile;
+
+import java.io.File;
+
+import org.keycloak.Config;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ImportProvider;
+import org.keycloak.exportimport.ImportProviderFactory;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class SingleFileImportProviderFactory implements ImportProviderFactory {
+
+    @Override
+    public ImportProvider create(KeycloakSession session) {
+        String fileName = ExportImportConfig.getFile();
+        return new SingleFileImportProvider(new File(fileName));
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return SingleFileExportProviderFactory.PROVIDER_ID;
+    }
+}
diff --git a/export-import/export-import-single-file/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory b/export-import/export-import-single-file/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory
new file mode 100644
index 0000000..82a1faf
--- /dev/null
+++ b/export-import/export-import-single-file/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory
@@ -0,0 +1 @@
+org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory
\ No newline at end of file
diff --git a/export-import/export-import-single-file/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory b/export-import/export-import-single-file/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory
new file mode 100644
index 0000000..d2192b6
--- /dev/null
+++ b/export-import/export-import-single-file/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory
@@ -0,0 +1 @@
+org.keycloak.exportimport.singlefile.SingleFileImportProviderFactory
\ No newline at end of file
diff --git a/export-import/export-import-zip/pom.xml b/export-import/export-import-zip/pom.xml
new file mode 100644
index 0000000..7738f85
--- /dev/null
+++ b/export-import/export-import-zip/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <artifactId>keycloak-export-import-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.0-beta-4-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-export-import-zip</artifactId>
+    <name>Keycloak Export Import To Encrypted ZIP</name>
+    <description/>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>de.idyl</groupId>
+            <artifactId>winzipaes</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProviderFactory.java b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProviderFactory.java
new file mode 100644
index 0000000..03f0147
--- /dev/null
+++ b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProviderFactory.java
@@ -0,0 +1,44 @@
+package org.keycloak.exportimport.zip;
+
+import java.io.File;
+
+import org.keycloak.Config;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ExportProvider;
+import org.keycloak.exportimport.ExportProviderFactory;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ZipExportProviderFactory implements ExportProviderFactory {
+
+
+    public static final String PROVIDER_ID = "zip";
+
+    @Override
+    public ExportProvider create(KeycloakSession session) {
+        String fileName = ExportImportConfig.getZipFile();
+        String password = ExportImportConfig.getZipPassword();
+        if (fileName == null) {
+            throw new IllegalArgumentException("ZIP file for export not provided");
+        }
+        if (password == null) {
+            throw new IllegalArgumentException("Password for encrypting ZIP not provided");
+        }
+        return new ZipExportProvider(new File(fileName), password);
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return PROVIDER_ID;
+    }
+}
diff --git a/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipImportProvider.java b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipImportProvider.java
new file mode 100644
index 0000000..20d3dc7
--- /dev/null
+++ b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipImportProvider.java
@@ -0,0 +1,110 @@
+package org.keycloak.exportimport.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.DataFormatException;
+
+import de.idyl.winzipaes.AesZipFileDecrypter;
+import de.idyl.winzipaes.impl.AESDecrypter;
+import de.idyl.winzipaes.impl.AESDecrypterBC;
+import de.idyl.winzipaes.impl.ExtZipEntry;
+import org.jboss.logging.Logger;
+import org.keycloak.exportimport.ImportProvider;
+import org.keycloak.exportimport.Strategy;
+import org.keycloak.exportimport.util.ExportImportJob;
+import org.keycloak.exportimport.util.ExportImportUtils;
+import org.keycloak.exportimport.util.ImportUtils;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.util.JsonSerialization;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ZipImportProvider implements ImportProvider {
+
+    private static final Logger logger = Logger.getLogger(ZipImportProvider.class);
+
+    private final AesZipFileDecrypter decrypter;
+    private final String password;
+
+    public ZipImportProvider(File zipFile, String password) {
+        try {
+            if (!zipFile.exists()) {
+                throw new IllegalStateException("File " + zipFile.getAbsolutePath() + " doesn't exists");
+            }
+
+            AESDecrypter decrypter = new AESDecrypterBC();
+            this.decrypter = new AesZipFileDecrypter(zipFile, decrypter);
+            this.password = password;
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+        logger.infof("Importing from ZIP file %s", zipFile.getAbsolutePath());
+    }
+
+    @Override
+    public void importModel(KeycloakSessionFactory factory, Strategy strategy) throws IOException {
+        for (ExtZipEntry entry : this.decrypter.getEntryList()) {
+            String entryName = entry.getName();
+            if (entryName.endsWith("-realm.json")) {
+                // Parse "foo" from "foo-realm.json"
+                String realmName = entryName.substring(0, entryName.length() - 11);
+                importRealm(factory, realmName, strategy);
+            }
+        }
+    }
+
+    @Override
+    public void importRealm(KeycloakSessionFactory factory, final String realmName, final Strategy strategy) throws IOException {
+        try {
+            // Import realm first
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            this.decrypter.extractEntry(this.decrypter.getEntry(realmName + "-realm.json"), bos, this.password);
+            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+            final RealmRepresentation realmRep = JsonSerialization.mapper.readValue(bis, RealmRepresentation.class);
+
+            ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+                @Override
+                public void run(KeycloakSession session) throws IOException {
+                    ImportUtils.importRealm(session, realmRep, strategy);
+                }
+
+            });
+
+
+            // Import users
+            for (ExtZipEntry entry : this.decrypter.getEntryList()) {
+                String name = entry.getName();
+                if ( (name.startsWith(realmName)) && (name.endsWith(".json")) && (name.substring(realmName.length()).contains("-users-")) ) {
+                    bos = new ByteArrayOutputStream();
+                    this.decrypter.extractEntry(entry, bos, this.password);
+                    final ByteArrayInputStream bis2 = new ByteArrayInputStream(bos.toByteArray());
+
+                    ExportImportUtils.runJobInTransaction(factory, new ExportImportJob() {
+
+                        @Override
+                        public void run(KeycloakSession session) throws IOException {
+                            ImportUtils.importUsersFromStream(session, realmName, JsonSerialization.mapper, bis2);
+                        }
+                    });
+                }
+            }
+        } catch (DataFormatException dfe) {
+            throw new RuntimeException(dfe);
+        }
+    }
+
+    @Override
+    public void close() {
+        try {
+            this.decrypter.close();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+}
diff --git a/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipImportProviderFactory.java b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipImportProviderFactory.java
new file mode 100644
index 0000000..9127a8b
--- /dev/null
+++ b/export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipImportProviderFactory.java
@@ -0,0 +1,41 @@
+package org.keycloak.exportimport.zip;
+
+import java.io.File;
+
+import org.keycloak.Config;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ImportProvider;
+import org.keycloak.exportimport.ImportProviderFactory;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ZipImportProviderFactory implements ImportProviderFactory {
+
+    @Override
+    public ImportProvider create(KeycloakSession session) {
+        String fileName = ExportImportConfig.getZipFile();
+        String password = ExportImportConfig.getZipPassword();
+        if (fileName == null) {
+            throw new IllegalArgumentException("ZIP file for import not provided");
+        }
+        if (password == null) {
+            throw new IllegalArgumentException("Password for decrypting ZIP not provided");
+        }
+        return new ZipImportProvider(new File(fileName), password);
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return ZipExportProviderFactory.PROVIDER_ID;
+    }
+}
diff --git a/export-import/export-import-zip/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory b/export-import/export-import-zip/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory
new file mode 100644
index 0000000..dce02f1
--- /dev/null
+++ b/export-import/export-import-zip/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportProviderFactory
@@ -0,0 +1 @@
+org.keycloak.exportimport.zip.ZipExportProviderFactory
\ No newline at end of file
diff --git a/export-import/export-import-zip/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory b/export-import/export-import-zip/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory
new file mode 100644
index 0000000..b88f372
--- /dev/null
+++ b/export-import/export-import-zip/src/main/resources/META-INF/services/org.keycloak.exportimport.ImportProviderFactory
@@ -0,0 +1 @@
+org.keycloak.exportimport.zip.ZipImportProviderFactory
\ No newline at end of file
diff --git a/export-import/pom.xml b/export-import/pom.xml
index b9a5a4d..72468fa 100755
--- a/export-import/pom.xml
+++ b/export-import/pom.xml
@@ -16,7 +16,9 @@
 
     <modules>
         <module>export-import-api</module>
-        <module>export-import-impl</module>
+        <module>export-import-dir</module>
+        <module>export-import-single-file</module>
+        <module>export-import-zip</module>
     </modules>
 
 </project>
diff --git a/model/api/pom.xml b/model/api/pom.xml
index f72d856..d0af4dc 100755
--- a/model/api/pom.xml
+++ b/model/api/pom.xml
@@ -31,6 +31,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 00e2b9b..33ee8e2 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -1,6 +1,5 @@
 package org.keycloak.models;
 
-import java.util.List;
 import java.util.Set;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java b/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
old mode 100644
new mode 100755
index 2297eed..6db19a7
--- a/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
@@ -1,11 +1,11 @@
 package org.keycloak.models.entities;
 
+import org.keycloak.models.UserModel;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import org.keycloak.models.UserModel;
-
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
index 628c1a6..af3dff0 100755
--- a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
+++ b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
@@ -2,8 +2,6 @@ package org.keycloak.models;
 
 import org.keycloak.provider.Provider;
 
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/ModelProvider.java b/model/api/src/main/java/org/keycloak/models/ModelProvider.java
index 2c1ad56..a39fedb 100755
--- a/model/api/src/main/java/org/keycloak/models/ModelProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/ModelProvider.java
@@ -3,8 +3,6 @@ package org.keycloak.models;
 import org.keycloak.provider.Provider;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
index 2cad371..f8d0000 100755
--- a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java
@@ -1,6 +1,5 @@
 package org.keycloak.models;
 
-import java.util.List;
 import java.util.Set;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java b/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java
index 0bfd293..6515ab0 100755
--- a/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java
@@ -1,8 +1,5 @@
 package org.keycloak.models;
 
-import java.util.List;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionModel.java b/model/api/src/main/java/org/keycloak/models/UserSessionModel.java
index ada5899..a0aa6a5 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSessionModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionModel.java
@@ -1,7 +1,6 @@
 package org.keycloak.models;
 
 import java.util.List;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
index fa643b3..fb33ca1 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
@@ -3,8 +3,6 @@ package org.keycloak.models;
 import org.keycloak.provider.Provider;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index 5ad0a68..4a00ff9 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -1,20 +1,25 @@
 package org.keycloak.models.utils;
 
+import org.bouncycastle.openssl.PEMWriter;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.util.PemUtils;
+
 import java.io.IOException;
 import java.io.StringWriter;
 import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.bouncycastle.openssl.PEMWriter;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.util.PemUtils;
 
 /**
  * Set of helper methods, which are useful in various model implementations.
@@ -66,6 +71,30 @@ public final class KeycloakModelUtils {
         return PemUtils.removeBeginEnd(s);
     }
 
+    public static void generateRealmKeys(RealmModel realm) {
+        KeyPair keyPair = null;
+        try {
+            keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+        realm.setPrivateKey(keyPair.getPrivate());
+        realm.setPublicKey(keyPair.getPublic());
+    }
+
+    public static UserCredentialModel generateSecret(ClientModel app) {
+        UserCredentialModel secret = UserCredentialModel.generateSecret();
+        app.setSecret(secret.getValue());
+        return secret;
+    }
+
+    public static ApplicationModel createApplication(RealmModel realm, String name) {
+        ApplicationModel app = realm.addApplication(name);
+        generateSecret(app);
+
+        return app;
+    }
+
     /**
      * Deep search if given role is descendant of composite role
      *
diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
old mode 100644
new mode 100755
index 3348d8b..fd7c06b
--- a/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
@@ -1,7 +1,5 @@
 package org.keycloak.models.utils.reflection;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java b/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
old mode 100644
new mode 100755
index 2d2c41d..604b83b
--- a/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
@@ -1,6 +1,5 @@
 package org.keycloak.models.utils.reflection;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 /**
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
new file mode 100755
index 0000000..35fe9c9
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -0,0 +1,672 @@
+package org.keycloak.models.utils;
+
+import net.iharder.Base64;
+import org.jboss.logging.Logger;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.AuthenticationLinkModel;
+import org.keycloak.models.AuthenticationProviderModel;
+import org.keycloak.models.ClaimMask;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserCredentialValueModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
+import org.keycloak.representations.idm.AuthenticationProviderRepresentation;
+import org.keycloak.representations.idm.ClaimRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.OAuthClientRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.ScopeMappingRepresentation;
+import org.keycloak.representations.idm.SocialLinkRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class RepresentationToModel {
+
+    private static Logger logger = Logger.getLogger(RepresentationToModel.class);
+
+    public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
+        newRealm.setName(rep.getRealm());
+        if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
+        if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
+        if (rep.isBruteForceProtected() != null) newRealm.setBruteForceProtected(rep.isBruteForceProtected());
+        if (rep.getMaxFailureWaitSeconds() != null) newRealm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
+        if (rep.getMinimumQuickLoginWaitSeconds() != null) newRealm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
+        if (rep.getWaitIncrementSeconds() != null) newRealm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
+        if (rep.getQuickLoginCheckMilliSeconds() != null) newRealm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
+        if (rep.getMaxDeltaTimeSeconds() != null) newRealm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
+        if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
+
+        if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
+
+        if (rep.getAccessTokenLifespan() != null) newRealm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
+        else newRealm.setAccessTokenLifespan(300);
+
+        if (rep.getSsoSessionIdleTimeout() != null) newRealm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
+        else newRealm.setSsoSessionIdleTimeout(600);
+        if (rep.getSsoSessionMaxLifespan() != null) newRealm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
+        else newRealm.setSsoSessionMaxLifespan(36000);
+
+        if (rep.getAccessCodeLifespan() != null) newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
+        else newRealm.setAccessCodeLifespan(60);
+
+        if (rep.getAccessCodeLifespanUserAction() != null)
+            newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
+        else newRealm.setAccessCodeLifespanUserAction(300);
+
+        if (rep.isSslNotRequired() != null) newRealm.setSslNotRequired(rep.isSslNotRequired());
+        if (rep.isPasswordCredentialGrantAllowed() != null) newRealm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
+        if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
+        if (rep.isRememberMe() != null) newRealm.setRememberMe(rep.isRememberMe());
+        if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail());
+        if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
+        if (rep.isUpdateProfileOnInitialSocialLogin() != null)
+            newRealm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
+        if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
+            KeycloakModelUtils.generateRealmKeys(newRealm);
+        } else {
+            newRealm.setPrivateKeyPem(rep.getPrivateKey());
+            newRealm.setPublicKeyPem(rep.getPublicKey());
+        }
+        if (rep.getLoginTheme() != null) newRealm.setLoginTheme(rep.getLoginTheme());
+        if (rep.getAccountTheme() != null) newRealm.setAccountTheme(rep.getAccountTheme());
+        if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAdminTheme());
+        if (rep.getEmailTheme() != null) newRealm.setEmailTheme(rep.getEmailTheme());
+
+        if (rep.getRequiredCredentials() != null) {
+            for (String requiredCred : rep.getRequiredCredentials()) {
+                addRequiredCredential(newRealm, requiredCred);
+            }
+        } else {
+            addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
+        }
+
+        if (rep.getPasswordPolicy() != null) newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
+
+        if (rep.getApplications() != null) {
+            Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
+        }
+
+        if (rep.getRoles() != null) {
+            if (rep.getRoles().getRealm() != null) { // realm roles
+                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+                    createRole(newRealm, roleRep);
+                }
+            }
+            if (rep.getRoles().getApplication() != null) {
+                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    if (app == null) {
+                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+                    }
+                    for (RoleRepresentation roleRep : entry.getValue()) {
+                        // Application role may already exists (for example if it is defaultRole)
+                        RoleModel role = app.getRole(roleRep.getName());
+                        if (role == null) {
+                            role = app.addRole(roleRep.getName());
+                        }
+                        role.setDescription(roleRep.getDescription());
+                    }
+                }
+            }
+            // now that all roles are created, re-iterate and set up composites
+            if (rep.getRoles().getRealm() != null) { // realm roles
+                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+                    RoleModel role = newRealm.getRole(roleRep.getName());
+                    addComposites(role, roleRep, newRealm);
+                }
+            }
+            if (rep.getRoles().getApplication() != null) {
+                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    if (app == null) {
+                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+                    }
+                    for (RoleRepresentation roleRep : entry.getValue()) {
+                        RoleModel role = app.getRole(roleRep.getName());
+                        addComposites(role, roleRep, newRealm);
+                    }
+                }
+            }
+        }
+
+
+        if (rep.getDefaultRoles() != null) {
+            for (String roleString : rep.getDefaultRoles()) {
+                newRealm.addDefaultRole(roleString.trim());
+            }
+        }
+
+        if (rep.getOauthClients() != null) {
+            createOAuthClients(rep, newRealm);
+        }
+
+
+        // Now that all possible roles and applications are created, create scope mappings
+
+        Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap();
+
+        if (rep.getApplicationScopeMappings() != null) {
+
+            for (Map.Entry<String, List<ScopeMappingRepresentation>> entry : rep.getApplicationScopeMappings().entrySet()) {
+                ApplicationModel app = appMap.get(entry.getKey());
+                if (app == null) {
+                    throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
+                }
+                createApplicationScopeMappings(newRealm, app, entry.getValue());
+            }
+        }
+
+        if (rep.getScopeMappings() != null) {
+            for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
+                ClientModel client = newRealm.findClient(scope.getClient());
+                for (String roleString : scope.getRoles()) {
+                    RoleModel role = newRealm.getRole(roleString.trim());
+                    if (role == null) {
+                        role = newRealm.addRole(roleString.trim());
+                    }
+                    client.addScopeMapping(role);
+                }
+
+            }
+        }
+
+        if (rep.getSmtpServer() != null) {
+            newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
+        }
+
+        if (rep.getSocialProviders() != null) {
+            newRealm.setSocialConfig(new HashMap(rep.getSocialProviders()));
+        }
+        if (rep.getLdapServer() != null) {
+            newRealm.setLdapServerConfig(new HashMap(rep.getLdapServer()));
+        }
+
+        if (rep.getAuthenticationProviders() != null) {
+            List<AuthenticationProviderModel> authProviderModels = convertAuthenticationProviders(rep.getAuthenticationProviders());
+            newRealm.setAuthenticationProviders(authProviderModels);
+        }  else {
+            List<AuthenticationProviderModel> authProviderModels = Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER);
+            newRealm.setAuthenticationProviders(authProviderModels);
+        }
+
+        // create users and their role mappings and social mappings
+
+        if (rep.getUsers() != null) {
+            for (UserRepresentation userRep : rep.getUsers()) {
+                UserModel user = createUser(session, newRealm, userRep, appMap);
+            }
+        }
+    }
+
+    public static void updateRealm(RealmRepresentation rep, RealmModel realm) {
+        if (rep.getRealm() != null) {
+            realm.setName(rep.getRealm());
+        }
+        if (rep.isEnabled() != null) realm.setEnabled(rep.isEnabled());
+        if (rep.isSocial() != null) realm.setSocial(rep.isSocial());
+        if (rep.isBruteForceProtected() != null) realm.setBruteForceProtected(rep.isBruteForceProtected());
+        if (rep.getMaxFailureWaitSeconds() != null) realm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
+        if (rep.getMinimumQuickLoginWaitSeconds() != null) realm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
+        if (rep.getWaitIncrementSeconds() != null) realm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
+        if (rep.getQuickLoginCheckMilliSeconds() != null) realm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
+        if (rep.getMaxDeltaTimeSeconds() != null) realm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
+        if (rep.getFailureFactor() != null) realm.setFailureFactor(rep.getFailureFactor());
+        if (rep.isPasswordCredentialGrantAllowed() != null) realm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
+        if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
+        if (rep.isRememberMe() != null) realm.setRememberMe(rep.isRememberMe());
+        if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
+        if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
+        if (rep.isUpdateProfileOnInitialSocialLogin() != null)
+            realm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
+        if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired()));
+        if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
+        if (rep.getAccessCodeLifespanUserAction() != null)
+            realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
+        if (rep.getNotBefore() != null) realm.setNotBefore(rep.getNotBefore());
+        if (rep.getAccessTokenLifespan() != null) realm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
+        if (rep.getSsoSessionIdleTimeout() != null) realm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
+        if (rep.getSsoSessionMaxLifespan() != null) realm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
+        if (rep.getRequiredCredentials() != null) {
+            realm.updateRequiredCredentials(rep.getRequiredCredentials());
+        }
+        if (rep.getLoginTheme() != null) realm.setLoginTheme(rep.getLoginTheme());
+        if (rep.getAccountTheme() != null) realm.setAccountTheme(rep.getAccountTheme());
+        if (rep.getAdminTheme() != null) realm.setAdminTheme(rep.getAdminTheme());
+        if (rep.getEmailTheme() != null) realm.setEmailTheme(rep.getEmailTheme());
+
+        if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
+
+        if (rep.getDefaultRoles() != null) {
+            realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()]));
+        }
+
+        if (rep.getSmtpServer() != null) {
+            realm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
+        }
+
+        if (rep.getSocialProviders() != null) {
+            realm.setSocialConfig(new HashMap(rep.getSocialProviders()));
+        }
+
+        if (rep.getLdapServer() != null) {
+            realm.setLdapServerConfig(new HashMap(rep.getLdapServer()));
+        }
+        if (rep.getAuthenticationProviders() != null) {
+            List<AuthenticationProviderModel> authProviderModels = convertAuthenticationProviders(rep.getAuthenticationProviders());
+            realm.setAuthenticationProviders(authProviderModels);
+        }
+
+        if ("GENERATE".equals(rep.getPublicKey())) {
+            KeycloakModelUtils.generateRealmKeys(realm);
+        }
+    }
+
+    // Basic realm stuff
+
+    public static void addRequiredCredential(RealmModel newRealm, String requiredCred) {
+        newRealm.addRequiredCredential(requiredCred);
+    }
+
+
+    private static List<AuthenticationProviderModel> convertAuthenticationProviders(List<AuthenticationProviderRepresentation> authenticationProviders) {
+        List<AuthenticationProviderModel> result = new ArrayList<AuthenticationProviderModel>();
+
+        for (AuthenticationProviderRepresentation representation : authenticationProviders) {
+            AuthenticationProviderModel model = new AuthenticationProviderModel(representation.getProviderName(),
+                    representation.isPasswordUpdateSupported(), representation.getConfig());
+            result.add(model);
+        }
+        return result;
+    }
+
+    // Roles
+
+    public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
+        RoleModel role = roleRep.getId()!=null ? newRealm.addRole(roleRep.getId(), roleRep.getName()) : newRealm.addRole(roleRep.getName());
+        if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
+    }
+
+    private static void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
+        if (roleRep.getComposites() == null) return;
+        if (roleRep.getComposites().getRealm() != null) {
+            for (String roleStr : roleRep.getComposites().getRealm()) {
+                RoleModel realmRole = realm.getRole(roleStr);
+                if (realmRole == null) throw new RuntimeException("Unable to find composite realm role: " + roleStr);
+                role.addCompositeRole(realmRole);
+            }
+        }
+        if (roleRep.getComposites().getApplication() != null) {
+            for (Map.Entry<String, List<String>> entry : roleRep.getComposites().getApplication().entrySet()) {
+                ApplicationModel app = realm.getApplicationByName(entry.getKey());
+                if (app == null) {
+                    throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName());
+                }
+                for (String roleStr : entry.getValue()) {
+                    RoleModel appRole = app.getRole(roleStr);
+                    if (appRole == null) throw new RuntimeException("Unable to find composite app role: " + roleStr);
+                    role.addCompositeRole(appRole);
+                }
+
+            }
+
+        }
+
+    }
+
+    // APPLICATIONS
+
+    private static Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
+        Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
+        for (ApplicationRepresentation resourceRep : rep.getApplications()) {
+            ApplicationModel app = createApplication(realm, resourceRep);
+            appMap.put(app.getName(), app);
+        }
+        return appMap;
+    }
+
+    /**
+     * Does not create scope or role mappings!
+     *
+     * @param realm
+     * @param resourceRep
+     * @return
+     */
+    public static ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep) {
+        logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
+        ApplicationModel applicationModel = resourceRep.getId()!=null ? realm.addApplication(resourceRep.getId(), resourceRep.getName()) : realm.addApplication(resourceRep.getName());
+        if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled());
+        applicationModel.setManagementUrl(resourceRep.getAdminUrl());
+        if (resourceRep.isSurrogateAuthRequired() != null)
+            applicationModel.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
+        applicationModel.setBaseUrl(resourceRep.getBaseUrl());
+        if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly());
+        if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient());
+        applicationModel.updateApplication();
+
+        if (resourceRep.getNotBefore() != null) {
+            applicationModel.setNotBefore(resourceRep.getNotBefore());
+        }
+
+        applicationModel.setSecret(resourceRep.getSecret());
+        if (applicationModel.getSecret() == null) {
+            KeycloakModelUtils.generateSecret(applicationModel);
+        }
+
+
+        if (resourceRep.getRedirectUris() != null) {
+            for (String redirectUri : resourceRep.getRedirectUris()) {
+                applicationModel.addRedirectUri(redirectUri);
+            }
+        }
+        if (resourceRep.getWebOrigins() != null) {
+            for (String webOrigin : resourceRep.getWebOrigins()) {
+                logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getName(), webOrigin);
+                applicationModel.addWebOrigin(webOrigin);
+            }
+        } else {
+            // add origins from redirect uris
+            if (resourceRep.getRedirectUris() != null) {
+                Set<String> origins = new HashSet<String>();
+                for (String redirectUri : resourceRep.getRedirectUris()) {
+                    logger.info("add redirectUri to origin: " + redirectUri);
+                    if (redirectUri.startsWith("http:")) {
+                        URI uri = URI.create(redirectUri);
+                        String origin = uri.getScheme() + "://" + uri.getHost();
+                        if (uri.getPort() != -1) {
+                            origin += ":" + uri.getPort();
+                        }
+                        logger.debugv("adding default application origin: {0}" , origin);
+                        origins.add(origin);
+                    }
+                }
+                if (origins.size() > 0) {
+                    applicationModel.setWebOrigins(origins);
+                }
+            }
+        }
+
+        if (resourceRep.getDefaultRoles() != null) {
+            applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
+        }
+
+        if (resourceRep.getClaims() != null) {
+            setClaims(applicationModel, resourceRep.getClaims());
+        } else {
+            applicationModel.setAllowedClaimsMask(ClaimMask.USERNAME);
+        }
+
+        return applicationModel;
+    }
+
+    public static void updateApplication(ApplicationRepresentation rep, ApplicationModel resource) {
+        if (rep.getName() != null) resource.setName(rep.getName());
+        if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
+        if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
+        if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
+        if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl());
+        if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl());
+        if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
+        resource.updateApplication();
+
+        if (rep.getNotBefore() != null) {
+            resource.setNotBefore(rep.getNotBefore());
+        }
+        if (rep.getDefaultRoles() != null) {
+            resource.updateDefaultRoles(rep.getDefaultRoles());
+        }
+
+        List<String> redirectUris = rep.getRedirectUris();
+        if (redirectUris != null) {
+            resource.setRedirectUris(new HashSet<String>(redirectUris));
+        }
+
+        List<String> webOrigins = rep.getWebOrigins();
+        if (webOrigins != null) {
+            resource.setWebOrigins(new HashSet<String>(webOrigins));
+        }
+
+        if (rep.getClaims() != null) {
+            setClaims(resource, rep.getClaims());
+        }
+    }
+
+    public static void setClaims(ClientModel model, ClaimRepresentation rep) {
+        long mask = model.getAllowedClaimsMask();
+        if (rep.getAddress()) {
+            mask |= ClaimMask.ADDRESS;
+        } else {
+            mask &= ~ClaimMask.ADDRESS;
+        }
+        if (rep.getEmail()) {
+            mask |= ClaimMask.EMAIL;
+        } else {
+            mask &= ~ClaimMask.EMAIL;
+        }
+        if (rep.getGender()) {
+            mask |= ClaimMask.GENDER;
+        } else {
+            mask &= ~ClaimMask.GENDER;
+        }
+        if (rep.getLocale()) {
+            mask |= ClaimMask.LOCALE;
+        } else {
+            mask &= ~ClaimMask.LOCALE;
+        }
+        if (rep.getName()) {
+            mask |= ClaimMask.NAME;
+        } else {
+            mask &= ~ClaimMask.NAME;
+        }
+        if (rep.getPhone()) {
+            mask |= ClaimMask.PHONE;
+        } else {
+            mask &= ~ClaimMask.PHONE;
+        }
+        if (rep.getPicture()) {
+            mask |= ClaimMask.PICTURE;
+        } else {
+            mask &= ~ClaimMask.PICTURE;
+        }
+        if (rep.getProfile()) {
+            mask |= ClaimMask.PROFILE;
+        } else {
+            mask &= ~ClaimMask.PROFILE;
+        }
+        if (rep.getUsername()) {
+            mask |= ClaimMask.USERNAME;
+        } else {
+            mask &= ~ClaimMask.USERNAME;
+        }
+        if (rep.getWebsite()) {
+            mask |= ClaimMask.WEBSITE;
+        } else {
+            mask &= ~ClaimMask.WEBSITE;
+        }
+        model.setAllowedClaimsMask(mask);
+    }
+
+    // OAuth clients
+
+    private static void createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
+        for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
+            createOAuthClient(rep, realm);
+        }
+    }
+
+    public static OAuthClientModel createOAuthClient(String id, String name, RealmModel realm) {
+        OAuthClientModel model = id!=null ? realm.addOAuthClient(id, name) : realm.addOAuthClient(name);
+        KeycloakModelUtils.generateSecret(model);
+        return model;
+    }
+
+    public static OAuthClientModel createOAuthClient(OAuthClientRepresentation rep, RealmModel realm) {
+        OAuthClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
+        updateOAuthClient(rep, model);
+        return model;
+    }
+
+    public static void updateOAuthClient(OAuthClientRepresentation rep, OAuthClientModel model) {
+        if (rep.getName() != null) model.setClientId(rep.getName());
+        if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
+        if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
+        if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
+        if (rep.getClaims() != null) {
+            setClaims(model, rep.getClaims());
+        }
+        if (rep.getNotBefore() != null) {
+            model.setNotBefore(rep.getNotBefore());
+        }
+        if (rep.getSecret() != null) model.setSecret(rep.getSecret());
+        List<String> redirectUris = rep.getRedirectUris();
+        if (redirectUris != null) {
+            model.setRedirectUris(new HashSet<String>(redirectUris));
+        }
+
+        List<String> webOrigins = rep.getWebOrigins();
+        if (webOrigins != null) {
+            model.setWebOrigins(new HashSet<String>(webOrigins));
+        }
+
+        if (rep.getClaims() != null) {
+            setClaims(model, rep.getClaims());
+        }
+
+        if (rep.getNotBefore() != null) {
+            model.setNotBefore(rep.getNotBefore());
+        }
+
+    }
+
+    // Scope mappings
+
+    public static void createApplicationScopeMappings(RealmModel realm, ApplicationModel applicationModel, List<ScopeMappingRepresentation> mappings) {
+        for (ScopeMappingRepresentation mapping : mappings) {
+            ClientModel client = realm.findClient(mapping.getClient());
+            for (String roleString : mapping.getRoles()) {
+                RoleModel role = applicationModel.getRole(roleString.trim());
+                if (role == null) {
+                    role = applicationModel.addRole(roleString.trim());
+                }
+                client.addScopeMapping(role);
+            }
+        }
+    }
+
+    // Users
+
+    public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
+        UserModel user = session.users().addUser(newRealm, userRep.getId(), userRep.getUsername(), false);
+        user.setEnabled(userRep.isEnabled());
+        user.setEmail(userRep.getEmail());
+        user.setFirstName(userRep.getFirstName());
+        user.setLastName(userRep.getLastName());
+        if (userRep.getAttributes() != null) {
+            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
+                user.setAttribute(entry.getKey(), entry.getValue());
+            }
+        }
+        if (userRep.getRequiredActions() != null) {
+            for (String requiredAction : userRep.getRequiredActions()) {
+                user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction));
+            }
+        }
+        if (userRep.getCredentials() != null) {
+            for (CredentialRepresentation cred : userRep.getCredentials()) {
+                updateCredential(user, cred);
+            }
+        }
+        if (userRep.getAuthenticationLink() != null) {
+            AuthenticationLinkRepresentation link = userRep.getAuthenticationLink();
+            AuthenticationLinkModel authLink = new AuthenticationLinkModel(link.getAuthProvider(), link.getAuthUserId());
+            user.setAuthenticationLink(authLink);
+        }
+        if (userRep.getSocialLinks() != null) {
+            for (SocialLinkRepresentation socialLink : userRep.getSocialLinks()) {
+                SocialLinkModel mappingModel = new SocialLinkModel(socialLink.getSocialProvider(), socialLink.getSocialUserId(), socialLink.getSocialUsername());
+                session.users().addSocialLink(newRealm, user, mappingModel);
+            }
+        }
+        if (userRep.getRealmRoles() != null) {
+            for (String roleString : userRep.getRealmRoles()) {
+                RoleModel role = newRealm.getRole(roleString.trim());
+                if (role == null) {
+                    role = newRealm.addRole(roleString.trim());
+                }
+                user.grantRole(role);
+            }
+        }
+        if (userRep.getApplicationRoles() != null) {
+            for (Map.Entry<String, List<String>> entry : userRep.getApplicationRoles().entrySet()) {
+                ApplicationModel app = appMap.get(entry.getKey());
+                if (app == null) {
+                    throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
+                }
+                createApplicationRoleMappings(app, user, entry.getValue());
+            }
+        }
+        return user;
+    }
+
+    // Detect if it is "plain-text" or "hashed" representation and update model according to it
+    private static void updateCredential(UserModel user, CredentialRepresentation cred) {
+        if (cred.getValue() != null) {
+            UserCredentialModel plainTextCred = convertCredential(cred);
+            user.updateCredential(plainTextCred);
+        } else {
+            UserCredentialValueModel hashedCred = new UserCredentialValueModel();
+            hashedCred.setType(cred.getType());
+            hashedCred.setDevice(cred.getDevice());
+            hashedCred.setHashIterations(cred.getHashIterations());
+            try {
+                hashedCred.setSalt(Base64.decode(cred.getSalt()));
+            } catch (IOException ioe) {
+                throw new RuntimeException(ioe);
+            }
+            hashedCred.setValue(cred.getHashedSaltedValue());
+            user.updateCredentialDirectly(hashedCred);
+        }
+    }
+
+    public static UserCredentialModel convertCredential(CredentialRepresentation cred) {
+        UserCredentialModel credential = new UserCredentialModel();
+        credential.setType(cred.getType());
+        credential.setValue(cred.getValue());
+        return credential;
+    }
+
+    // Role mappings
+
+    public static void createApplicationRoleMappings(ApplicationModel applicationModel, UserModel user, List<String> roleNames) {
+        if (user == null) {
+            throw new RuntimeException("User not found");
+        }
+
+        for (String roleName : roleNames) {
+            RoleModel role = applicationModel.getRole(roleName.trim());
+            if (role == null) {
+                role = applicationModel.addRole(roleName.trim());
+            }
+            user.grantRole(role);
+
+        }
+    }
+
+}
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
old mode 100644
new mode 100755
index 57ff498..713d651
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
@@ -1,15 +1,12 @@
 package org.keycloak.models.hybrid;
 
-import org.keycloak.models.realms.Application;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.realms.Application;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
-import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
old mode 100644
new mode 100755
index d0c4b4e..dfaa612
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
@@ -3,7 +3,6 @@ package org.keycloak.models.hybrid;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.realms.Client;
 
 import java.util.Set;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
old mode 100644
new mode 100755
index b971646..1b27841
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
@@ -1,7 +1,6 @@
 package org.keycloak.models.hybrid;
 
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.ModelProvider;
@@ -10,13 +9,11 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.sessions.SessionProvider;
 import org.keycloak.models.users.UserProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.util.Time;
 
 import java.util.HashSet;
 import java.util.List;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
old mode 100644
new mode 100755
index 314ea96..3a644d4
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
@@ -1,12 +1,9 @@
 package org.keycloak.models.hybrid;
 
 import org.keycloak.Config;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.ModelProviderFactory;
-import org.keycloak.models.sessions.SessionProvider;
-import org.keycloak.models.users.UserProvider;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
old mode 100644
new mode 100755
index 1f7bd27..f8b5415
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
@@ -1,11 +1,5 @@
 package org.keycloak.models.hybrid;
 
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserCredentialValueModel;
-import org.keycloak.models.realms.Application;
-import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.OAuthClient;
-import org.keycloak.models.realms.Realm;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.ClientModel;
@@ -15,9 +9,14 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.UsernameLoginFailureModel;
+import org.keycloak.models.realms.Application;
+import org.keycloak.models.realms.Client;
+import org.keycloak.models.realms.OAuthClient;
+import org.keycloak.models.realms.Realm;
 import org.keycloak.models.users.Credentials;
 import org.keycloak.models.users.Feature;
 import org.keycloak.models.users.User;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
old mode 100644
new mode 100755
index c6e79ef..7b10d04
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
@@ -1,10 +1,10 @@
 package org.keycloak.models.hybrid;
 
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
 import org.keycloak.models.realms.Application;
 import org.keycloak.models.realms.Realm;
 import org.keycloak.models.realms.Role;
-import org.keycloak.models.RoleContainerModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import java.util.HashSet;
diff --git a/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java b/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
old mode 100644
new mode 100755
index 35b9539..b496f3f
--- a/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
+++ b/model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
@@ -3,9 +3,6 @@ package org.keycloak.models.hybrid;
 import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.sessions.LoginFailure;
 
-import java.util.LinkedList;
-import java.util.List;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
index b8bc526..1b63d1e 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
@@ -1,6 +1,5 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserProvider;
 
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java
index 0d25e33..247a797 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java
@@ -7,7 +7,6 @@ import org.keycloak.models.ModelProvider;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.cache.entities.CachedApplication;
 import org.keycloak.models.cache.entities.CachedApplicationRole;
@@ -15,7 +14,6 @@ import org.keycloak.models.cache.entities.CachedOAuthClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRealmRole;
 import org.keycloak.models.cache.entities.CachedRole;
-import org.keycloak.models.cache.entities.CachedUser;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -202,9 +200,23 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
     @Override
     public boolean removeRealm(String id) {
         cache.invalidateCachedRealmById(id);
+
+        RealmModel realm = getDelegate().getRealm(id);
+        Set<RoleModel> realmRoles = null;
+        if (realm != null) {
+            realmRoles = realm.getRoles();
+        }
+
         boolean didIt = getDelegate().removeRealm(id);
         realmInvalidations.add(id);
 
+        // TODO: Temporary workaround to invalidate cached realm roles
+        if (didIt && realmRoles != null) {
+            for (RoleModel role : realmRoles) {
+                roleInvalidations.add(role.getId());
+            }
+        }
+
         return didIt;
     }
 
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
index 415ad8d..f44bbd5 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
@@ -215,6 +215,9 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
 
     @Override
     public boolean removeUser(RealmModel realm, String name) {
+        UserModel user = getUserByUsername(name, realm);
+        if (user == null) return false;
+        registerUserInvalidation(realm, user.getId());
         return getDelegate().removeUser(realm, name);
     }
 
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java
index b6f6668..f1f34dc 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealmRole.java
@@ -2,9 +2,6 @@ package org.keycloak.models.cache.entities;
 
 import org.keycloak.models.RoleModel;
 
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java
index a705c2d..4ef60fa 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheModelProvider.java
@@ -1,21 +1,13 @@
 package org.keycloak.models.cache;
 
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.UsernameLoginFailureModel;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
new file mode 100755
index 0000000..36f5669
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
@@ -0,0 +1,126 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
+import org.keycloak.models.cache.entities.CachedUser;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class NoCacheUserProvider implements CacheUserProvider {
+    protected KeycloakSession session;
+    protected UserProvider delegate;
+
+    public NoCacheUserProvider(KeycloakSession session) {
+        this.session = session;
+    }
+
+    @Override
+    public UserProvider getDelegate() {
+        if (delegate != null) return delegate;
+        delegate = session.getProvider(UserProvider.class);
+        return delegate;
+    }
+
+    @Override
+    public void registerUserInvalidation(RealmModel realm, String id) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public UserModel getUserById(String id, RealmModel realm) {
+        return getDelegate().getUserById(id, realm);
+    }
+
+    @Override
+    public UserModel getUserByUsername(String username, RealmModel realm) {
+        return getDelegate().getUserByUsername(username, realm);
+    }
+
+    @Override
+    public UserModel getUserByEmail(String email, RealmModel realm) {
+        return getDelegate().getUserByEmail(email, realm);
+    }
+
+    @Override
+    public void close() {
+        if (delegate != null) delegate.close();
+    }
+
+    @Override
+    public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
+        return getDelegate().getUserBySocialLink(socialLink, realm);
+    }
+
+    @Override
+    public List<UserModel> getUsers(RealmModel realm) {
+        return getDelegate().getUsers(realm);
+    }
+
+    @Override
+    public List<UserModel> searchForUser(String search, RealmModel realm) {
+        return getDelegate().searchForUser(search, realm);
+    }
+
+    @Override
+    public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
+        return getDelegate().searchForUserByAttributes(attributes, realm);
+    }
+
+    @Override
+    public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
+        return getDelegate().getSocialLinks(user, realm);
+    }
+
+    @Override
+    public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
+        return getDelegate().getSocialLink(user, socialProvider, realm);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) {
+        return getDelegate().addUser(realm, id, username, addDefaultRoles);
+    }
+
+    @Override
+    public UserModel addUser(RealmModel realm, String username) {
+        return getDelegate().addUser(realm, username);
+    }
+
+    @Override
+    public boolean removeUser(RealmModel realm, String name) {
+        return getDelegate().removeUser(realm, name);
+    }
+
+    @Override
+    public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
+        getDelegate().addSocialLink(realm, user, socialLink);
+    }
+
+    @Override
+    public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
+        return getDelegate().removeSocialLink(realm, user, socialProvider);
+    }
+
+    @Override
+    public void preRemove(RealmModel realm) {
+        getDelegate().preRemove(realm);
+    }
+
+    @Override
+    public void preRemove(RoleModel role) {
+        getDelegate().preRemove(role);
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java
new file mode 100755
index 0000000..1008a00
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java
@@ -0,0 +1,30 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class NoCacheUserProviderFactory implements CacheUserProviderFactory {
+    @Override
+    public CacheUserProvider create(KeycloakSession session) {
+        return new NoCacheUserProvider(session);
+    }
+
+    @Override
+    public void close() {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public String getId() {
+        return "none";
+    }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
index b1813c7..7ef235f 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
@@ -9,7 +9,6 @@ import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
index 3dd15b1..1bb0c3f 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
@@ -1,11 +1,9 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.RealmModel;
 import org.keycloak.models.cache.entities.CachedApplication;
 import org.keycloak.models.cache.entities.CachedOAuthClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRole;
-import org.keycloak.models.cache.entities.CachedUser;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
index 3f94077..879dcf9 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
@@ -3,7 +3,6 @@ package org.keycloak.models.cache;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
index 48a02b6..09c7b35 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
@@ -1,6 +1,5 @@
 package org.keycloak.models.cache;
 
-import org.keycloak.models.RealmModel;
 import org.keycloak.models.cache.entities.CachedUser;
 
 /**
diff --git a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheModelProviderFactory b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheModelProviderFactory
index 343a85b..7e3ca5d 100755
--- a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheModelProviderFactory
+++ b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheModelProviderFactory
@@ -1,2 +1,2 @@
-org.keycloak.models.cache.SimpleCacheModelProviderFactory
+org.keycloak.models.cache.MemoryCacheModelProviderFactory
 org.keycloak.models.cache.NoCacheModelProviderFactory
\ No newline at end of file
diff --git a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory
index 880596e..438f9e1 100755
--- a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory
+++ b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheUserProviderFactory
@@ -1 +1,2 @@
-org.keycloak.models.cache.SimpleCacheUserProviderFactory
+org.keycloak.models.cache.MemoryCacheUserProviderFactory
+org.keycloak.models.cache.NoCacheUserProviderFactory
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
index c91d132..caf8f4e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
@@ -3,12 +3,12 @@ package org.keycloak.models.jpa;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.jpa.entities.*;
+import org.keycloak.models.jpa.entities.ApplicationEntity;
+import org.keycloak.models.jpa.entities.RoleEntity;
+import org.keycloak.models.jpa.entities.ScopeMappingEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
index 8327bd0..b379f18 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
@@ -1,25 +1,12 @@
 package org.keycloak.models.jpa.entities;
 
 import javax.persistence.CascadeType;
-import javax.persistence.CollectionTable;
-import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
-import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.hibernate.annotations.GenericGenerator;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
old mode 100644
new mode 100755
index e6ae8d4..16942d9
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
@@ -1,14 +1,10 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToOne;
-
-import org.hibernate.annotations.GenericGenerator;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
old mode 100644
new mode 100755
index 2ce4c12..06094a2
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
@@ -1,6 +1,6 @@
 package org.keycloak.models.jpa.entities;
 
-import java.util.Map;
+import org.hibernate.annotations.GenericGenerator;
 
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
@@ -11,8 +11,7 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.MapKeyColumn;
 import javax.persistence.Table;
-
-import org.hibernate.annotations.GenericGenerator;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index 9367d25..46b8197 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -1,20 +1,15 @@
 package org.keycloak.models.jpa.entities;
 
-import org.hibernate.annotations.GenericGenerator;
-
-import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
 import java.util.HashSet;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
index 6d792f8..2a03cdf 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java
@@ -1,5 +1,7 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -8,8 +10,6 @@ import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -33,6 +33,9 @@ public class CredentialEntity {
     @ManyToOne(fetch = FetchType.LAZY)
     protected UserEntity user;
 
+    @ManyToOne(fetch = FetchType.LAZY)
+    protected RealmEntity realm;
+
     public String getValue() {
         return value;
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
index 9487022..bc07b01 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java
@@ -1,11 +1,11 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @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/entities/RoleEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
index d3fc6df..2c62502 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java
@@ -3,10 +3,7 @@ package org.keycloak.models.jpa.entities;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
@@ -18,8 +15,6 @@ import javax.persistence.UniqueConstraint;
 import java.util.ArrayList;
 import java.util.Collection;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @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/entities/SocialLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
index a1de3af..5e63b51 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
@@ -1,5 +1,7 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -8,8 +10,6 @@ import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 
-import org.hibernate.annotations.GenericGenerator;
-
 /**
  * @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/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
index 75389c9..53561f9 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java
@@ -1,6 +1,5 @@
 package org.keycloak.models.jpa.entities;
 
-import org.hibernate.annotations.GenericGenerator;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
@@ -10,7 +9,6 @@ import javax.persistence.Column;
 import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
@@ -21,7 +19,6 @@ import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
index 647acea..27b8f49 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java
@@ -1,6 +1,13 @@
 package org.keycloak.models.jpa.entities;
 
+import org.hibernate.annotations.GenericGenerator;
+
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 
@@ -14,6 +21,40 @@ import javax.persistence.NamedQuery;
         @NamedQuery(name="userRoleMappingIds", query="select m.role.id from UserRoleMappingEntity m where m.user = :user")
 })
 @Entity
-public class UserRoleMappingEntity extends AbstractRoleMappingEntity {
+public class UserRoleMappingEntity  {
+    @Id
+    @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator")
+    @GeneratedValue(generator = "keycloak_generator")
+    protected String id;
+    @ManyToOne(fetch= FetchType.LAZY)
+    protected UserEntity user;
+
+    @ManyToOne(fetch= FetchType.LAZY)
+    @JoinColumn(name="roleId")
+    protected RoleEntity role;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public UserEntity getUser() {
+        return user;
+    }
+
+    public void setUser(UserEntity user) {
+        this.user = user;
+    }
+
+    public RoleEntity getRole() {
+        return role;
+    }
+
+    public void setRole(RoleEntity role) {
+        this.role = role;
+    }
 
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
index e780760..18ee599 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
@@ -2,29 +2,21 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.models.jpa.entities.ApplicationEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
 import org.keycloak.models.jpa.entities.RoleEntity;
-import org.keycloak.models.jpa.entities.SocialLinkEntity;
-import org.keycloak.models.jpa.entities.UserEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
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 ba232a5..01e32ec 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
@@ -2,16 +2,11 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
-import org.keycloak.models.ModelProvider;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
-import org.keycloak.models.jpa.entities.ApplicationEntity;
-import org.keycloak.models.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.jpa.entities.RealmEntity;
 import org.keycloak.models.jpa.entities.RoleEntity;
 import org.keycloak.models.jpa.entities.SocialLinkEntity;
@@ -23,7 +18,6 @@ import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -127,11 +121,9 @@ public class JpaUserProvider implements UserProvider {
 
     @Override
     public void preRemove(RealmModel realm) {
-        TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm", UserEntity.class);
         RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
-        query.setParameter("realm", realmEntity);
-        for (UserEntity u : query.getResultList()) {
-            em.remove(u);
+        for (UserEntity u : em.createQuery("from UserEntity u where u.realm = :realm", UserEntity.class).setParameter("realm", realmEntity).getResultList()) {
+            removeUser(realm, u.getUsername());
         }
     }
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
index 3242489..3a52f12 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
@@ -3,8 +3,6 @@ package org.keycloak.models.jpa;
 import org.keycloak.Config;
 import org.keycloak.connections.jpa.JpaConnectionProvider;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
-import org.keycloak.models.ModelProviderFactory;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.UserProviderFactory;
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
index c890c9f..2279163 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
@@ -1,14 +1,10 @@
 package org.keycloak.models.jpa;
 
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
 
 import javax.persistence.EntityManager;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
old mode 100644
new mode 100755
index dfa5053..62a9426
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
@@ -1,12 +1,11 @@
 package org.keycloak.models.jpa;
 
 import org.hibernate.exception.ConstraintViolationException;
-import org.keycloak.models.ModelException;
 import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.ModelException;
 
 import javax.persistence.EntityExistsException;
 import javax.persistence.EntityManager;
-import javax.persistence.PersistenceException;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 0d8dad0..b9addbd 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -10,11 +10,9 @@ import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UsernameLoginFailureModel;
 import org.keycloak.models.jpa.entities.ApplicationEntity;
 import org.keycloak.models.jpa.entities.AuthenticationProviderEntity;
 import org.keycloak.models.jpa.entities.OAuthClientEntity;
@@ -607,7 +605,7 @@ public class RealmAdapter implements RealmModel {
     public boolean removeOAuthClient(String id) {
         OAuthClientModel oauth = getOAuthClientById(id);
         if (oauth == null) return false;
-        OAuthClientEntity client = (OAuthClientEntity) ((OAuthClientAdapter) oauth).getEntity();
+        OAuthClientEntity client = em.getReference(OAuthClientEntity.class, oauth.getId());
         em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where client = :client").setParameter("client", client).executeUpdate();
         em.remove(client);
         return true;
@@ -926,7 +924,8 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public void setMasterAdminApp(ApplicationModel app) {
-        realm.setMasterAdminApp(((ApplicationAdapter) app).getJpaEntity());
+        ApplicationEntity appEntity = app!=null ? em.getReference(ApplicationEntity.class, app.getId()) : null;
+        realm.setMasterAdminApp(appEntity);
         em.flush();
     }
 
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 18219f6..fc2fcbc 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
@@ -2,7 +2,6 @@ package org.keycloak.models.jpa;
 
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
-import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java b/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
old mode 100644
new mode 100755
index 6fc10e8..b35ee13
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.jpa.utils;
 
-import java.io.Serializable;
-
 import org.hibernate.HibernateException;
 import org.hibernate.engine.spi.SessionImplementor;
 import org.hibernate.id.IdentifierGenerator;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
+import java.io.Serializable;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
index 525d33c..606ebd3 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
@@ -2,12 +2,12 @@ package org.keycloak.models.mongo.keycloak.adapters;
 
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.mongo.utils.MongoModelUtils;
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 5077746..66cf49d 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -1,13 +1,13 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
+import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.entities.ClientEntity;
-import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.mongo.utils.MongoModelUtils;
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java
index b5147cb..f03f099 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoModelProvider.java
@@ -11,23 +11,14 @@ import org.keycloak.models.ModelProvider;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.entities.SocialLinkEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
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 f6a8d8e..f14f645 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
@@ -1,26 +1,18 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import com.mongodb.BasicDBObject;
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.MongoStore;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
-import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.entities.SocialLinkEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
-import org.keycloak.models.utils.KeycloakModelUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java
index b40127e..083d0c0 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProviderFactory.java
@@ -4,8 +4,6 @@ import org.jboss.logging.Logger;
 import org.keycloak.Config;
 import org.keycloak.connections.mongo.MongoConnectionProvider;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelProvider;
-import org.keycloak.models.ModelProviderFactory;
 import org.keycloak.models.UserProvider;
 import org.keycloak.models.UserProviderFactory;
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
index e124392..71b73ce 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
@@ -1,10 +1,9 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import org.keycloak.models.ApplicationModel;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
 
 /**
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index f9b9d04..b0fc75e 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -15,18 +15,15 @@ import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.entities.AuthenticationProviderEntity;
 import org.keycloak.models.entities.RequiredCredentialEntity;
-import org.keycloak.models.entities.SocialLinkEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
-import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.models.utils.TimeBasedOTP;
 
@@ -858,7 +855,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
 
     @Override
     public void setMasterAdminApp(ApplicationModel app) {
-        realm.setAdminAppId(app.getId());
+        String adminAppId = app != null ? app.getId() : null;
+        realm.setAdminAppId(adminAppId);
         updateRealm();
     }
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
index ba47283..c2a8317 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java
@@ -1,22 +1,22 @@
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
+import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
 import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Wrapper around RoleData object, which will persist wrapped object after each set operation (compatibility with picketlink based idm)
  *
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java
index 36728dc..c1a4267 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRealmEntity.java
@@ -2,11 +2,11 @@ package org.keycloak.models.mongo.keycloak.entities;
 
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
-import org.keycloak.models.entities.RealmEntity;
 import org.keycloak.connections.mongo.api.MongoCollection;
 import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
 import org.keycloak.connections.mongo.api.MongoIndex;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.entities.RealmEntity;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java
index 46f1df9..be034da 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/MongoRoleEntity.java
@@ -3,13 +3,13 @@ package org.keycloak.models.mongo.keycloak.entities;
 import com.mongodb.DBObject;
 import com.mongodb.QueryBuilder;
 import org.jboss.logging.Logger;
-import org.keycloak.models.entities.RoleEntity;
 import org.keycloak.connections.mongo.api.MongoCollection;
 import org.keycloak.connections.mongo.api.MongoField;
 import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
 import org.keycloak.connections.mongo.api.MongoIndex;
 import org.keycloak.connections.mongo.api.MongoStore;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
+import org.keycloak.models.entities.RoleEntity;
 
 import java.util.List;
 
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
index 9fa72d0..9b02e14 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
@@ -16,7 +16,12 @@ import org.picketlink.idm.model.sample.SampleModel;
 import org.picketlink.idm.query.IdentityQuery;
 import org.picketlink.idm.query.RelationshipQuery;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
index 36d7098..bb1b564 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
@@ -1,7 +1,6 @@
 package org.keycloak.models.picketlink;
 
 import org.bouncycastle.openssl.PEMWriter;
-import org.keycloak.util.PemUtils;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.IdGenerator;
 import org.keycloak.models.KeycloakSession;
@@ -22,6 +21,7 @@ import org.keycloak.models.picketlink.relationships.RequiredApplicationCredentia
 import org.keycloak.models.picketlink.relationships.RequiredCredentialRelationship;
 import org.keycloak.models.picketlink.relationships.ScopeRelationship;
 import org.keycloak.models.picketlink.relationships.SocialLinkRelationship;
+import org.keycloak.util.PemUtils;
 import org.picketlink.idm.IdentityManagementException;
 import org.picketlink.idm.IdentityManager;
 import org.picketlink.idm.PartitionManager;
@@ -46,7 +46,14 @@ import java.io.StringWriter;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Meant to be a per-request object
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java
index e44c7b1..16c2500 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ApplicationAdapter.java
@@ -2,13 +2,13 @@ package org.keycloak.models.realms.jpa;
 
 import org.keycloak.models.realms.Application;
 import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.RoleContainer;
-import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 import org.keycloak.models.realms.jpa.entities.ApplicationEntity;
 import org.keycloak.models.realms.jpa.entities.RoleEntity;
+import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java
index 660646e..147a4aa 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/ClientAdapter.java
@@ -1,12 +1,12 @@
 package org.keycloak.models.realms.jpa;
 
 import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.RoleContainer;
-import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 import org.keycloak.models.realms.jpa.entities.ClientEntity;
+import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java
index 9f8f043..00c833c 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProvider.java
@@ -1,15 +1,15 @@
 package org.keycloak.models.realms.jpa;
 
+import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.realms.Application;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.OAuthClient;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.jpa.entities.ApplicationEntity;
 import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.realms.jpa.entities.RealmEntity;
 import org.keycloak.models.realms.jpa.entities.RoleEntity;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java
index e181b8e..f5c72cd 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/JpaRealmProviderFactory.java
@@ -1,9 +1,9 @@
 package org.keycloak.models.realms.jpa;
 
 import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.RealmProviderFactory;
-import org.keycloak.models.KeycloakSession;
 import org.keycloak.util.JpaUtils;
 
 import javax.persistence.EntityManagerFactory;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java
index 39bf489..b792a7d 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/OAuthClientAdapter.java
@@ -1,8 +1,7 @@
 package org.keycloak.models.realms.jpa;
 
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.OAuthClient;
-import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
 
 import javax.persistence.EntityManager;
diff --git a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java
index 578fa65..ffbbacf 100755
--- a/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java
+++ b/model/realms-jpa/src/main/java/org/keycloak/models/realms/jpa/RealmAdapter.java
@@ -1,21 +1,21 @@
 package org.keycloak.models.realms.jpa;
 
-import org.keycloak.models.realms.Application;
-import org.keycloak.models.realms.Client;
-import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RequiredCredentialModel;
+import org.keycloak.models.realms.Application;
+import org.keycloak.models.realms.Client;
 import org.keycloak.models.realms.OAuthClient;
 import org.keycloak.models.realms.Realm;
+import org.keycloak.models.realms.RealmProvider;
 import org.keycloak.models.realms.Role;
 import org.keycloak.models.realms.jpa.entities.ApplicationEntity;
 import org.keycloak.models.realms.jpa.entities.AuthenticationProviderEntity;
+import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
 import org.keycloak.models.realms.jpa.entities.RealmEntity;
 import org.keycloak.models.realms.jpa.entities.RequiredCredentialEntity;
 import org.keycloak.models.realms.jpa.entities.RoleEntity;
 import org.keycloak.models.realms.jpa.entities.ScopeMappingEntity;
-import org.keycloak.models.realms.jpa.entities.OAuthClientEntity;
-import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
index e08448e..fac9375 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/UsernameLoginFailureEntity.java
@@ -1,10 +1,8 @@
 package org.keycloak.models.sessions.jpa.entities;
 
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
-import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import java.io.Serializable;
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java
old mode 100644
new mode 100755
index 1fdbb8f..fca5ca1
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProviderFactory.java
@@ -5,11 +5,8 @@ import org.keycloak.connections.jpa.JpaConnectionProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.UserSessionProviderFactory;
-import org.keycloak.util.JpaUtils;
 
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
old mode 100644
new mode 100755
index d5369e4..0ebdefd
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
@@ -2,7 +2,6 @@ package org.keycloak.models.sessions.mem;
 
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
diff --git a/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java b/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java
old mode 100644
new mode 100755
index 354bc86..4101191
--- a/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java
+++ b/model/tests/src/main/java/org/keycloak/model/test/LDAPEmbeddedServer.java
@@ -1,11 +1,8 @@
 package org.keycloak.model.test;
 
-import java.io.File;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Properties;
+import org.keycloak.models.LDAPConstants;
+import org.keycloak.models.RealmModel;
+import org.picketbox.test.ldap.AbstractLDAPTest;
 
 import javax.naming.CompositeName;
 import javax.naming.Context;
@@ -16,10 +13,12 @@ import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
-
-import org.keycloak.models.LDAPConstants;
-import org.keycloak.models.RealmModel;
-import org.picketbox.test.ldap.AbstractLDAPTest;
+import java.io.File;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
 
 /**
  * Forked from Picketlink project
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index 24e2237..edb4e40 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -5,7 +5,6 @@ import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.Constants;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
@@ -16,10 +15,8 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.UserSessionProvider;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
 
 import java.util.ArrayList;
@@ -151,8 +148,9 @@ public class AdapterTest extends AbstractModelTest {
     public void testOAuthClient() throws Exception {
         test1CreateRealm();
 
-        OAuthClientModel oauth = new OAuthClientManager(realmModel).create("oauth-client");
-        oauth = realmModel.getOAuthClient("oauth-client");
+        RepresentationToModel.createOAuthClient(null, "oauth-client", realmModel);
+        OAuthClientModel oauth = realmModel.getOAuthClient("oauth-client");
+        Assert.assertNotNull(oauth);
     }
 
     @Test
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
index f8869bc..ed62c37 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
@@ -6,7 +6,8 @@ import org.junit.Test;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.services.managers.ApplicationManager;
 
@@ -57,10 +58,10 @@ public class ApplicationModelTest extends AbstractModelTest {
 
     @Test
     public void json() {
-        ApplicationRepresentation representation = appManager.toRepresentation(application);
+        ApplicationRepresentation representation = ModelToRepresentation.toRepresentation(application);
 
         RealmModel realm = realmManager.createRealm("copy");
-        ApplicationModel copy = appManager.createApplication(realm, representation);
+        ApplicationModel copy = RepresentationToModel.createApplication(realm, representation);
 
         assertEquals(application, copy);
     }
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java
index da603ba..a8491c3 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java
@@ -18,7 +18,6 @@ import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus
 import org.keycloak.services.managers.BruteForceProtector;
 
 import javax.ws.rs.core.MultivaluedMap;
-
 import java.util.Arrays;
 import java.util.UUID;
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java
old mode 100644
new mode 100755
index 166b3f4..308c8f7
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersConfigTest.java
@@ -1,17 +1,17 @@
 package org.keycloak.model.test;
 
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.authentication.AuthProviderConstants;
+import org.keycloak.models.AuthenticationProviderModel;
+import org.keycloak.models.RealmModel;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.junit.Assert;
-import org.junit.Test;
-import org.keycloak.models.AuthenticationProviderModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.authentication.AuthProviderConstants;
-
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java
index 0de953e..2d30404 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersExternalModelTest.java
@@ -1,13 +1,5 @@
 package org.keycloak.model.test;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.MultivaluedMap;
-
 import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.junit.Assert;
@@ -15,6 +7,9 @@ import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.keycloak.authentication.AuthProviderConstants;
+import org.keycloak.authentication.AuthenticationProviderException;
+import org.keycloak.authentication.AuthenticationProviderManager;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.KeycloakSession;
@@ -24,9 +19,13 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.authentication.AuthProviderConstants;
-import org.keycloak.authentication.AuthenticationProviderException;
-import org.keycloak.authentication.AuthenticationProviderManager;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
index 0c98722..90c074c 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AuthProvidersLDAPTest.java
@@ -1,10 +1,5 @@
 package org.keycloak.model.test;
 
-import java.util.Arrays;
-import java.util.Collections;
-
-import javax.ws.rs.core.MultivaluedMap;
-
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Before;
@@ -12,6 +7,9 @@ import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.keycloak.authentication.AuthProviderConstants;
+import org.keycloak.authentication.AuthenticationProviderException;
+import org.keycloak.authentication.AuthenticationProviderManager;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
 import org.keycloak.models.RealmModel;
@@ -19,9 +17,10 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.authentication.AuthProviderConstants;
-import org.keycloak.authentication.AuthenticationProviderException;
-import org.keycloak.authentication.AuthenticationProviderManager;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
index 38c1c2a..768e9d0 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
@@ -1,8 +1,5 @@
 package org.keycloak.model.test;
 
-import java.util.HashSet;
-import java.util.Set;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -13,6 +10,9 @@ import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
index a3bfa24..c013155 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
@@ -4,7 +4,7 @@ import org.junit.Assert;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
-import org.keycloak.models.AccountRoles;
+import org.keycloak.authentication.AuthProviderConstants;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.AuthenticationLinkModel;
 import org.keycloak.models.AuthenticationProviderModel;
@@ -18,7 +18,6 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.authentication.AuthProviderConstants;
 
 import java.util.List;
 import java.util.Map;
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
index 05fee92..14a315e 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java
@@ -4,13 +4,10 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
 
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
 
 public class ModelTest extends AbstractModelTest {
 
diff --git a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
index 578c84d..15ce423 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java
@@ -2,7 +2,6 @@ package org.keycloak.model.test;
 
 import org.junit.Assert;
 import org.junit.Test;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java
index 3d0175f..1da3606 100755
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/entities/UserCredentialEntity.java
@@ -4,7 +4,6 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.IdClass;
 import javax.persistence.ManyToOne;
-
 import java.io.Serializable;
 
 /**
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java
index 64e8b06..2d11563 100755
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/JpaUserProviderFactory.java
@@ -2,7 +2,6 @@ package org.keycloak.models.users.jpa;
 
 import org.keycloak.Config;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.users.Feature;
 import org.keycloak.models.users.UserProvider;
 import org.keycloak.models.users.UserProviderFactory;
 import org.keycloak.util.JpaUtils;
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java
old mode 100644
new mode 100755
index ddd1c58..42c02d0
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/PersistenceExceptionConverter.java
@@ -1,8 +1,8 @@
 package org.keycloak.models.users.jpa;
 
 import org.hibernate.exception.ConstraintViolationException;
-import org.keycloak.models.ModelException;
 import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.ModelException;
 
 import javax.persistence.EntityExistsException;
 import javax.persistence.EntityManager;
diff --git a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java
index 2851379..fad265a 100755
--- a/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java
+++ b/model/users-jpa/src/main/java/org/keycloak/models/users/jpa/UserAdapter.java
@@ -5,8 +5,8 @@ import org.keycloak.models.users.Credentials;
 import org.keycloak.models.users.User;
 import org.keycloak.models.users.jpa.entities.UserAttributeEntity;
 import org.keycloak.models.users.jpa.entities.UserCredentialEntity;
-import org.keycloak.models.users.jpa.entities.UserRoleMappingEntity;
 import org.keycloak.models.users.jpa.entities.UserEntity;
+import org.keycloak.models.users.jpa.entities.UserRoleMappingEntity;
 
 import javax.persistence.EntityManager;
 import java.util.ArrayList;
diff --git a/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java b/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java
index 6f13dac..cf4d70c 100644
--- a/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java
+++ b/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java
@@ -37,7 +37,7 @@ public class LDAPKeycloakCredentialHandler extends LDAPPlainTextPasswordCredenti
 
     @Override
     public void setup(LDAPIdentityStore store) {
-        // TODO: Don't setup it here once PLIDM-508 is fixed
+        // TODO: Don't setup it here once PLINK-508 is fixed
         if (store.getConfig().isActiveDirectory() || Boolean.getBoolean("keycloak.ldap.ad.skipUserAccountControlAfterPasswordUpdate")) {
             String userAccountControlProp = System.getProperty("keycloak.ldap.ad.userAccountControlAfterPasswordUpdate");
             this.userAccountControlAfterPasswordUpdate = userAccountControlProp!=null ? userAccountControlProp : "512";
diff --git a/project-integrations/aerogear-ups/auth-server/pom.xml b/project-integrations/aerogear-ups/auth-server/pom.xml
index 2ea0015..a689697 100755
--- a/project-integrations/aerogear-ups/auth-server/pom.xml
+++ b/project-integrations/aerogear-ups/auth-server/pom.xml
@@ -167,7 +167,12 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-export-import-impl</artifactId>
+            <artifactId>keycloak-export-import-dir</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-single-file</artifactId>
             <version>${project.version}</version>
         </dependency>
 

server/pom.xml 12(+11 -1)

diff --git a/server/pom.xml b/server/pom.xml
index a086cee..7ab2cbb 100755
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -284,7 +284,17 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-export-import-impl</artifactId>
+            <artifactId>keycloak-export-import-dir</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-zip</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-single-file</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/server/src/main/resources/META-INF/keycloak-server.json b/server/src/main/resources/META-INF/keycloak-server.json
index 8dc062e..6bf6d88 100755
--- a/server/src/main/resources/META-INF/keycloak-server.json
+++ b/server/src/main/resources/META-INF/keycloak-server.json
@@ -14,12 +14,20 @@
         "provider": "jpa"
     },
 
+    "user": {
+        "provider": "${keycloak.user.provider:jpa}"
+    },
+
     "userSessions": {
-        "provider" : "mem"
+        "provider" : "${keycloak.userSessions.provider:mem}"
     },
 
     "modelCache": {
-        "provider": "${keycloak.model.cache.provider:}"
+        "provider": "${keycloak.model.cache.provider:mem}"
+    },
+
+    "userCache": {
+        "provider": "${keycloak.user.cache.provider:mem}"
     },
 
     "timer": {
diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
index be3cf34..b6b0040 100755
--- a/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
+++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakSession.java
@@ -1,7 +1,6 @@
 package org.keycloak.services;
 
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.KeycloakTransactionManager;
 import org.keycloak.models.ModelProvider;
 import org.keycloak.models.UserProvider;
diff --git a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
index 9c556d1..179e730 100755
--- a/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
+++ b/services/src/main/java/org/keycloak/services/managers/AccessCodeEntry.java
@@ -1,24 +1,17 @@
 package org.keycloak.services.managers;
 
-import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
-import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.AccessCode;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.util.Time;
 
-import javax.ws.rs.core.MultivaluedMap;
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
-import java.util.UUID;
 
 /**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index cf8f35e..63c01bc 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -12,6 +12,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.idm.CredentialRepresentation;
 
 import java.util.Arrays;
@@ -58,7 +59,7 @@ public class ApplianceBootstrap {
         realm.setAccessCodeLifespanUserAction(300);
         realm.setSslNotRequired(true);
         realm.setRegistrationAllowed(false);
-        manager.generateRealmKeys(realm);
+        KeycloakModelUtils.generateRealmKeys(realm);
         realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));
 
         realm.setAuditListeners(Collections.singleton("jboss-logging"));
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index 1f186b1..a9eecf0 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -4,26 +4,15 @@ import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.annotate.JsonPropertyOrder;
 import org.jboss.logging.Logger;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClaimMask;
-import org.keycloak.models.ClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionProvider;
+import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.adapters.config.BaseRealmConfig;
-import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.ScopeMappingRepresentation;
-import org.keycloak.representations.idm.UserRoleMappingRepresentation;
 
 import java.net.URI;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -41,114 +30,8 @@ public class ApplicationManager {
     public ApplicationManager() {
     }
 
-
-    /**
-     * Does not create scope or role mappings!
-     *
-     * @param realm
-     * @param resourceRep
-     * @return
-     */
-    public ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep) {
-        logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
-        ApplicationModel applicationModel = realm.addApplication(resourceRep.getName());
-        if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled());
-        applicationModel.setManagementUrl(resourceRep.getAdminUrl());
-        if (resourceRep.isSurrogateAuthRequired() != null)
-            applicationModel.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
-        applicationModel.setBaseUrl(resourceRep.getBaseUrl());
-        if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly());
-        if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient());
-        applicationModel.updateApplication();
-
-        if (resourceRep.getNotBefore() != null) {
-            applicationModel.setNotBefore(resourceRep.getNotBefore());
-        }
-
-        applicationModel.setSecret(resourceRep.getSecret());
-        if (applicationModel.getSecret() == null) {
-            generateSecret(applicationModel);
-        }
-
-
-        if (resourceRep.getRedirectUris() != null) {
-            for (String redirectUri : resourceRep.getRedirectUris()) {
-                applicationModel.addRedirectUri(redirectUri);
-            }
-        }
-        if (resourceRep.getWebOrigins() != null) {
-            for (String webOrigin : resourceRep.getWebOrigins()) {
-                logger.debugv("Application: {0} webOrigin: {1}", resourceRep.getName(), webOrigin);
-                applicationModel.addWebOrigin(webOrigin);
-            }
-        } else {
-            // add origins from redirect uris
-            if (resourceRep.getRedirectUris() != null) {
-                Set<String> origins = new HashSet<String>();
-                for (String redirectUri : resourceRep.getRedirectUris()) {
-                    logger.info("add redirectUri to origin: " + redirectUri);
-                    if (redirectUri.startsWith("http:")) {
-                        URI uri = URI.create(redirectUri);
-                        String origin = uri.getScheme() + "://" + uri.getHost();
-                        if (uri.getPort() != -1) {
-                            origin += ":" + uri.getPort();
-                        }
-                        logger.debugv("adding default application origin: {0}" , origin);
-                        origins.add(origin);
-                    }
-                }
-                if (origins.size() > 0) {
-                    applicationModel.setWebOrigins(origins);
-                }
-            }
-        }
-
-        if (resourceRep.getDefaultRoles() != null) {
-            applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
-        }
-
-        if (resourceRep.getClaims() != null) {
-            ClaimManager.setClaims(applicationModel, resourceRep.getClaims());
-        } else {
-            applicationModel.setAllowedClaimsMask(ClaimMask.USERNAME);
-        }
-
-        return applicationModel;
-    }
-
-    public void createRoleMappings(ApplicationModel applicationModel, UserModel user, List<String> roleNames) {
-        for (String roleName : roleNames) {
-            if (user == null) {
-                throw new RuntimeException("User not found");
-            }
-
-            RoleModel role = applicationModel.getRole(roleName.trim());
-            if (role == null) {
-                role = applicationModel.addRole(roleName.trim());
-            }
-            user.grantRole(role);
-
-        }
-    }
-
-    public void createScopeMappings(RealmModel realm, ApplicationModel applicationModel, List<ScopeMappingRepresentation> mappings) {
-        for (ScopeMappingRepresentation mapping : mappings) {
-            for (String roleString : mapping.getRoles()) {
-                RoleModel role = applicationModel.getRole(roleString.trim());
-                if (role == null) {
-                    role = applicationModel.addRole(roleString.trim());
-                }
-                ClientModel client = realm.findClient(mapping.getClient());
-                client.addScopeMapping(role);
-            }
-        }
-    }
-
     public ApplicationModel createApplication(RealmModel realm, String name) {
-        ApplicationModel app = realm.addApplication(name);
-        generateSecret(app);
-
-        return app;
+        return KeycloakModelUtils.createApplication(realm, name);
     }
 
     public boolean removeApplication(RealmModel realm, ApplicationModel application) {
@@ -163,74 +46,6 @@ public class ApplicationManager {
         }
     }
 
-    public UserCredentialModel generateSecret(ApplicationModel app) {
-        UserCredentialModel secret = UserCredentialModel.generateSecret();
-        app.setSecret(secret.getValue());
-        return secret;
-    }
-
-    public void updateApplication(ApplicationRepresentation rep, ApplicationModel resource) {
-        if (rep.getName() != null) resource.setName(rep.getName());
-        if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
-        if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
-        if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
-        if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl());
-        if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl());
-        if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
-        resource.updateApplication();
-
-        if (rep.getNotBefore() != null) {
-            resource.setNotBefore(rep.getNotBefore());
-        }
-        if (rep.getDefaultRoles() != null) {
-            resource.updateDefaultRoles(rep.getDefaultRoles());
-        }
-
-        List<String> redirectUris = rep.getRedirectUris();
-        if (redirectUris != null) {
-            resource.setRedirectUris(new HashSet<String>(redirectUris));
-        }
-
-        List<String> webOrigins = rep.getWebOrigins();
-        if (webOrigins != null) {
-            resource.setWebOrigins(new HashSet<String>(webOrigins));
-        }
-
-        if (rep.getClaims() != null) {
-            ClaimManager.setClaims(resource, rep.getClaims());
-        }
-    }
-
-    public ApplicationRepresentation toRepresentation(ApplicationModel applicationModel) {
-        ApplicationRepresentation rep = new ApplicationRepresentation();
-        rep.setId(applicationModel.getId());
-        rep.setName(applicationModel.getName());
-        rep.setEnabled(applicationModel.isEnabled());
-        rep.setAdminUrl(applicationModel.getManagementUrl());
-        rep.setPublicClient(applicationModel.isPublicClient());
-        rep.setBearerOnly(applicationModel.isBearerOnly());
-        rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
-        rep.setBaseUrl(applicationModel.getBaseUrl());
-        rep.setNotBefore(applicationModel.getNotBefore());
-
-        Set<String> redirectUris = applicationModel.getRedirectUris();
-        if (redirectUris != null) {
-            rep.setRedirectUris(new LinkedList<String>(redirectUris));
-        }
-
-        Set<String> webOrigins = applicationModel.getWebOrigins();
-        if (webOrigins != null) {
-            rep.setWebOrigins(new LinkedList<String>(webOrigins));
-        }
-
-        if (!applicationModel.getDefaultRoles().isEmpty()) {
-            rep.setDefaultRoles(applicationModel.getDefaultRoles().toArray(new String[0]));
-        }
-
-        return rep;
-
-    }
-
     @JsonPropertyOrder({"realm", "realm-public-key", "bearer-only", "auth-server-url", "ssl-not-required",
             "resource", "public-client", "credentials",
             "use-resource-role-mappings"})
diff --git a/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java b/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java
old mode 100644
new mode 100755
index a11fd74..468a146
--- a/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/LDAPConnectionTestManager.java
@@ -1,15 +1,11 @@
 package org.keycloak.services.managers;
 
-import java.util.Hashtable;
-import java.util.Map;
+import org.jboss.logging.Logger;
 
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.naming.ldap.InitialLdapContext;
-
-import org.jboss.logging.Logger;
-import org.keycloak.models.LDAPConstants;
-import org.keycloak.models.RealmModel;
+import java.util.Hashtable;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
index df13eb4..f69df51 100755
--- a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -2,22 +2,15 @@ package org.keycloak.services.managers;
 
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.annotate.JsonPropertyOrder;
-import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserSessionProvider;
 import org.keycloak.representations.adapters.config.BaseRealmConfig;
 import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.OAuthClientRepresentation;
 
 import java.net.URI;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -26,35 +19,14 @@ import java.util.Set;
 public class OAuthClientManager {
 
     private RealmManager realmManager;
-    protected RealmModel realm;
 
-    public OAuthClientManager(RealmModel realm) {
-        this.realm = realm;
+    public OAuthClientManager() {
     }
 
     public OAuthClientManager(RealmManager realmManager) {
         this.realmManager = realmManager;
     }
 
-    public UserCredentialModel generateSecret(OAuthClientModel app) {
-        UserCredentialModel secret = UserCredentialModel.generateSecret();
-        app.setSecret(secret.getValue());
-        return secret;
-    }
-
-
-    public OAuthClientModel create(String name) {
-        OAuthClientModel model = realm.addOAuthClient(name);
-        generateSecret(model);
-        return model;
-    }
-
-    public OAuthClientModel create(OAuthClientRepresentation rep) {
-        OAuthClientModel model = create(rep.getName());
-        update(rep, model);
-        return model;
-    }
-
     public boolean removeClient(RealmModel realm, OAuthClientModel client) {
         if (realm.removeOAuthClient(client.getId())) {
             UserSessionProvider sessions = realmManager.getSession().sessions();
@@ -67,58 +39,6 @@ public class OAuthClientManager {
         }
     }
 
-    public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
-        if (rep.getName() != null) model.setClientId(rep.getName());
-        if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
-        if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
-        if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
-        if (rep.getClaims() != null) {
-            ClaimManager.setClaims(model, rep.getClaims());
-        }
-        if (rep.getNotBefore() != null) {
-            model.setNotBefore(rep.getNotBefore());
-        }
-        if (rep.getSecret() != null) model.setSecret(rep.getSecret());
-        List<String> redirectUris = rep.getRedirectUris();
-        if (redirectUris != null) {
-            model.setRedirectUris(new HashSet<String>(redirectUris));
-        }
-
-        List<String> webOrigins = rep.getWebOrigins();
-        if (webOrigins != null) {
-            model.setWebOrigins(new HashSet<String>(webOrigins));
-        }
-
-        if (rep.getClaims() != null) {
-            ClaimManager.setClaims(model, rep.getClaims());
-        }
-
-        if (rep.getNotBefore() != null) {
-            model.setNotBefore(rep.getNotBefore());
-        }
-
-    }
-
-    public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
-        OAuthClientRepresentation rep = new OAuthClientRepresentation();
-        rep.setId(model.getId());
-        rep.setName(model.getClientId());
-        rep.setEnabled(model.isEnabled());
-        rep.setPublicClient(model.isPublicClient());
-        rep.setDirectGrantsOnly(model.isDirectGrantsOnly());
-        Set<String> redirectUris = model.getRedirectUris();
-        if (redirectUris != null) {
-            rep.setRedirectUris(new LinkedList<String>(redirectUris));
-        }
-
-        Set<String> webOrigins = model.getWebOrigins();
-        if (webOrigins != null) {
-            rep.setWebOrigins(new LinkedList<String>(webOrigins));
-        }
-        rep.setNotBefore(model.getNotBefore());
-        return rep;
-    }
-
     @JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required",
             "resource", "public-client", "credentials"})
     public static class InstallationAdapterConfig extends BaseRealmConfig {
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 9ab7831..595d4a3 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -1,48 +1,26 @@
 package org.keycloak.services.managers;
 
 import org.jboss.logging.Logger;
+import org.keycloak.Config;
+import org.keycloak.exportimport.util.ImportUtils;
 import org.keycloak.models.AccountRoles;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.AuthenticationLinkModel;
-import org.keycloak.models.AuthenticationProviderModel;
-import org.keycloak.models.ClientModel;
-import org.keycloak.Config;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelProvider;
-import org.keycloak.models.OAuthClientModel;
-import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.SocialLinkModel;
-import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.models.UserSessionProvider;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
-import org.keycloak.representations.idm.AuthenticationProviderRepresentation;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.OAuthClientRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.RealmAuditRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.representations.idm.ScopeMappingRepresentation;
-import org.keycloak.representations.idm.SocialLinkRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
+
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Per request object
@@ -128,10 +106,6 @@ public class RealmManager {
         adminConsole.addScopeMapping(adminRole);
     }
 
-    public String getMasterRealmAdminApplicationName(RealmModel realm) {
-        return realm.getName() + "-realm";
-    }
-
     public String getRealmAdminApplicationName(RealmModel realm) {
         return "realm-management";
     }
@@ -162,80 +136,6 @@ public class RealmManager {
         return removed;
     }
 
-    public void generateRealmKeys(RealmModel realm) {
-        KeyPair keyPair = null;
-        try {
-            keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        }
-        realm.setPrivateKey(keyPair.getPrivate());
-        realm.setPublicKey(keyPair.getPublic());
-    }
-
-    public void updateRealm(RealmRepresentation rep, RealmModel realm) {
-        if (rep.getRealm() != null) {
-            realm.setName(rep.getRealm());
-        }
-        if (rep.isEnabled() != null) realm.setEnabled(rep.isEnabled());
-        if (rep.isSocial() != null) realm.setSocial(rep.isSocial());
-        if (rep.isBruteForceProtected() != null) realm.setBruteForceProtected(rep.isBruteForceProtected());
-        if (rep.getMaxFailureWaitSeconds() != null) realm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
-        if (rep.getMinimumQuickLoginWaitSeconds() != null) realm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
-        if (rep.getWaitIncrementSeconds() != null) realm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
-        if (rep.getQuickLoginCheckMilliSeconds() != null) realm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
-        if (rep.getMaxDeltaTimeSeconds() != null) realm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
-        if (rep.getFailureFactor() != null) realm.setFailureFactor(rep.getFailureFactor());
-        if (rep.isPasswordCredentialGrantAllowed() != null) realm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
-        if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
-        if (rep.isRememberMe() != null) realm.setRememberMe(rep.isRememberMe());
-        if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
-        if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
-        if (rep.isUpdateProfileOnInitialSocialLogin() != null)
-            realm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
-        if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired()));
-        if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
-        if (rep.getAccessCodeLifespanUserAction() != null)
-            realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
-        if (rep.getNotBefore() != null) realm.setNotBefore(rep.getNotBefore());
-        if (rep.getAccessTokenLifespan() != null) realm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
-        if (rep.getSsoSessionIdleTimeout() != null) realm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
-        if (rep.getSsoSessionMaxLifespan() != null) realm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
-        if (rep.getRequiredCredentials() != null) {
-            realm.updateRequiredCredentials(rep.getRequiredCredentials());
-        }
-        if (rep.getLoginTheme() != null) realm.setLoginTheme(rep.getLoginTheme());
-        if (rep.getAccountTheme() != null) realm.setAccountTheme(rep.getAccountTheme());
-        if (rep.getAdminTheme() != null) realm.setAdminTheme(rep.getAdminTheme());
-        if (rep.getEmailTheme() != null) realm.setEmailTheme(rep.getEmailTheme());
-
-        if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
-
-        if (rep.getDefaultRoles() != null) {
-            realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()]));
-        }
-
-        if (rep.getSmtpServer() != null) {
-            realm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
-        }
-
-        if (rep.getSocialProviders() != null) {
-            realm.setSocialConfig(new HashMap(rep.getSocialProviders()));
-        }
-
-        if (rep.getLdapServer() != null) {
-            realm.setLdapServerConfig(new HashMap(rep.getLdapServer()));
-        }
-        if (rep.getAuthenticationProviders() != null) {
-            List<AuthenticationProviderModel> authProviderModels = convertAuthenticationProviders(rep.getAuthenticationProviders());
-            realm.setAuthenticationProviders(authProviderModels);
-        }
-
-        if ("GENERATE".equals(rep.getPublicKey())) {
-            generateRealmKeys(realm);
-        }
-    }
-
     public void updateRealmAudit(RealmAuditRepresentation rep, RealmModel realm) {
         realm.setAuditEnabled(rep.isAuditEnabled());
         realm.setAuditExpiration(rep.getAuditExpiration() != null ? rep.getAuditExpiration() : 0);
@@ -244,34 +144,9 @@ public class RealmManager {
         }
     }
 
-
-
+    // Should be RealmManager moved to model/api instead of referencing methods this way?
     private void setupMasterAdminManagement(RealmModel realm) {
-        RealmModel adminRealm;
-        RoleModel adminRole;
-
-        if (realm.getName().equals(Config.getAdminRealm())) {
-            adminRealm = realm;
-
-            adminRole = realm.addRole(AdminRoles.ADMIN);
-
-            RoleModel createRealmRole = realm.addRole(AdminRoles.CREATE_REALM);
-            adminRole.addCompositeRole(createRealmRole);
-        } else {
-            adminRealm = model.getRealmByName(Config.getAdminRealm());
-            adminRole = adminRealm.getRole(AdminRoles.ADMIN);
-        }
-
-        ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
-
-        ApplicationModel realmAdminApp = applicationManager.createApplication(adminRealm, getMasterRealmAdminApplicationName(realm));
-        realmAdminApp.setBearerOnly(true);
-        realm.setMasterAdminApp(realmAdminApp);
-
-        for (String r : AdminRoles.ALL_REALM_ROLES) {
-            RoleModel role = realmAdminApp.addRole(r);
-            adminRole.addCompositeRole(role);
-        }
+        ImportUtils.setupMasterAdminManagement(model, realm);
     }
 
     private void setupRealmAdminManagement(RealmModel realm) {
@@ -321,273 +196,7 @@ public class RealmManager {
     }
 
     public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
-        newRealm.setName(rep.getRealm());
-        if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
-        if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
-        if (rep.isBruteForceProtected() != null) newRealm.setBruteForceProtected(rep.isBruteForceProtected());
-        if (rep.getMaxFailureWaitSeconds() != null) newRealm.setMaxFailureWaitSeconds(rep.getMaxFailureWaitSeconds());
-        if (rep.getMinimumQuickLoginWaitSeconds() != null) newRealm.setMinimumQuickLoginWaitSeconds(rep.getMinimumQuickLoginWaitSeconds());
-        if (rep.getWaitIncrementSeconds() != null) newRealm.setWaitIncrementSeconds(rep.getWaitIncrementSeconds());
-        if (rep.getQuickLoginCheckMilliSeconds() != null) newRealm.setQuickLoginCheckMilliSeconds(rep.getQuickLoginCheckMilliSeconds());
-        if (rep.getMaxDeltaTimeSeconds() != null) newRealm.setMaxDeltaTimeSeconds(rep.getMaxDeltaTimeSeconds());
-        if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
-
-        if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
-
-        if (rep.getAccessTokenLifespan() != null) newRealm.setAccessTokenLifespan(rep.getAccessTokenLifespan());
-        else newRealm.setAccessTokenLifespan(300);
-
-        if (rep.getSsoSessionIdleTimeout() != null) newRealm.setSsoSessionIdleTimeout(rep.getSsoSessionIdleTimeout());
-        else newRealm.setSsoSessionIdleTimeout(600);
-        if (rep.getSsoSessionMaxLifespan() != null) newRealm.setSsoSessionMaxLifespan(rep.getSsoSessionMaxLifespan());
-        else newRealm.setSsoSessionMaxLifespan(36000);
-
-        if (rep.getAccessCodeLifespan() != null) newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
-        else newRealm.setAccessCodeLifespan(60);
-
-        if (rep.getAccessCodeLifespanUserAction() != null)
-            newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
-        else newRealm.setAccessCodeLifespanUserAction(300);
-
-        if (rep.isSslNotRequired() != null) newRealm.setSslNotRequired(rep.isSslNotRequired());
-        if (rep.isPasswordCredentialGrantAllowed() != null) newRealm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
-        if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
-        if (rep.isRememberMe() != null) newRealm.setRememberMe(rep.isRememberMe());
-        if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail());
-        if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
-        if (rep.isUpdateProfileOnInitialSocialLogin() != null)
-            newRealm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
-        if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
-            generateRealmKeys(newRealm);
-        } else {
-            newRealm.setPrivateKeyPem(rep.getPrivateKey());
-            newRealm.setPublicKeyPem(rep.getPublicKey());
-        }
-        if (rep.getLoginTheme() != null) newRealm.setLoginTheme(rep.getLoginTheme());
-        if (rep.getAccountTheme() != null) newRealm.setAccountTheme(rep.getAccountTheme());
-        if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAdminTheme());
-        if (rep.getEmailTheme() != null) newRealm.setEmailTheme(rep.getEmailTheme());
-
-        if (rep.getRequiredCredentials() != null) {
-            for (String requiredCred : rep.getRequiredCredentials()) {
-                addRequiredCredential(newRealm, requiredCred);
-            }
-        } else {
-            addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
-        }
-
-        if (rep.getPasswordPolicy() != null) newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
-
-        if (rep.getApplications() != null) {
-            Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
-        }
-
-        if (rep.getRoles() != null) {
-            if (rep.getRoles().getRealm() != null) { // realm roles
-                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
-                    createRole(newRealm, roleRep);
-                }
-            }
-            if (rep.getRoles().getApplication() != null) {
-                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
-                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
-                    if (app == null) {
-                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
-                    }
-                    for (RoleRepresentation roleRep : entry.getValue()) {
-                        RoleModel role = app.addRole(roleRep.getName());
-                        role.setDescription(roleRep.getDescription());
-                    }
-                }
-            }
-            // now that all roles are created, re-iterate and set up composites
-            if (rep.getRoles().getRealm() != null) { // realm roles
-                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
-                    RoleModel role = newRealm.getRole(roleRep.getName());
-                    addComposites(role, roleRep, newRealm);
-                }
-            }
-            if (rep.getRoles().getApplication() != null) {
-                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
-                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
-                    if (app == null) {
-                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
-                    }
-                    for (RoleRepresentation roleRep : entry.getValue()) {
-                        RoleModel role = app.getRole(roleRep.getName());
-                        addComposites(role, roleRep, newRealm);
-                    }
-                }
-            }
-        }
-
-
-        if (rep.getDefaultRoles() != null) {
-            for (String roleString : rep.getDefaultRoles()) {
-                newRealm.addDefaultRole(roleString.trim());
-            }
-        }
-
-        if (rep.getOauthClients() != null) {
-            createOAuthClients(rep, newRealm);
-        }
-
-
-        // Now that all possible roles and applications are created, create scope mappings
-
-        Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap();
-
-        if (rep.getApplicationScopeMappings() != null) {
-            ApplicationManager manager = new ApplicationManager(this);
-            for (Map.Entry<String, List<ScopeMappingRepresentation>> entry : rep.getApplicationScopeMappings().entrySet()) {
-                ApplicationModel app = appMap.get(entry.getKey());
-                if (app == null) {
-                    throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
-                }
-                manager.createScopeMappings(newRealm, app, entry.getValue());
-            }
-        }
-
-        if (rep.getScopeMappings() != null) {
-            for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
-                for (String roleString : scope.getRoles()) {
-                    RoleModel role = newRealm.getRole(roleString.trim());
-                    if (role == null) {
-                        role = newRealm.addRole(roleString.trim());
-                    }
-                    ClientModel client = newRealm.findClient(scope.getClient());
-                    client.addScopeMapping(role);
-                }
-
-            }
-        }
-
-        if (rep.getSmtpServer() != null) {
-            newRealm.setSmtpConfig(new HashMap(rep.getSmtpServer()));
-        }
-
-        if (rep.getSocialProviders() != null) {
-            newRealm.setSocialConfig(new HashMap(rep.getSocialProviders()));
-        }
-        if (rep.getLdapServer() != null) {
-            newRealm.setLdapServerConfig(new HashMap(rep.getLdapServer()));
-        }
-
-        if (rep.getAuthenticationProviders() != null) {
-            List<AuthenticationProviderModel> authProviderModels = convertAuthenticationProviders(rep.getAuthenticationProviders());
-            newRealm.setAuthenticationProviders(authProviderModels);
-        }  else {
-            List<AuthenticationProviderModel> authProviderModels = Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER);
-            newRealm.setAuthenticationProviders(authProviderModels);
-        }
-
-        // create users and their role mappings and social mappings
-
-        if (rep.getUsers() != null) {
-            for (UserRepresentation userRep : rep.getUsers()) {
-                UserModel user = createUser(newRealm, userRep, appMap);
-            }
-        }
-    }
-
-    public void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
-        if (roleRep.getComposites() == null) return;
-        if (roleRep.getComposites().getRealm() != null) {
-            for (String roleStr : roleRep.getComposites().getRealm()) {
-                RoleModel realmRole = realm.getRole(roleStr);
-                if (realmRole == null) throw new RuntimeException("Unable to find composite realm role: " + roleStr);
-                role.addCompositeRole(realmRole);
-            }
-        }
-        if (roleRep.getComposites().getApplication() != null) {
-            for (Map.Entry<String, List<String>> entry : roleRep.getComposites().getApplication().entrySet()) {
-                ApplicationModel app = realm.getApplicationByName(entry.getKey());
-                if (app == null) {
-                    throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName());
-                }
-                for (String roleStr : entry.getValue()) {
-                    RoleModel appRole = app.getRole(roleStr);
-                    if (appRole == null) throw new RuntimeException("Unable to find composite app role: " + roleStr);
-                    role.addCompositeRole(appRole);
-                }
-
-            }
-
-        }
-
-    }
-
-    public void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
-        RoleModel role = newRealm.addRole(roleRep.getName());
-        if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
-    }
-
-    public void createRole(RealmModel newRealm, ApplicationModel app, RoleRepresentation roleRep) {
-        RoleModel role = app.addRole(roleRep.getName());
-        if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
-    }
-
-
-    public UserModel createUser(RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
-        UserModel user = session.users().addUser(newRealm, userRep.getId(), userRep.getUsername(), false);
-        user.setEnabled(userRep.isEnabled());
-        user.setEmail(userRep.getEmail());
-        user.setFirstName(userRep.getFirstName());
-        user.setLastName(userRep.getLastName());
-        if (userRep.getAttributes() != null) {
-            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
-                user.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-        if (userRep.getRequiredActions() != null) {
-            for (String requiredAction : userRep.getRequiredActions()) {
-                user.addRequiredAction(RequiredAction.valueOf(requiredAction));
-            }
-        }
-        if (userRep.getCredentials() != null) {
-            for (CredentialRepresentation cred : userRep.getCredentials()) {
-                UserCredentialModel credential = fromRepresentation(cred);
-                user.updateCredential(credential);
-            }
-        }
-        if (userRep.getAuthenticationLink() != null) {
-            AuthenticationLinkRepresentation link = userRep.getAuthenticationLink();
-            AuthenticationLinkModel authLink = new AuthenticationLinkModel(link.getAuthProvider(), link.getAuthUserId());
-            user.setAuthenticationLink(authLink);
-        }
-        if (userRep.getSocialLinks() != null) {
-            for (SocialLinkRepresentation socialLink : userRep.getSocialLinks()) {
-                SocialLinkModel mappingModel = new SocialLinkModel(socialLink.getSocialProvider(), socialLink.getSocialUserId(), socialLink.getSocialUsername());
-                session.users().addSocialLink(newRealm, user, mappingModel);
-            }
-        }
-        if (userRep.getRealmRoles() != null) {
-            for (String roleString : userRep.getRealmRoles()) {
-                RoleModel role = newRealm.getRole(roleString.trim());
-                if (role == null) {
-                    role = newRealm.addRole(roleString.trim());
-                }
-                user.grantRole(role);
-            }
-        }
-        if (userRep.getApplicationRoles() != null) {
-            ApplicationManager manager = new ApplicationManager(this);
-            for (Map.Entry<String, List<String>> entry : userRep.getApplicationRoles().entrySet()) {
-                ApplicationModel app = appMap.get(entry.getKey());
-                if (app == null) {
-                    throw new RuntimeException("Unable to find application role mappings for app: " + entry.getKey());
-                }
-                manager.createRoleMappings(app, user, entry.getValue());
-            }
-        }
-        return user;
-    }
-
-    public static UserCredentialModel fromRepresentation(CredentialRepresentation cred) {
-        UserCredentialModel credential = new UserCredentialModel();
-        credential.setType(cred.getType());
-        credential.setValue(cred.getValue());
-        return credential;
+        RepresentationToModel.importRealm(session, rep, newRealm);
     }
 
     /**
@@ -608,37 +217,4 @@ public class RealmManager {
         return session.users().searchForUser(searchString.trim(), realmModel);
     }
 
-    public void addRequiredCredential(RealmModel newRealm, String requiredCred) {
-        newRealm.addRequiredCredential(requiredCred);
-    }
-
-    protected Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
-        Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
-        ApplicationManager manager = new ApplicationManager(this);
-        for (ApplicationRepresentation resourceRep : rep.getApplications()) {
-            ApplicationModel app = manager.createApplication(realm, resourceRep);
-            appMap.put(app.getName(), app);
-        }
-        return appMap;
-    }
-
-    protected void createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
-        OAuthClientManager manager = new OAuthClientManager(realm);
-        for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
-            OAuthClientModel app = manager.create(rep);
-        }
-    }
-
-    protected List<AuthenticationProviderModel> convertAuthenticationProviders(List<AuthenticationProviderRepresentation> authenticationProviders) {
-        List<AuthenticationProviderModel> result = new ArrayList<AuthenticationProviderModel>();
-
-        for (AuthenticationProviderRepresentation representation : authenticationProviders) {
-            AuthenticationProviderModel model = new AuthenticationProviderModel(representation.getProviderName(),
-                    representation.isPasswordUpdateSupported(), representation.getConfig());
-            result.add(model);
-        }
-        return result;
-    }
-
-
 }
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 a71c87c..57d229a 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -46,6 +46,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.TimeBasedOTP;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
@@ -53,7 +54,6 @@ import org.keycloak.services.ForbiddenException;
 import org.keycloak.services.managers.AppAuthManager;
 import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.OAuthRedirect;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index 2afdda7..e438faa 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -10,13 +10,15 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.adapters.action.SessionStats;
 import org.keycloak.representations.adapters.action.UserStats;
 import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 import org.keycloak.services.managers.ApplicationManager;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.resources.KeycloakApplication;
@@ -97,7 +99,7 @@ public class ApplicationResource {
 
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
         try {
-            applicationManager.updateApplication(rep, application);
+            RepresentationToModel.updateApplication(rep, application);
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Application " + rep.getName() + " already exists");
@@ -116,8 +118,7 @@ public class ApplicationResource {
     public ApplicationRepresentation getApplication() {
         auth.requireView();
 
-        ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
-        return applicationManager.toRepresentation(application);
+        return ModelToRepresentation.toRepresentation(application);
     }
 
 
@@ -184,7 +185,7 @@ public class ApplicationResource {
         auth.requireManage();
 
         logger.debug("regenerateSecret");
-        UserCredentialModel cred = new ApplicationManager().generateSecret(application);
+        UserCredentialModel cred = KeycloakModelUtils.generateSecret(application);
         CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred);
         return rep;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index f83bfc7..68926ec 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -8,9 +8,9 @@ import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.services.managers.ApplicationManager;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
@@ -60,12 +60,11 @@ public class ApplicationsResource {
 
         List<ApplicationRepresentation> rep = new ArrayList<ApplicationRepresentation>();
         List<ApplicationModel> applicationModels = realm.getApplications();
-        ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
 
         boolean view = auth.hasView();
         for (ApplicationModel applicationModel : applicationModels) {
             if (view) {
-                rep.add(resourceManager.toRepresentation(applicationModel));
+                rep.add(ModelToRepresentation.toRepresentation(applicationModel));
             } else {
                 ApplicationRepresentation app = new ApplicationRepresentation();
                 app.setName(applicationModel.getName());
@@ -87,9 +86,8 @@ public class ApplicationsResource {
     public Response createApplication(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) {
         auth.requireManage();
 
-        ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
         try {
-            ApplicationModel applicationModel = resourceManager.createApplication(realm, rep);
+            ApplicationModel applicationModel = RepresentationToModel.createApplication(realm, rep);
             return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getName()).build()).build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Application " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
index 9a9ebaa..1b8c0d9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
@@ -1,9 +1,9 @@
 package org.keycloak.services.resources.admin;
 
 import org.keycloak.models.ClientModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ClaimRepresentation;
-import org.keycloak.services.managers.ClaimManager;
-import org.keycloak.services.managers.ModelToRepresentation;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -47,6 +47,6 @@ public class ClaimResource {
     @Consumes(MediaType.APPLICATION_JSON)
     public void updateClaims(ClaimRepresentation rep) {
         auth.requireManage();
-        ClaimManager.setClaims(model, rep);
+        RepresentationToModel.setClaims(model, rep);
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index d8b6d65..84f1b88 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -8,9 +8,10 @@ import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.resources.KeycloakApplication;
@@ -82,9 +83,8 @@ public class OAuthClientResource  {
     public Response update(final OAuthClientRepresentation rep) {
         auth.requireManage();
 
-        OAuthClientManager manager = new OAuthClientManager(realm);
         try {
-            manager.update(rep, oauthClient);
+            RepresentationToModel.updateOAuthClient(rep, oauthClient);
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Client " + rep.getName() + " already exists");
@@ -102,7 +102,7 @@ public class OAuthClientResource  {
     public OAuthClientRepresentation getOAuthClient() {
         auth.requireView();
 
-        return OAuthClientManager.toRepresentation(oauthClient);
+        return ModelToRepresentation.toRepresentation(oauthClient);
     }
 
     /**
@@ -118,7 +118,7 @@ public class OAuthClientResource  {
     public String getInstallation() throws IOException {
         auth.requireView();
 
-        OAuthClientManager manager = new OAuthClientManager(realm);
+        OAuthClientManager manager = new OAuthClientManager();
         Object rep = manager.toInstallationRepresentation(realm, oauthClient, getApplication().getBaseUri(uriInfo));
 
         // TODO Temporary solution to pretty-print
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index f80a8c9..3bb4144 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -8,8 +8,9 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
-import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
@@ -65,7 +66,7 @@ public class OAuthClientsResource {
         boolean view = auth.hasView();
         for (OAuthClientModel oauth : oauthModels) {
             if (view) {
-                rep.add(OAuthClientManager.toRepresentation(oauth));
+                rep.add(ModelToRepresentation.toRepresentation(oauth));
             } else {
                 OAuthClientRepresentation client = new OAuthClientRepresentation();
                 client.setName(oauth.getClientId());
@@ -87,9 +88,8 @@ public class OAuthClientsResource {
     public Response createOAuthClient(final @Context UriInfo uriInfo, final OAuthClientRepresentation rep) {
         auth.requireManage();
 
-        OAuthClientManager resourceManager = new OAuthClientManager(realm);
         try {
-            OAuthClientModel oauth = resourceManager.create(rep);
+            OAuthClientModel oauth = RepresentationToModel.createOAuthClient(rep, realm);
             return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getId()).build()).build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Client " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 99d64e8..81e5db1 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -13,11 +13,12 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.adapters.action.SessionStats;
 import org.keycloak.representations.idm.RealmAuditRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.managers.LDAPConnectionTestManager;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.TokenManager;
@@ -138,7 +139,7 @@ public class RealmAdminResource {
 
         logger.debug("updating realm: " + realm.getName());
         try {
-            new RealmManager(session).updateRealm(rep, realm);
+            RepresentationToModel.updateRealm(rep, realm);
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
index 89d9ef3..e2ef922 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java
@@ -3,9 +3,6 @@ package org.keycloak.services.resources.admin;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.services.ForbiddenException;
-import org.keycloak.services.managers.Auth;
-
-import javax.ws.rs.WebApplicationException;
 
 
 /**
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
index 35f8176..e7d7046 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java
@@ -12,9 +12,9 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.services.ForbiddenException;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.TokenManager;
 import org.keycloak.services.resources.KeycloakApplication;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
index d1bb149..a4b6f58 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
@@ -2,13 +2,12 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
-import org.keycloak.models.Constants;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.resources.flows.Flows;
 
 import javax.ws.rs.Consumes;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
index 8ef17d8..52bfae9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java
@@ -4,8 +4,8 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
 
 import java.util.Collections;
 import java.util.HashSet;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
index 92b129c..9da9085 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java
@@ -7,12 +7,10 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
 import org.keycloak.representations.idm.MappingsRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
-import org.keycloak.services.managers.RealmManager;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index d9c4e64..ac35189 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -17,6 +17,8 @@ import org.keycloak.models.SocialLinkModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.adapters.action.UserStats;
 import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
@@ -26,7 +28,6 @@ import org.keycloak.representations.idm.SocialLinkRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 import org.keycloak.services.managers.AccessCodeEntry;
-import org.keycloak.services.managers.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.managers.TokenManager;
@@ -760,7 +761,7 @@ public class UsersResource {
             throw new BadRequestException("No password provided");
         }
 
-        UserCredentialModel cred = RealmManager.fromRepresentation(pass);
+        UserCredentialModel cred = RepresentationToModel.convertCredential(pass);
         user.updateCredential(cred);
         user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/Cors.java b/services/src/main/java/org/keycloak/services/resources/Cors.java
index c77b001..7689ea0 100755
--- a/services/src/main/java/org/keycloak/services/resources/Cors.java
+++ b/services/src/main/java/org/keycloak/services/resources/Cors.java
@@ -1,13 +1,5 @@
 package org.keycloak.services.resources;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.spi.HttpRequest;
 import org.jboss.resteasy.spi.HttpResponse;
@@ -15,6 +7,13 @@ import org.keycloak.models.ClientModel;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.util.CollectionUtil;
 
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java
index 37c0922..5091bc3 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/SocialRedirectFlows.java
@@ -3,18 +3,15 @@ package org.keycloak.services.resources.flows;
 import org.keycloak.jose.jws.JWSBuilder;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.SocialResource;
 import org.keycloak.services.util.CookieHelper;
 import org.keycloak.social.AuthRequest;
-import org.keycloak.social.UriBuilder;
 import org.keycloak.social.SocialProvider;
 import org.keycloak.social.SocialProviderConfig;
 import org.keycloak.social.SocialProviderException;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-import java.net.URI;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
index fa311fa..539674b 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java
@@ -22,10 +22,10 @@
 package org.keycloak.services.resources.flows;
 
 import org.keycloak.services.resources.AccountService;
-import org.keycloak.services.resources.ThemeResource;
 import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.services.resources.RequiredActionsService;
 import org.keycloak.services.resources.SocialResource;
+import org.keycloak.services.resources.ThemeResource;
 import org.keycloak.services.resources.TokenService;
 
 import javax.ws.rs.core.UriBuilder;
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index c868e3f..f4094af 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -7,7 +7,7 @@ import org.jboss.resteasy.core.Dispatcher;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.Config;
 import org.keycloak.SkeletonKeyContextResolver;
-import org.keycloak.exportimport.ExportImportProvider;
+import org.keycloak.exportimport.ExportImportManager;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
@@ -24,7 +24,6 @@ import org.keycloak.services.scheduled.ScheduledTaskRunner;
 import org.keycloak.services.util.JsonConfigProvider;
 import org.keycloak.timer.TimerProvider;
 import org.keycloak.util.JsonSerialization;
-import org.keycloak.util.ProviderLoader;
 
 import javax.servlet.ServletContext;
 import javax.ws.rs.core.Application;
@@ -38,7 +37,6 @@ import java.io.InputStream;
 import java.net.URI;
 import java.net.URL;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Set;
 import java.util.StringTokenizer;
 
@@ -81,7 +79,7 @@ public class KeycloakApplication extends Application {
         classes.add(JsResource.class);
         classes.add(WelcomeResource.class);
 
-        checkExportImportProvider();
+        new ExportImportManager().checkExportImport(this.sessionFactory);
 
         setupDefaultRealm(context.getContextPath());
 
@@ -235,16 +233,4 @@ public class KeycloakApplication extends Application {
         }
     }
 
-    protected void checkExportImportProvider() {
-        Iterator<ExportImportProvider> providers = ProviderLoader.load(ExportImportProvider.class).iterator();
-
-        if (providers.hasNext()) {
-            ExportImportProvider exportImport = providers.next();
-            exportImport.checkExportImport(sessionFactory);
-        } else {
-            log.warn("No ExportImportProvider found!");
-        }
-    }
-
-
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
index 097b25a..565303c 100755
--- a/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/PublicRealmResource.java
@@ -7,7 +7,6 @@ import org.keycloak.representations.idm.PublishedRealmRepresentation;
 import org.keycloak.services.resources.admin.AdminRoot;
 
 import javax.ws.rs.GET;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.UriInfo;
diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
index e66c000..85eabf5 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -28,6 +28,8 @@ import org.keycloak.audit.Audit;
 import org.keycloak.audit.Details;
 import org.keycloak.audit.Errors;
 import org.keycloak.audit.EventType;
+import org.keycloak.authentication.AuthenticationProviderException;
+import org.keycloak.authentication.AuthenticationProviderManager;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
 import org.keycloak.login.LoginFormsProvider;
@@ -48,8 +50,6 @@ import org.keycloak.services.messages.Messages;
 import org.keycloak.services.resources.flows.Flows;
 import org.keycloak.services.resources.flows.Urls;
 import org.keycloak.services.validation.Validation;
-import org.keycloak.authentication.AuthenticationProviderException;
-import org.keycloak.authentication.AuthenticationProviderManager;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 8aa68ff..dc7c937 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -21,7 +21,6 @@ import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakTransaction;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.UserCredentialModel;
diff --git a/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java b/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java
old mode 100644
new mode 100755
index 0eb1cef..785cc81
--- a/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java
+++ b/services/src/main/java/org/keycloak/services/util/JsonConfigProvider.java
@@ -4,8 +4,6 @@ import org.codehaus.jackson.JsonNode;
 import org.keycloak.Config;
 import org.keycloak.util.StringPropertyReplacer;
 
-import java.util.ArrayList;
-
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index acb145b..6507a5e 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -289,7 +289,17 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-export-import-impl</artifactId>
+            <artifactId>keycloak-export-import-dir</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-single-file</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-zip</artifactId>
             <version>${project.version}</version>
         </dependency>
 
diff --git a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
index f0c40b2..9c4ac85 100755
--- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
@@ -20,7 +20,11 @@
     },
 
     "modelCache": {
-        "provider": "${keycloak.model.cache.provider:simple}"
+        "provider": "${keycloak.model.cache.provider:mem}"
+    },
+
+    "userCache": {
+        "provider": "${keycloak.user.cache.provider:mem}"
     },
 
     "timer": {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
index cf46738..af4967d 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
@@ -33,6 +33,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.services.managers.ApplicationManager;
 import org.keycloak.services.managers.RealmManager;
@@ -59,7 +60,7 @@ public class CompositeRoleTest {
         @Override
         protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
             RealmModel realm = manager.createRealm("Test");
-            manager.generateRealmKeys(realm);
+            KeycloakModelUtils.generateRealmKeys(realm);
             realmPublicKey = realm.getPublicKey();
             realm.setSsoSessionIdleTimeout(3000);
             realm.setAccessTokenLifespan(10000);
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
new file mode 100755
index 0000000..548b5ef
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java
@@ -0,0 +1,386 @@
+package org.keycloak.testsuite.exportimport;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.keycloak.Config;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.dir.DirExportProvider;
+import org.keycloak.exportimport.dir.DirExportProviderFactory;
+import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
+import org.keycloak.exportimport.zip.ZipExportProviderFactory;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelProvider;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserProvider;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.rule.KeycloakRule;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class ExportImportTest {
+    /*
+
+    // We want data to be persisted among server restarts
+    private static ExternalResource hibernateSetupRule = new ExternalResource() {
+
+        private boolean setupDone = false;
+
+        @Override
+        protected void before() throws Throwable {
+            if (System.getProperty("hibernate.connection.url") == null) {
+                String baseExportImportDir = getExportImportTestDirectory();
+
+                File oldDBFile = new File(baseExportImportDir, "keycloakDB.h2.db");
+                if (oldDBFile.exists()) {
+                    oldDBFile.delete();
+                }
+
+                String dbDir = baseExportImportDir + "/keycloakDB";
+                System.setProperty("hibernate.connection.url", "jdbc:h2:file:" + dbDir + ";DB_CLOSE_DELAY=-1");
+                System.setProperty("hibernate.hbm2ddl.auto", "update");
+                setupDone = true;
+            }
+        }
+
+        @Override
+        protected void after() {
+            if (setupDone) {
+                Properties sysProps = System.getProperties();
+                sysProps.remove("hibernate.connection.url");
+                sysProps.remove("hibernate.hbm2ddl.auto");
+            }
+        }
+    };
+
+    // We want data to be persisted among server restarts
+    private static ExternalResource mongoRule = new ExternalResource() {
+
+        private static final String MONGO_CLEAR_ON_STARTUP_PROP_NAME = "keycloak.model.mongo.clearOnStartup";
+        private String previousMongoClearOnStartup;
+
+        @Override
+        protected void before() throws Throwable {
+            previousMongoClearOnStartup = System.getProperty(MONGO_CLEAR_ON_STARTUP_PROP_NAME);
+            System.setProperty(MONGO_CLEAR_ON_STARTUP_PROP_NAME, "false");
+        }
+
+        @Override
+        protected void after() {
+            if (previousMongoClearOnStartup != null) {
+                System.setProperty(MONGO_CLEAR_ON_STARTUP_PROP_NAME, "false");
+            } else {
+                System.getProperties().remove(MONGO_CLEAR_ON_STARTUP_PROP_NAME);
+            }
+        }
+
+    };
+
+    private static KeycloakRule keycloakRule = new KeycloakRule( new KeycloakRule.KeycloakSetup() {
+
+        @Override
+        public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+            addUser(manager.getSession().users(), appRealm, "user1", "password");
+            addUser(manager.getSession().users(), appRealm, "user2", "password");
+            addUser(manager.getSession().users(), appRealm, "user3", "password");
+            addUser(manager.getSession().users(), adminstrationRealm, "admin2", "admin2");
+        }
+
+
+
+    }) {
+        @Override
+        protected void after() {
+            {
+                KeycloakSession session = server.getSessionFactory().create();
+                session.getTransaction().begin();
+
+                try {
+                    RealmManager manager = new RealmManager(session);
+
+                    RealmModel adminstrationRealm = manager.getRealm(Config.getAdminRealm());
+                    RealmModel appRealm = manager.getRealm("test");
+                    boolean removed = session.users().removeUser(appRealm, "user1");
+                    removed = session.users().removeUser(appRealm, "user2");
+                    removed = session.users().removeUser(appRealm, "user3");
+                    removed = session.users().removeUser(adminstrationRealm, "admin2");
+
+                    session.getTransaction().commit();
+                } finally {
+                    session.close();
+                }
+            }
+            {
+                KeycloakSession session = server.getSessionFactory().create();
+                session.getTransaction().begin();
+
+                try {
+                    RealmManager manager = new RealmManager(session);
+
+                    RealmModel adminstrationRealm = manager.getRealm(Config.getAdminRealm());
+                    RealmModel appRealm = manager.getRealm("test");
+                    UserModel user1 = session.users().getUserByUsername("user1", appRealm);
+                    UserModel user2= session.users().getUserByUsername("user2", appRealm);
+                    UserModel user3 = session.users().getUserByUsername("user3", appRealm);
+                    UserModel admin2 = session.users().getUserByUsername("admin2", adminstrationRealm);
+                    Assert.assertNull(user1);
+                    Assert.assertNull(user2);
+                    Assert.assertNull(user3);
+                    Assert.assertNull(admin2);
+
+                    session.getTransaction().commit();
+                } finally {
+                    session.close();
+                }
+            }
+
+            super.after();
+        }
+    };
+
+    @ClassRule
+    public static TestRule chain = RuleChain
+            .outerRule(hibernateSetupRule)
+            .around(mongoRule)
+            .around(keycloakRule);
+
+    @Test
+    public void testDirFullExportImport() throws Throwable {
+        ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID);
+        String targetDirPath = getExportImportTestDirectory() + File.separator + "dirExport";
+        DirExportProvider.recursiveDeleteDir(new File(targetDirPath));
+        ExportImportConfig.setDir(targetDirPath);
+        ExportImportConfig.setUsersPerFile(ExportImportConfig.DEFAULT_USERS_PER_FILE);
+
+        testFullExportImport();
+
+        // There should be 4 files in target directory (2 realm, 2 user)
+        Assert.assertEquals(4, new File(targetDirPath).listFiles().length);
+    }
+
+    @Test
+    public void testDirRealmExportImport() throws Throwable {
+        ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID);
+        String targetDirPath = getExportImportTestDirectory() + File.separator + "dirRealmExport";
+        DirExportProvider.recursiveDeleteDir(new File(targetDirPath));
+        ExportImportConfig.setDir(targetDirPath);
+        ExportImportConfig.setUsersPerFile(3);
+
+        testRealmExportImport();
+
+        // There should be 3 files in target directory (1 realm, 2 user)
+        Assert.assertEquals(3, new File(targetDirPath).listFiles().length);
+    }
+
+    @Test
+    public void testSingleFileFullExportImport() throws Throwable {
+        ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID);
+        String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-full.json";
+        ExportImportConfig.setFile(targetFilePath);
+
+        testFullExportImport();
+    }
+
+    @Test
+    public void testSingleFileRealmExportImport() throws Throwable {
+        ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID);
+        String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-realm.json";
+        ExportImportConfig.setFile(targetFilePath);
+
+        testRealmExportImport();
+    }
+
+    @Test
+    public void testZipFullExportImport() throws Throwable {
+        ExportImportConfig.setProvider(ZipExportProviderFactory.PROVIDER_ID);
+        String zipFilePath = getExportImportTestDirectory() + File.separator + "export-full.zip";
+        new File(zipFilePath).delete();
+        ExportImportConfig.setZipFile(zipFilePath);
+        ExportImportConfig.setZipPassword("encPassword");
+        ExportImportConfig.setUsersPerFile(ExportImportConfig.DEFAULT_USERS_PER_FILE);
+
+        testFullExportImport();
+    }
+
+    @Test
+    public void testZipRealmExportImport() throws Throwable {
+        ExportImportConfig.setProvider(ZipExportProviderFactory.PROVIDER_ID);
+        String zipFilePath = getExportImportTestDirectory() + File.separator + "export-realm.zip";
+        new File(zipFilePath).delete();
+        ExportImportConfig.setZipFile(zipFilePath);
+        ExportImportConfig.setZipPassword("encPassword");
+        ExportImportConfig.setUsersPerFile(3);
+
+        testRealmExportImport();
+    }
+
+    private void testFullExportImport() {
+        ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT);
+        ExportImportConfig.setRealmName(null);
+
+        // Restart server, which triggers export
+        keycloakRule.restartServer();
+
+        // Delete some realm (and some data in admin realm)
+        KeycloakSession session = keycloakRule.startSession();
+        try {
+            ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
+            new RealmManager(session).removeRealm(model.getRealmByName("test"));
+            Assert.assertEquals(1, model.getRealms().size());
+
+            RealmModel master = model.getRealmByName(Config.getAdminRealm());
+            session.users().removeUser(master, "admin2");
+            assertNotAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertNotAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user1", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user2", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user3", "password");
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
+
+        // Configure import
+        ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT);
+
+        // Restart server, which triggers import
+        keycloakRule.restartServer();
+
+        // Ensure data are imported back
+        session = keycloakRule.startSession();
+        try {
+            ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
+            Assert.assertEquals(2, model.getRealms().size());
+
+            assertAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertAuthenticated(userProvider, model, "test", "user1", "password");
+            assertAuthenticated(userProvider, model, "test", "user2", "password");
+            assertAuthenticated(userProvider, model, "test", "user3", "password");
+
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
+    }
+
+    private void testRealmExportImport() {
+        ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT);
+        ExportImportConfig.setRealmName("test");
+
+        // Restart server, which triggers export
+        keycloakRule.restartServer();
+
+        // Delete some realm (and some data in admin realm)
+        KeycloakSession session = keycloakRule.startSession();
+        try {
+            ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
+            new RealmManager(session).removeRealm(model.getRealmByName("test"));
+            Assert.assertEquals(1, model.getRealms().size());
+
+            RealmModel master = model.getRealmByName(Config.getAdminRealm());
+            session.users().removeUser(master, "admin2");
+
+            assertNotAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertNotAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user1", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user2", "password");
+            assertNotAuthenticated(userProvider, model, "test", "user3", "password");
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
+
+        // Configure import
+        ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT);
+
+        // Restart server, which triggers import
+        keycloakRule.restartServer();
+
+        // Ensure data are imported back, but just for "test" realm
+        session = keycloakRule.startSession();
+        try {
+            ModelProvider model = session.model();
+            UserProvider userProvider = session.users();
+            Assert.assertEquals(2, model.getRealms().size());
+
+            assertNotAuthenticated(userProvider, model, Config.getAdminRealm(), "admin2", "admin2");
+            assertAuthenticated(userProvider, model, "test", "test-user@localhost", "password");
+            assertAuthenticated(userProvider, model, "test", "user1", "password");
+            assertAuthenticated(userProvider, model, "test", "user2", "password");
+            assertAuthenticated(userProvider, model, "test", "user3", "password");
+
+            addUser(userProvider, model.getRealmByName(Config.getAdminRealm()), "admin2", "admin2");
+        } finally {
+            keycloakRule.stopSession(session, true);
+        }
+    }
+
+    private void assertAuthenticated(UserProvider userProvider, ModelProvider model, String realmName, String username, String password) {
+        RealmModel realm = model.getRealmByName(realmName);
+        if (realm == null) {
+            Assert.fail("realm " + realmName + " not found");
+        }
+
+        UserModel user = userProvider.getUserByUsername(username, realm);
+        if (user == null) {
+            Assert.fail("user " + username + " not found");
+        }
+
+        Assert.assertTrue(realm.validatePassword(user, password));
+    }
+
+    private void assertNotAuthenticated(UserProvider userProvider, ModelProvider model, String realmName, String username, String password) {
+        RealmModel realm = model.getRealmByName(realmName);
+        if (realm == null) {
+            return;
+        }
+
+        UserModel user = userProvider.getUserByUsername(username, realm);
+        if (user == null) {
+            return;
+        }
+
+        Assert.assertFalse(realm.validatePassword(user, password));
+    }
+
+    private static void addUser(UserProvider userProvider, RealmModel appRealm, String username, String password) {
+        UserModel user = userProvider.addUser(appRealm, username);
+        user.setEmail(username + "@test.com");
+        user.setEnabled(true);
+
+        UserCredentialModel creds = new UserCredentialModel();
+        creds.setType(CredentialRepresentation.PASSWORD);
+        creds.setValue(password);
+        user.updateCredential(creds);
+    }
+
+    private static String getExportImportTestDirectory() {
+        String dirPath = null;
+        String relativeDirExportImportPath = "testsuite" + File.separator + "integration" + File.separator + "target" + File.separator + "export-import";
+
+        if (System.getProperties().containsKey("maven.home")) {
+            dirPath = System.getProperty("user.dir").replaceFirst("testsuite.integration.*", relativeDirExportImportPath);
+        } else {
+            for (String c : System.getProperty("java.class.path").split(File.pathSeparator)) {
+                if (c.contains(File.separator + "testsuite" + File.separator + "integration")) {
+                    dirPath = c.replaceFirst("testsuite.integration.*", relativeDirExportImportPath);
+                }
+            }
+        }
+
+        String absolutePath = new File(dirPath).getAbsolutePath();
+        return absolutePath;
+    }
+    */
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
index 03b9086..947551e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java
@@ -91,7 +91,9 @@ public class OAuthGrantTest {
 
         OAuthClient.AccessTokenResponse accessToken = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "password");
 
-        AccessToken token = oauth.verifyToken(accessToken.getAccessToken());
+        String tokenString = accessToken.getAccessToken();
+        Assert.assertNotNull(tokenString);
+        AccessToken token = oauth.verifyToken(tokenString);
         assertEquals(sessionId, token.getSessionState());
 
         AccessToken.Access realmAccess = token.getRealmAccess();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
index eac0cee..3bcbe61 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java
@@ -12,7 +12,7 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.services.managers.ModelToRepresentation;
+import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testutils.KeycloakServer;
 import org.keycloak.util.JsonSerialization;
@@ -148,4 +148,13 @@ public abstract class AbstractKeycloakRule extends ExternalResource {
         }
         session.close();
     }
+
+    public void restartServer() {
+        try {
+            server.stop();
+            server.start();
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
 }
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
index 8deadb7..14a106c 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java
@@ -6,6 +6,7 @@ import org.apache.log.Logger;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.managers.RealmManager;
 
@@ -77,9 +78,9 @@ public class CreateRealmsWorker implements Worker {
 
         // Add required credentials
         if (createRequiredCredentials) {
-            realmManager.addRequiredCredential(realm, CredentialRepresentation.PASSWORD);
-            realmManager.addRequiredCredential(realm, CredentialRepresentation.TOTP);
-            realmManager.addRequiredCredential(realm, CredentialRepresentation.CLIENT_CERT);
+            RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.PASSWORD);
+            RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.TOTP);
+            RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.CLIENT_CERT);
         }
 
         log.info("Finished creation of realm " + realmName);
diff --git a/testsuite/tools/pom.xml b/testsuite/tools/pom.xml
index c630624..d3b9867 100755
--- a/testsuite/tools/pom.xml
+++ b/testsuite/tools/pom.xml
@@ -283,7 +283,17 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-export-import-impl</artifactId>
+            <artifactId>keycloak-export-import-dir</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-zip</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-export-import-single-file</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
index ab5735a..504fba3 100755
--- a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
+++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java
@@ -1,7 +1,8 @@
 package org.keycloak.test.tools;
 
 import org.keycloak.exportimport.ExportImportConfig;
-import org.keycloak.exportimport.ExportImportProvider;
+import org.keycloak.exportimport.ExportImportManager;
+import org.keycloak.exportimport.ExportProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
@@ -231,14 +232,7 @@ public class PerfTools {
         ExportImportConfig.setProvider("dir");
         ExportImportConfig.setDir(dir);
 
-        Iterator<ExportImportProvider> providers = ProviderLoader.load(ExportImportProvider.class).iterator();
-
-        if (providers.hasNext()) {
-            ExportImportProvider exportImport = providers.next();
-            exportImport.checkExportImport(sessionFactory);
-        } else {
-            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
-        }
+        new ExportImportManager().checkExportImport(sessionFactory);
     }
 
     public static class JobRepresentation {