keycloak-aplcache

merge

5/18/2015 5:41:51 PM

Changes

distribution/server-dist/src/main/xslt/standalone.xsl 61(+0 -61)

integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/Environment.java 58(+0 -58)

integration/keycloak-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessorEAP6.java 132(+0 -132)

integration/keycloak-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension 1(+0 -1)

pom.xml 208(+200 -8)

Details

diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java
index e660700..44fb65d 100755
--- a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderMapperSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class IdentityProviderMapperSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return false;
+    }
+
+    @Override
     public String getName() {
         return "identity-provider-mapper";
     }
diff --git a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderSpi.java b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderSpi.java
index de9872a..b507e55 100644
--- a/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderSpi.java
+++ b/broker/core/src/main/java/org/keycloak/broker/provider/IdentityProviderSpi.java
@@ -29,6 +29,11 @@ public class IdentityProviderSpi implements Spi {
     public static final String IDENTITY_PROVIDER_SPI_NAME = "identity_provider";
 
     @Override
+    public boolean isPrivate() {
+        return false;
+    }
+
+    @Override
     public String getName() {
         return IDENTITY_PROVIDER_SPI_NAME;
     }
diff --git a/connections/file/src/main/java/org/keycloak/connections/file/FileConnectionSpi.java b/connections/file/src/main/java/org/keycloak/connections/file/FileConnectionSpi.java
index 4558be3..ec64192 100644
--- a/connections/file/src/main/java/org/keycloak/connections/file/FileConnectionSpi.java
+++ b/connections/file/src/main/java/org/keycloak/connections/file/FileConnectionSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class FileConnectionSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsFile";
     }
diff --git a/connections/http-client/src/main/java/org/keycloak/connections/httpclient/HttpClientSpi.java b/connections/http-client/src/main/java/org/keycloak/connections/httpclient/HttpClientSpi.java
index d9f4228..510b164 100755
--- a/connections/http-client/src/main/java/org/keycloak/connections/httpclient/HttpClientSpi.java
+++ b/connections/http-client/src/main/java/org/keycloak/connections/httpclient/HttpClientSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class HttpClientSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsHttpClient";
     }
diff --git a/connections/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionSpi.java b/connections/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionSpi.java
index 71f915d..f76c070 100644
--- a/connections/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionSpi.java
+++ b/connections/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class InfinispanConnectionSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsInfinispan";
     }
diff --git a/connections/jpa/src/main/java/org/keycloak/connections/jpa/JpaConnectionSpi.java b/connections/jpa/src/main/java/org/keycloak/connections/jpa/JpaConnectionSpi.java
index 83859ab..d565357 100644
--- a/connections/jpa/src/main/java/org/keycloak/connections/jpa/JpaConnectionSpi.java
+++ b/connections/jpa/src/main/java/org/keycloak/connections/jpa/JpaConnectionSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class JpaConnectionSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsJpa";
     }
diff --git a/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterSpi.java b/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterSpi.java
index e95242a..c9bd8ee 100644
--- a/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterSpi.java
+++ b/connections/jpa/src/main/java/org/keycloak/connections/jpa/updater/JpaUpdaterSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class JpaUpdaterSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsJpaUpdater";
     }
diff --git a/connections/jpa/src/main/resources/META-INF/persistence.xml b/connections/jpa/src/main/resources/META-INF/persistence.xml
index 55ff7f0..5bcb77e 100755
--- a/connections/jpa/src/main/resources/META-INF/persistence.xml
+++ b/connections/jpa/src/main/resources/META-INF/persistence.xml
@@ -35,9 +35,10 @@
         <class>org.keycloak.models.sessions.jpa.entities.UserSessionEntity</class>
         <class>org.keycloak.models.sessions.jpa.entities.UsernameLoginFailureEntity</class>
 
-        <!-- JpaAuditProvider -->
+        <!-- JpaAuditProviders -->
         <class>org.keycloak.events.jpa.EventEntity</class>
-
+        <class>org.keycloak.events.jpa.AdminEventEntity</class>
+        
         <exclude-unlisted-classes>true</exclude-unlisted-classes>
 
         <properties>
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml
new file mode 100755
index 0000000..7ee7763
--- /dev/null
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Final.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
+    <changeSet author="keycloak" id="1.2.0.Final">
+        <!-- KEYCLOAK-1277 -->
+        <update tableName="CLIENT">
+            <column name="DIRECT_GRANTS_ONLY" valueBoolean="false"/>
+            <where>DIRECT_GRANTS_ONLY is null</where>
+        </update>
+        <update tableName="CLIENT">
+            <column name="BEARER_ONLY" valueBoolean="false"/>
+            <where>BEARER_ONLY is null</where>
+        </update>
+        <update tableName="CLIENT">
+            <column name="SURROGATE_AUTH_REQUIRED" valueBoolean="false"/>
+            <where>SURROGATE_AUTH_REQUIRED is null</where>
+        </update>
+    </changeSet>
+</databaseChangeLog>
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml
index 50e8a48..27869eb 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml
@@ -6,6 +6,29 @@
         <delete tableName="CLIENT_SESSION"/>
         <delete tableName="USER_SESSION_NOTE"/>
         <delete tableName="USER_SESSION"/>
+        <createTable tableName="ADMIN_EVENT_ENTITY">
+            <column name="ID" type="VARCHAR(36)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="ADMIN_EVENT_TIME" type="BIGINT"/>
+            <column name="REALM_ID" type="VARCHAR(255)"/>
+            <column name="OPERATION_TYPE" type="VARCHAR(255)"/>
+            <column name="AUTH_REALM_ID" type="VARCHAR(255)"/>
+            <column name="AUTH_CLIENT_ID" type="VARCHAR(255)"/>
+            <column name="AUTH_USER_ID" type="VARCHAR(255)"/>
+            <column name="IP_ADDRESS" type="VARCHAR(255)"/>
+            <column name="RESOURCE_PATH" type="VARCHAR(2550)"/>
+            <column name="REPRESENTATION" type="VARCHAR(25500)"/>
+            <column name="ERROR" type="VARCHAR(255)"/>
+        </createTable>
+        <addColumn tableName="REALM">
+            <column name="ADMIN_EVENTS_ENABLED" type="BOOLEAN" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
+            <column name="ADMIN_EVENTS_DETAILS_ENABLED" type="BOOLEAN" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
+        </addColumn>
         <createTable tableName="CLIENT_SESSION_AUTH_STATUS">
             <column name="AUTHENTICATOR" type="VARCHAR(32)">
                 <constraints nullable="false"/>
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
index 8272af8..76c4507 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-master.xml
@@ -5,5 +5,6 @@
     <include file="META-INF/jpa-changelog-1.1.0.Final.xml"/>
     <include file="META-INF/jpa-changelog-1.2.0.Beta1.xml"/>
     <include file="META-INF/jpa-changelog-1.2.0.CR1.xml"/>
+    <include file="META-INF/jpa-changelog-1.2.0.Final.xml"/>
     <include file="META-INF/jpa-changelog-1.3.0.Beta1.xml"/>
 </databaseChangeLog>
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/MongoConnectionSpi.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/MongoConnectionSpi.java
index 031076d..f391dfd 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/MongoConnectionSpi.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/MongoConnectionSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class MongoConnectionSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsMongo";
     }
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterSpi.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterSpi.java
index da89b4d..830aaa3 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterSpi.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class MongoUpdaterSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "connectionsMongoUpdater";
     }
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java
index a88a75d..5b39f7e 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java
@@ -11,6 +11,9 @@ public class RealmEventsConfigRepresentation {
     protected Long eventsExpiration;
     protected List<String> eventsListeners;
     protected List<String> enabledEventTypes;
+    
+    protected Boolean adminEventsEnabled;
+    protected Boolean adminEventsDetailsEnabled;
 
     public boolean isEventsEnabled() {
         return eventsEnabled;
@@ -43,4 +46,21 @@ public class RealmEventsConfigRepresentation {
     public void setEnabledEventTypes(List<String> enabledEventTypes) {
         this.enabledEventTypes = enabledEventTypes;
     }
+
+    public Boolean isAdminEventsEnabled() {
+        return adminEventsEnabled;
+    }
+
+    public void setAdminEventsEnabled(Boolean adminEventsEnabled) {
+        this.adminEventsEnabled = adminEventsEnabled;
+    }
+
+    public Boolean isAdminEventsDetailsEnabled() {
+        return adminEventsDetailsEnabled;
+    }
+
+    public void setAdminEventsDetailsEnabled(Boolean adminEventsDetailsEnabled) {
+        this.adminEventsDetailsEnabled = adminEventsDetailsEnabled;
+    }
+    
 }
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 d9926fe..0240a8d 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -57,10 +57,15 @@ public class RealmRepresentation {
     protected String accountTheme;
     protected String adminTheme;
     protected String emailTheme;
+    
     protected Boolean eventsEnabled;
     protected Long eventsExpiration;
     protected List<String> eventsListeners;
     protected List<String> enabledEventTypes;
+    
+    protected Boolean adminEventsEnabled;
+    protected Boolean adminEventsDetailsEnabled;
+    
     private List<IdentityProviderRepresentation> identityProviders;
     private List<IdentityProviderMapperRepresentation> identityProviderMappers;
     private List<ProtocolMapperRepresentation> protocolMappers;
@@ -507,6 +512,22 @@ public class RealmRepresentation {
         this.enabledEventTypes = enabledEventTypes;
     }
 
+    public Boolean isAdminEventsEnabled() {
+        return adminEventsEnabled;
+    }
+
+    public void setAdminEventsEnabled(Boolean adminEventsEnabled) {
+        this.adminEventsEnabled = adminEventsEnabled;
+    }
+
+    public Boolean isAdminEventsDetailsEnabled() {
+        return adminEventsDetailsEnabled;
+    }
+
+    public void setAdminEventsDetailsEnabled(Boolean adminEventsDetailsEnabled) {
+        this.adminEventsDetailsEnabled = adminEventsDetailsEnabled;
+    }
+
     public List<UserFederationProviderRepresentation> getUserFederationProviders() {
         return userFederationProviders;
     }
diff --git a/core/src/main/java/org/keycloak/util/SystemEnvProperties.java b/core/src/main/java/org/keycloak/util/SystemEnvProperties.java
new file mode 100644
index 0000000..1e54b52
--- /dev/null
+++ b/core/src/main/java/org/keycloak/util/SystemEnvProperties.java
@@ -0,0 +1,25 @@
+package org.keycloak.util;
+
+import java.util.Properties;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class SystemEnvProperties extends Properties {
+
+    @Override
+    public String getProperty(String key) {
+        if (key.startsWith("env.")) {
+            return System.getenv().get(key.substring(4));
+        } else {
+            return System.getProperty(key);
+        }
+    }
+
+    @Override
+    public String getProperty(String key, String defaultValue) {
+        String value = getProperty(key);
+        return value != null ? value : defaultValue;
+    }
+
+}
diff --git a/core/src/main/java/org/keycloak/util/SystemPropertiesJsonParserFactory.java b/core/src/main/java/org/keycloak/util/SystemPropertiesJsonParserFactory.java
index 52f893d..a09a91b 100644
--- a/core/src/main/java/org/keycloak/util/SystemPropertiesJsonParserFactory.java
+++ b/core/src/main/java/org/keycloak/util/SystemPropertiesJsonParserFactory.java
@@ -3,6 +3,8 @@ package org.keycloak.util;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
+import java.util.Map;
+import java.util.Properties;
 
 import org.codehaus.jackson.JsonParser;
 import org.codehaus.jackson.io.IOContext;
@@ -16,6 +18,8 @@ import org.codehaus.jackson.util.JsonParserDelegate;
  */
 public class SystemPropertiesJsonParserFactory extends MappingJsonFactory {
 
+    private static final Properties properties = new SystemEnvProperties();
+
     @Override
     protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) throws IOException {
         JsonParser delegate = super._createJsonParser(data, offset, len, ctxt);
@@ -34,8 +38,6 @@ public class SystemPropertiesJsonParserFactory extends MappingJsonFactory {
         return new SystemPropertiesAwareJsonParser(delegate);
     }
 
-
-
     public static class SystemPropertiesAwareJsonParser extends JsonParserDelegate {
 
         public SystemPropertiesAwareJsonParser(JsonParser d) {
@@ -45,7 +47,7 @@ public class SystemPropertiesJsonParserFactory extends MappingJsonFactory {
         @Override
         public String getText() throws IOException {
             String orig = super.getText();
-            return StringPropertyReplacer.replaceProperties(orig);
+            return StringPropertyReplacer.replaceProperties(orig, properties);
         }
     }
 }
diff --git a/distribution/feature-pack-builds/adapter-only/adapter-only-build/assembly.xml b/distribution/feature-pack-builds/adapter-only/adapter-only-build/assembly.xml
new file mode 100644
index 0000000..704449a
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/adapter-only-build/assembly.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>thin-server</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target</directory>
+            <outputDirectory/>
+            <includes>
+                <include>${project.build.finalName}/**</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-pack-builds/adapter-only/adapter-only-build/pom.xml b/distribution/feature-pack-builds/adapter-only/adapter-only-build/pom.xml
new file mode 100644
index 0000000..95f05ec
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/adapter-only-build/pom.xml
@@ -0,0 +1,88 @@
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2015 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>adapter-only-builds</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-adapter-only-build</artifactId>
+
+    <name>Keycloak WildFly Build: Adapter Only</name>
+    <packaging>pom</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-adapter-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.wildfly.build</groupId>
+                <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>server-provisioning</id>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <phase>compile</phase>
+                        <configuration>
+                            <config-file>server-provisioning.xml</config-file>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>assembly.xml</descriptor>
+                            </descriptors>
+                            <recompressZippedFiles>true</recompressZippedFiles>
+                            <finalName>${project.build.finalName}</finalName>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <outputDirectory>${project.build.directory}</outputDirectory>
+                            <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+                            <tarLongFileMode>gnu</tarLongFileMode>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/distribution/feature-pack-builds/adapter-only/adapter-only-build/server-provisioning.xml b/distribution/feature-pack-builds/adapter-only/adapter-only-build/server-provisioning.xml
new file mode 100644
index 0000000..13de0ef
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/adapter-only-build/server-provisioning.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2015 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0">
+    <feature-packs>
+        <!-- uncomment wildfly-feature-pack to build against wildfly full instead of wildfly web -->
+        <!--<feature-pack groupId="org.wildfly" artifactId="wildfly-feature-pack" version="${wildfly.version}"/>-->
+        
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-adapter-feature-pack" version="${project.version}"/>
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/feature-pack-builds/adapter-only/adapter-only-dist/assembly.xml b/distribution/feature-pack-builds/adapter-only/adapter-only-dist/assembly.xml
new file mode 100644
index 0000000..704449a
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/adapter-only-dist/assembly.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>thin-server</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target</directory>
+            <outputDirectory/>
+            <includes>
+                <include>${project.build.finalName}/**</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-pack-builds/adapter-only/adapter-only-dist/pom.xml b/distribution/feature-pack-builds/adapter-only/adapter-only-dist/pom.xml
new file mode 100644
index 0000000..4f1ca1a
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/adapter-only-dist/pom.xml
@@ -0,0 +1,92 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>adapter-only-builds</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-adapter-only-dist</artifactId>
+
+    <name>Keycloak WildFly Dist: Adapter Only</name>
+    <packaging>pom</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-adapter-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+    
+    <profiles>
+        <profile>
+            <id>jboss-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.wildfly.build</groupId>
+                        <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>server-provisioning</id>
+                                <goals>
+                                    <goal>build</goal>
+                                </goals>
+                                <phase>compile</phase>
+                                <configuration>
+                                    <config-file>server-provisioning.xml</config-file>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>assemble</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptors>
+                                        <descriptor>assembly.xml</descriptor>
+                                    </descriptors>
+                                    <recompressZippedFiles>true</recompressZippedFiles>
+                                    <finalName>${project.build.finalName}</finalName>
+                                    <appendAssemblyId>false</appendAssemblyId>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                    <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+                                    <tarLongFileMode>gnu</tarLongFileMode>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/distribution/feature-pack-builds/adapter-only/adapter-only-dist/server-provisioning.xml b/distribution/feature-pack-builds/adapter-only/adapter-only-dist/server-provisioning.xml
new file mode 100644
index 0000000..b9f46bc
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/adapter-only-dist/server-provisioning.xml
@@ -0,0 +1,25 @@
+ <!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2015 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0" extract-schemas="true" copy-module-artifacts="true">
+    <feature-packs>
+        <!-- uncomment wildfly-feature-pack to build against wildfly full instead of wildfly web -->
+        <!--<feature-pack groupId="org.wildfly" artifactId="wildfly-feature-pack" version="${wildfly.version}"/>-->
+        
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-adapter-feature-pack" version="${project.version}"/>
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/feature-pack-builds/adapter-only/pom.xml b/distribution/feature-pack-builds/adapter-only/pom.xml
new file mode 100644
index 0000000..bd57e0b
--- /dev/null
+++ b/distribution/feature-pack-builds/adapter-only/pom.xml
@@ -0,0 +1,21 @@
+<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>feature-pack-builds</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <name>Adapter Only Builds</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>adapter-only-builds</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>adapter-feature-pack</module>
+        <module>adapter-only-build</module>
+        <module>adapter-only-dist</module>
+    </modules>
+</project>
diff --git a/distribution/feature-pack-builds/pom.xml b/distribution/feature-pack-builds/pom.xml
new file mode 100644
index 0000000..a35b3f7
--- /dev/null
+++ b/distribution/feature-pack-builds/pom.xml
@@ -0,0 +1,21 @@
+<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>distribution-pom</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <name>Feature Pack Builds</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>feature-pack-builds</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>adapter-only</module>
+        <module>server-only</module>
+        <module>server-and-adapter</module>
+    </modules>
+</project>
diff --git a/distribution/feature-pack-builds/README.md b/distribution/feature-pack-builds/README.md
new file mode 100644
index 0000000..fe4c55a
--- /dev/null
+++ b/distribution/feature-pack-builds/README.md
@@ -0,0 +1,25 @@
+Keycloak Feature Pack Builds
+============================
+
+The feature pack builds rely on WildFly Feature packs to create different combinations
+of Keycloak server/adapter and WildFly web/full.
+
+Types of Builds Created
+--------------------
+The three directories under feature-pack-builds are _adapter-only_, _server-only_, and _server-and-adapter_.
+
+* **adapter-only** - A WildFly server with the Keycloak adapter subsystem added.  This build is based on the WildFly Web Feature Pack.  **keycloak-adapter-feature-pack** contains all the modules needed to run the Keycloak WildFly Adapter.  Therefore, the build is _org.wildfly:wildfly-web-feature-pack_ + _org.keycloak:keycloak-adapter-feature-pack_.
+* **server-only** - A WildFly server with the Keycloak adapter subsystem added.  This build is based on the WildFly Full Feature Pack.  **keycloak-server-feature-pack** contains all the modules needed to run the Keycloak Server without those already provided by the full WildFly Server.  Therefore, the build is _org.wildfly:wildfly-feature-pack_ + _org.keycloak:keycloak-server-feature-pack_.
+* **server-and-adapter** is the same thing as **server-only** except it also includes **keycloak-adapter-feature-pack**.  Therefore, the build is  _org.wildfly:wildfly-feature-pack_ + _org.keycloak:keycloak-server-feature-pack_ + _org.keycloak:keycloak-adapter-feature-pack_.
+
+Building
+--------
+Each of the three types of builds in turn creates a build version and a dist version.  
+
+The build version is a server that uses the new WildFly 9 feature whereby maven artifacts are not bundled with the server.  Instead, they are looked up in a repository.  
+
+For the dist version, these artifacts are copied into the server itself and no maven repo is required.
+
+By default, the dist version does not get built.  To build it, specify the jboss-release profile:
+
+_mvn install -Pjboss-release_
diff --git a/distribution/feature-pack-builds/server-and-adapter/pom.xml b/distribution/feature-pack-builds/server-and-adapter/pom.xml
new file mode 100644
index 0000000..9616217
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/pom.xml
@@ -0,0 +1,20 @@
+<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>feature-pack-builds</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <name>Builds with both server and adapter</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>server-and-adapter</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>server-and-adapter-build</module>
+        <module>server-and-adapter-dist</module>
+    </modules>
+</project>
diff --git a/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/assembly.xml b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/assembly.xml
new file mode 100644
index 0000000..704449a
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/assembly.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>thin-server</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target</directory>
+            <outputDirectory/>
+            <includes>
+                <include>${project.build.finalName}/**</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/pom.xml b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/pom.xml
new file mode 100644
index 0000000..2bc3a0a
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/pom.xml
@@ -0,0 +1,93 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>server-and-adapter</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-server-and-adapter-build</artifactId>
+
+    <name>Keycloak WildFly Build: Server and Adapter</name>
+    <packaging>pom</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-adapter-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.wildfly.build</groupId>
+                <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>server-provisioning</id>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <phase>compile</phase>
+                        <configuration>
+                            <config-file>server-provisioning.xml</config-file>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>assembly.xml</descriptor>
+                            </descriptors>
+                            <recompressZippedFiles>true</recompressZippedFiles>
+                            <finalName>${project.build.finalName}</finalName>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <outputDirectory>${project.build.directory}</outputDirectory>
+                            <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+                            <tarLongFileMode>gnu</tarLongFileMode>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/server-provisioning.xml b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/server-provisioning.xml
new file mode 100644
index 0000000..f83f517
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-build/server-provisioning.xml
@@ -0,0 +1,23 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0">
+    <feature-packs>
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>     
+	  <feature-pack groupId="org.keycloak" artifactId="keycloak-adapter-feature-pack" version="${project.version}"/>     
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/assembly.xml b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/assembly.xml
new file mode 100644
index 0000000..704449a
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/assembly.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>thin-server</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target</directory>
+            <outputDirectory/>
+            <includes>
+                <include>${project.build.finalName}/**</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/pom.xml b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/pom.xml
new file mode 100644
index 0000000..4a492fd
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/pom.xml
@@ -0,0 +1,98 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>server-and-adapter</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-server-and-adapter-dist</artifactId>
+
+    <name>Keycloak WildFly Dist: Server and Adapter</name>
+    <packaging>pom</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-adapter-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>jboss-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.wildfly.build</groupId>
+                        <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>server-provisioning</id>
+                                <goals>
+                                    <goal>build</goal>
+                                </goals>
+                                <phase>compile</phase>
+                                <configuration>
+                                    <config-file>server-provisioning.xml</config-file>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>assemble</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptors>
+                                        <descriptor>assembly.xml</descriptor>
+                                    </descriptors>
+                                    <recompressZippedFiles>true</recompressZippedFiles>
+                                    <finalName>${project.build.finalName}</finalName>
+                                    <appendAssemblyId>false</appendAssemblyId>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                    <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+                                    <tarLongFileMode>gnu</tarLongFileMode>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/server-provisioning.xml b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/server-provisioning.xml
new file mode 100644
index 0000000..83253d7
--- /dev/null
+++ b/distribution/feature-pack-builds/server-and-adapter/server-and-adapter-dist/server-provisioning.xml
@@ -0,0 +1,23 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0" extract-schemas="true" copy-module-artifacts="true">
+    <feature-packs>
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>     
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-adapter-feature-pack" version="${project.version}"/>     
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/feature-pack-builds/server-only/pom.xml b/distribution/feature-pack-builds/server-only/pom.xml
new file mode 100644
index 0000000..af41711
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/pom.xml
@@ -0,0 +1,21 @@
+<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>feature-pack-builds</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <name>Server Only Builds</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>server-only-builds</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>server-feature-pack</module>
+        <module>server-only-build</module>
+        <module>server-only-dist</module>
+    </modules>
+</project>
diff --git a/distribution/feature-pack-builds/server-only/server-only-build/assembly.xml b/distribution/feature-pack-builds/server-only/server-only-build/assembly.xml
new file mode 100644
index 0000000..704449a
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/server-only-build/assembly.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>thin-server</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target</directory>
+            <outputDirectory/>
+            <includes>
+                <include>${project.build.finalName}/**</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-pack-builds/server-only/server-only-build/pom.xml b/distribution/feature-pack-builds/server-only/server-only-build/pom.xml
new file mode 100644
index 0000000..5d88347
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/server-only-build/pom.xml
@@ -0,0 +1,87 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>server-only-builds</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-server-only-build</artifactId>
+
+    <name>Keycloak WildFly Build: Server Only</name>
+    <packaging>pom</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.wildfly.build</groupId>
+                <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>server-provisioning</id>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <phase>compile</phase>
+                        <configuration>
+                            <config-file>server-provisioning.xml</config-file>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>assembly.xml</descriptor>
+                            </descriptors>
+                            <recompressZippedFiles>true</recompressZippedFiles>
+                            <finalName>${project.build.finalName}</finalName>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <outputDirectory>${project.build.directory}</outputDirectory>
+                            <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+                            <tarLongFileMode>gnu</tarLongFileMode>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/distribution/feature-pack-builds/server-only/server-only-build/server-provisioning.xml b/distribution/feature-pack-builds/server-only/server-only-build/server-provisioning.xml
new file mode 100644
index 0000000..9e4b4f3
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/server-only-build/server-provisioning.xml
@@ -0,0 +1,22 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0">
+    <feature-packs>
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>     
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/feature-pack-builds/server-only/server-only-dist/assembly.xml b/distribution/feature-pack-builds/server-only/server-only-dist/assembly.xml
new file mode 100644
index 0000000..1d7cc51
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/server-only-dist/assembly.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>full-server</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target</directory>
+            <outputDirectory/>
+            <includes>
+                <include>${project.build.finalName}/**</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-pack-builds/server-only/server-only-dist/pom.xml b/distribution/feature-pack-builds/server-only/server-only-dist/pom.xml
new file mode 100644
index 0000000..4f13fbc
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/server-only-dist/pom.xml
@@ -0,0 +1,92 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>server-only-builds</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-server-only-dist</artifactId>
+
+    <name>Keycloak WildFly Dist: Server Only</name>
+    <packaging>pom</packaging>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-feature-pack</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>jboss-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.wildfly.build</groupId>
+                        <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>server-provisioning</id>
+                                <goals>
+                                    <goal>build</goal>
+                                </goals>
+                                <phase>compile</phase>
+                                <configuration>
+                                    <config-file>server-provisioning.xml</config-file>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>assemble</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptors>
+                                        <descriptor>assembly.xml</descriptor>
+                                    </descriptors>
+                                    <recompressZippedFiles>true</recompressZippedFiles>
+                                    <finalName>${project.build.finalName}</finalName>
+                                    <appendAssemblyId>false</appendAssemblyId>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                    <workDirectory>${project.build.directory}/assembly/work</workDirectory>
+                                    <tarLongFileMode>gnu</tarLongFileMode>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/distribution/feature-pack-builds/server-only/server-only-dist/server-provisioning.xml b/distribution/feature-pack-builds/server-only/server-only-dist/server-provisioning.xml
new file mode 100644
index 0000000..d414b95
--- /dev/null
+++ b/distribution/feature-pack-builds/server-only/server-only-dist/server-provisioning.xml
@@ -0,0 +1,22 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0" extract-schemas="true" copy-module-artifacts="true">
+    <feature-packs>
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>     
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/feature-packs/adapter-feature-pack/assembly.xml b/distribution/feature-packs/adapter-feature-pack/assembly.xml
new file mode 100644
index 0000000..526c08d
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/assembly.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~ * JBoss, Home of Professional Open Source.
+  ~ * Copyright 2014, Red Hat, Inc., and individual contributors
+  ~ * as indicated by the @author tags. See the copyright.txt file in the
+  ~ * distribution for a full listing of individual contributors.
+  ~ *
+  ~ * This is free software; you can redistribute it and/or modify it
+  ~ * under the terms of the GNU Lesser General Public License as
+  ~ * published by the Free Software Foundation; either version 2.1 of
+  ~ * the License, or (at your option) any later version.
+  ~ *
+  ~ * This software is distributed in the hope that it will be useful,
+  ~ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ * Lesser General Public License for more details.
+  ~ *
+  ~ * You should have received a copy of the GNU Lesser General Public
+  ~ * License along with this software; if not, write to the Free
+  ~ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  ~ */
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>feature-pack</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target/${project.build.finalName}</directory>
+            <outputDirectory/>            
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-packs/adapter-feature-pack/feature-pack-build.xml b/distribution/feature-packs/adapter-feature-pack/feature-pack-build.xml
new file mode 100644
index 0000000..e55c8d9
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/feature-pack-build.xml
@@ -0,0 +1,36 @@
+<build xmlns="urn:wildfly:feature-pack-build:1.0">
+    <dependencies>
+        <artifact name="org.wildfly:wildfly-web-feature-pack" />
+    </dependencies>
+    <config>
+        <standalone template="configuration/standalone/template.xml" subsystems="configuration/standalone/subsystems.xml" output-file="standalone/configuration/standalone.xml" />
+        <domain template="configuration/domain/template.xml" subsystems="configuration/domain/subsystems.xml" output-file="domain/configuration/domain.xml" />
+    </config>
+
+    <copy-artifacts>
+    </copy-artifacts>
+    <mkdirs>
+    </mkdirs>
+    
+    <file-permissions>
+        <permission value="755">
+            <filter pattern="*.sh" include="true"/>
+        </permission>
+        <permission value="700">
+            <filter pattern="*/tmp/auth" include="true"/>
+        </permission>
+        <permission value="600">
+            <filter pattern="*-users.properties" include="true" />
+            <filter pattern="*/.installation" include="true"/>
+        </permission>
+    </file-permissions>
+    <line-endings>
+        <windows>
+            <filter pattern="*.bat" include="true"/>
+        </windows>
+        <unix>
+            <filter pattern="*.sh" include="true"/>
+            <filter pattern="*.conf" include="true"/>
+        </unix>
+    </line-endings>
+</build>
\ No newline at end of file
diff --git a/distribution/feature-packs/adapter-feature-pack/pom.xml b/distribution/feature-packs/adapter-feature-pack/pom.xml
new file mode 100644
index 0000000..1fa74ff
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/pom.xml
@@ -0,0 +1,176 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>feature-packs-parent</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-adapter-feature-pack</artifactId>
+
+    <name>Keycloak Feature Pack: Adapter</name>
+    <packaging>pom</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.github.relaxng</groupId>
+            <artifactId>relaxngDatatype</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.istack</groupId>
+            <artifactId>istack-commons-runtime</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.istack</groupId>
+            <artifactId>istack-commons-tools</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind.external</groupId>
+            <artifactId>rngom</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xsom</groupId>
+            <artifactId>xsom</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-runtime</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>jaxb-xjc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>codemodel</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jaxb</groupId>
+            <artifactId>txw2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.spec.javax.xml.bind</groupId>
+            <artifactId>jboss-jaxb-api_2.2_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.xnio.netty</groupId>
+            <artifactId>netty-xnio-transport</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mime4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-wildfly-adapter-subsystem</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-undertow-adapter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wildfly</groupId>
+            <artifactId>wildfly-web-feature-pack</artifactId>
+            <type>zip</type>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions></executions>
+            </plugin>
+            <plugin>
+                <groupId>org.wildfly.build</groupId>
+                <artifactId>wildfly-feature-pack-build-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>feature-pack-build</id>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <phase>compile</phase>
+                        <configuration>
+                            <config-file>feature-pack-build.xml</config-file>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>assembly.xml</descriptor>
+                            </descriptors>
+                            <recompressZippedFiles>true</recompressZippedFiles>
+                            <finalName>${project.build.finalName}</finalName>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <outputDirectory>target/</outputDirectory>
+                            <workDirectory>target/assembly/work</workDirectory>
+                            <tarLongFileMode>gnu</tarLongFileMode>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/domain/subsystems.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/domain/subsystems.xml
new file mode 100644
index 0000000..3bff333
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/domain/subsystems.xml
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
+<config>
+    <subsystems name="default">
+        <subsystem>logging.xml</subsystem>
+        <subsystem supplement="web-build">ee.xml</subsystem>
+        <subsystem>io.xml</subsystem>
+        <subsystem>jmx.xml</subsystem>
+        <subsystem supplement="web-build">naming.xml</subsystem>
+        <subsystem>request-controller.xml</subsystem>
+        <subsystem supplement="web-build">security.xml</subsystem>
+        <subsystem>undertow.xml</subsystem>
+        <subsystem>keycloak-adapter.xml</subsystem>
+    </subsystems>
+</config>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/domain/template.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/domain/template.xml
new file mode 100644
index 0000000..33a0ac7
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/domain/template.xml
@@ -0,0 +1,85 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!--
+  ~
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  ~
+  -->
+
+<domain xmlns="urn:jboss:domain:2.1">
+
+    <extensions>
+        <?EXTENSIONS?>
+    </extensions>
+
+    <system-properties>
+        <!-- IPv4 is not required, but setting this helps avoid unintended use of IPv6 -->
+        <property name="java.net.preferIPv4Stack" value="true"/>
+    </system-properties>
+
+    <management>
+        <access-control provider="simple">
+            <role-mapping>
+                <role name="SuperUser">
+                    <include>
+                        <user name="$local"/>
+                    </include>
+                </role>
+            </role-mapping>
+        </access-control>
+    </management>
+
+    <profiles>
+       <profile name="default">
+           <?SUBSYSTEMS socket-binding-group="standard-sockets"?>
+       </profile>
+    </profiles>
+
+    <!--
+         Named interfaces that can be referenced elsewhere in the configuration. The configuration
+         for how to associate these logical names with an actual network interface can either
+         be specified here or can be declared on a per-host basis in the equivalent element in host.xml.
+
+         These default configurations require the binding specification to be done in host.xml.
+    -->
+    <interfaces>
+        <interface name="management"/>
+        <interface name="public"/>
+        <interface name="unsecure"/>
+    </interfaces>
+
+    <socket-binding-groups>
+        <socket-binding-group name="standard-sockets" default-interface="public">
+            <!-- Needed for server groups using the 'default' profile  -->
+            <?SOCKET-BINDINGS?>
+        </socket-binding-group>
+    </socket-binding-groups>
+
+    <server-groups>
+        <server-group name="main-server-group" profile="default">
+            <jvm name="default">
+                <heap size="64m" max-size="512m"/>
+            </jvm>
+            <socket-binding-group ref="standard-sockets"/>
+        </server-group>
+    </server-groups>
+
+</domain>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/standalone/subsystems.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/standalone/subsystems.xml
new file mode 100644
index 0000000..765f018
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/standalone/subsystems.xml
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
+<config>
+   <subsystems>
+       <subsystem>logging.xml</subsystem>
+       <subsystem>deployment-scanner.xml</subsystem>
+       <subsystem supplement="web-build">ee.xml</subsystem>
+       <subsystem>io.xml</subsystem>
+       <subsystem>jmx.xml</subsystem>
+       <subsystem supplement="web-build">naming.xml</subsystem>
+       <subsystem>request-controller.xml</subsystem>
+       <subsystem supplement="web-build">security.xml</subsystem>
+       <subsystem>security-manager.xml</subsystem>
+       <subsystem>undertow.xml</subsystem>
+       <subsystem>keycloak-adapter.xml</subsystem>
+   </subsystems>
+</config>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/standalone/template.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/standalone/template.xml
new file mode 100644
index 0000000..d0a8130
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/configuration/standalone/template.xml
@@ -0,0 +1,81 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:2.0">
+
+    <extensions>
+        <?EXTENSIONS?>
+    </extensions>
+
+    <management>
+        <security-realms>
+            <security-realm name="ManagementRealm">
+                <authentication>
+                    <local default-user="$local" />
+                    <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization map-groups-to-roles="false">
+                    <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+            <security-realm name="ApplicationRealm">
+                <authentication>
+                    <local default-user="$local" allowed-users="*" />
+                    <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization>
+                    <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+        </security-realms>
+        <audit-log>
+            <formatters>
+               <json-formatter name="json-formatter"/>
+            </formatters>        
+            <handlers>
+               <file-handler name="file" formatter="json-formatter" relative-to="jboss.server.data.dir" path="audit-log.log"/>
+            </handlers>
+            <logger log-boot="true" log-read-only="false" enabled="false">
+               <handlers>
+                  <handler name="file"/>
+               </handlers>
+            </logger>
+        </audit-log>
+        <management-interfaces>
+            <http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">
+                <socket-binding http="management-http"/>
+            </http-interface>
+        </management-interfaces>
+        <access-control provider="simple">
+            <role-mapping>
+                <role name="SuperUser">
+                    <include>
+                        <user name="$local"/>
+                    </include>
+                </role>
+            </role-mapping>
+        </access-control>
+    </management>
+
+    <profile>
+
+        <?SUBSYSTEMS socket-binding-group="standard-sockets"?>
+
+    </profile>
+
+    <interfaces>
+        <interface name="management">
+            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+        </interface>
+        <interface name="public">
+            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+        </interface>
+    </interfaces>
+
+    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+        <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+        <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
+
+        <?SOCKET-BINDINGS?>
+
+    </socket-binding-group>
+</server>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/content/README.md b/distribution/feature-packs/adapter-feature-pack/src/main/resources/content/README.md
new file mode 100644
index 0000000..e7b122b
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/content/README.md
@@ -0,0 +1,2 @@
+This directory intentionally left empty.  The Feature Pack plugin barfs if there is no content 
+directory.  But Git won't save an empty directory.  Thus, we need this readme file.
\ No newline at end of file
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/github/relaxng/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/github/relaxng/main/module.xml
new file mode 100644
index 0000000..c4985dd
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/github/relaxng/main/module.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2012, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+
+<module xmlns="urn:jboss:module:1.3" name="com.github.relaxng">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${com.github.relaxng:relaxngDatatype}"/>
+    </resources>
+
+    <dependencies>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/istack/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/istack/main/module.xml
new file mode 100644
index 0000000..e876e16
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/istack/main/module.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="com.sun.istack">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${com.sun.istack:istack-commons-runtime}"/>
+        <artifact name="${com.sun.istack:istack-commons-tools}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.activation.api" />
+        <module name="javax.api" />
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xml/bind/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xml/bind/main/module.xml
new file mode 100644
index 0000000..90c2a2a
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xml/bind/main/module.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="com.sun.xml.bind">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.glassfish.jaxb:jaxb-core}"/>
+        <artifact name="${org.glassfish.jaxb:jaxb-runtime}"/>
+        <artifact name="${org.glassfish.jaxb:jaxb-xjc}"/>
+        <artifact name="${org.glassfish.jaxb:codemodel}"/>
+        <artifact name="${com.sun.xml.bind.external:rngom}"/>
+    </resources>
+
+    <dependencies>
+        <module name="com.github.relaxng" export="true" />
+        <module name="com.sun.istack" export="true" />
+        <module name="com.sun.xml.txw2" export="true" />
+        <module name="com.sun.xsom" export="true" />
+        <module name="javax.api" />
+        <module name="javax.xml.bind.api" />
+        <module name="javax.xml.stream.api" />
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xml/txw2/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xml/txw2/main/module.xml
new file mode 100644
index 0000000..8b31f98
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xml/txw2/main/module.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="com.sun.xml.txw2">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.glassfish.jaxb:txw2}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/> 
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xsom/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xsom/main/module.xml
new file mode 100644
index 0000000..bb0d1bb
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/com/sun/xsom/main/module.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="com.sun.xsom">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${com.sun.xsom:xsom}"/>
+    </resources>
+
+    <dependencies>
+        <module name="com.github.relaxng"/>
+        <module name="javax.api" />
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/io/netty/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/io/netty/main/module.xml
new file mode 100644
index 0000000..f841695
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/io/netty/main/module.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="io.netty">
+    <resources>
+        <artifact name="${io.netty:netty-all}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="sun.jdk"/>
+        <module name="org.javassist" optional="true"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/javax/xml/bind/api/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/javax/xml/bind/api/main/module.xml
new file mode 100644
index 0000000..fdb649f
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/javax/xml/bind/api/main/module.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="javax.xml.bind.api">
+
+
+    <dependencies>
+        <module name="javax.activation.api" export="true"/>
+        <module name="javax.xml.stream.api"/>
+        <module name="com.sun.xml.bind" services="import"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+    <resources>
+        <artifact name="${org.jboss.spec.javax.xml.bind:jboss-jaxb-api_2.2_spec}"/>
+    </resources>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/net/iharder/base64/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/net/iharder/base64/main/module.xml
new file mode 100644
index 0000000..ba70430
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/net/iharder/base64/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="net.iharder.base64">
+    <resources>
+        <artifact name="${net.iharder:base64}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/commons/codec/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/commons/codec/main/module.xml
new file mode 100644
index 0000000..cf9cb86
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/commons/codec/main/module.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.apache.commons.codec">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${commons-codec:commons-codec}"/>
+    </resources>
+
+    <dependencies>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/commons/logging/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/commons/logging/main/module.xml
new file mode 100644
index 0000000..f7362e3
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/commons/logging/main/module.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module-alias xmlns="urn:jboss:module:1.3" name="org.apache.commons.logging" target-name="org.slf4j.jcl-over-slf4j"/>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/httpcomponents/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/httpcomponents/main/module.xml
new file mode 100644
index 0000000..39aab46
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/httpcomponents/main/module.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.apache.httpcomponents">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.apache.httpcomponents:httpclient}"/>
+        <artifact name="${org.apache.httpcomponents:httpcore}"/>
+        <artifact name="${org.apache.httpcomponents:httpmime}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.apache.commons.codec"/>
+        <module name="org.apache.commons.logging"/>
+        <module name="org.apache.james.mime4j"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/james/mime4j/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/james/mime4j/main/module.xml
new file mode 100644
index 0000000..95de37e
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/apache/james/mime4j/main/module.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.apache.james.mime4j">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.apache.james:apache-mime4j}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.apache.commons.logging"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/bouncycastle/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/bouncycastle/main/module.xml
new file mode 100644
index 0000000..eaa0557
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/bouncycastle/main/module.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.bouncycastle">
+    <resources>
+        <artifact name="${org.bouncycastle:bcprov-jdk15on}"/>
+        <artifact name="${org.bouncycastle:bcpkix-jdk15on}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-core-asl/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-core-asl/main/module.xml
new file mode 100644
index 0000000..a4e2692
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-core-asl/main/module.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+<module xmlns="urn:jboss:module:1.3" name="org.codehaus.jackson.jackson-core-asl">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.codehaus.jackson:jackson-core-asl}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-mapper-asl/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-mapper-asl/main/module.xml
new file mode 100644
index 0000000..5e62a8a
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-mapper-asl/main/module.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+<module xmlns="urn:jboss:module:1.3" name="org.codehaus.jackson.jackson-mapper-asl">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.codehaus.jackson:jackson-mapper-asl}"/>
+    </resources>
+
+    <dependencies>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.joda.time"/>
+        <module name="javax.api"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-xc/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-xc/main/module.xml
new file mode 100644
index 0000000..25b7520
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/codehaus/jackson/jackson-xc/main/module.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+<module xmlns="urn:jboss:module:1.3" name="org.codehaus.jackson.jackson-xc">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.codehaus.jackson:jackson-xc}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="javax.activation.api"/>
+        <module name="javax.xml.bind.api"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/jboss/xnio/netty/netty-xnio-transport/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/jboss/xnio/netty/netty-xnio-transport/main/module.xml
new file mode 100644
index 0000000..1f3215d
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/jboss/xnio/netty/netty-xnio-transport/main/module.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.jboss.xnio.netty.netty-xnio-transport">
+    <properties>
+        <property name="jboss.api" value="private"/>
+    </properties>
+
+    <resources>
+        <artifact name="${org.jboss.xnio.netty:netty-xnio-transport}"/>
+    </resources>
+
+    <dependencies>
+        <module name="io.netty"/>
+        <module name="org.jboss.xnio"/>
+        <module name="org.jboss.xnio.nio"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/joda/time/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/joda/time/main/module.xml
new file mode 100644
index 0000000..c4b1b52
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/joda/time/main/module.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.joda.time">
+
+    <resources>
+        <artifact name="${joda-time:joda-time}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api" />
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-core/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-core/main/module.xml
new file mode 100644
index 0000000..07dcd06
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-core/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-adapter-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-adapter-core}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="org.jboss.logging"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="net.iharder.base64"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-subsystem/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-subsystem/main/module.xml
new file mode 100644
index 0000000..f7cd890
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-subsystem/main/module.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-adapter-subsystem">
+
+    <resources>
+        <artifact name="${org.keycloak:keycloak-wildfly-adapter-subsystem}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.jboss.staxmapper"/>
+        <module name="org.jboss.as.controller"/>
+        <module name="org.jboss.as.ee"/>
+        <module name="org.jboss.as.server"/>
+        <module name="org.jboss.modules"/>
+        <module name="org.jboss.msc"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.jboss.vfs"/>
+        <module name="org.jboss.as.web-common" optional="true"/>
+        <module name="org.jboss.as.web" optional="true"/>
+        <module name="org.jboss.as.version" optional="true"/>
+        <module name="org.keycloak.keycloak-wildfly-adapter" optional="true"/>
+        <module name="org.jboss.metadata"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core/main/module.xml
new file mode 100644
index 0000000..b23c589
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core/main/module.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-core}"/>
+    </resources>
+    <dependencies>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+        <module name="javax.activation.api"/>
+        <module name="sun.jdk" optional="true" />
+        <module name="sun.jdk.jgss" optional="true" />
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-jboss-adapter-core/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
new file mode 100644
index 0000000..6e5b217
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-jboss-adapter-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-jboss-adapter-core}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.picketbox"/>
+        <module name="org.keycloak.keycloak-adapter-core"/>
+        <module name="org.keycloak.keycloak-core"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-undertow-adapter/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-undertow-adapter/main/module.xml
new file mode 100644
index 0000000..9ba1cb2
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-undertow-adapter/main/module.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-undertow-adapter">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-undertow-adapter}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.bouncycastle" />
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="javax.servlet.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.jboss.xnio"/>
+        <module name="io.undertow.core"/>
+        <module name="io.undertow.servlet"/>
+        <module name="org.keycloak.keycloak-adapter-core"/>
+        <module name="org.keycloak.keycloak-core"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-adapter/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-adapter/main/module.xml
new file mode 100644
index 0000000..df7cc03
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-adapter/main/module.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-wildfly-adapter">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-wildfly-adapter}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.bouncycastle" />
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="javax.servlet.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="io.undertow.core"/>
+        <module name="io.undertow.servlet"/>
+        <module name="org.picketbox"/>
+        <module name="org.keycloak.keycloak-undertow-adapter"/>
+        <module name="org.keycloak.keycloak-adapter-core"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.jboss.xnio"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/slf4j/jcl-over-slf4j/main/module.xml b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/slf4j/jcl-over-slf4j/main/module.xml
new file mode 100644
index 0000000..c29c8fc
--- /dev/null
+++ b/distribution/feature-packs/adapter-feature-pack/src/main/resources/modules/system/layers/base/org/slf4j/jcl-over-slf4j/main/module.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2010, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.3" name="org.slf4j.jcl-over-slf4j">
+    <resources>
+        <artifact name="${org.slf4j:jcl-over-slf4j}"/>
+    </resources>
+
+    <dependencies>
+        <module name="org.slf4j"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/pom.xml b/distribution/feature-packs/pom.xml
new file mode 100644
index 0000000..dcc6c0c
--- /dev/null
+++ b/distribution/feature-packs/pom.xml
@@ -0,0 +1,20 @@
+<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>distribution-pom</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <name>Feature Pack Builds</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>feature-packs-parent</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>adapter-feature-pack</module>
+        <module>server-feature-pack</module>
+    </modules>
+</project>
diff --git a/distribution/feature-packs/server-feature-pack/assembly.xml b/distribution/feature-packs/server-feature-pack/assembly.xml
new file mode 100644
index 0000000..eaee2ca
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/assembly.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ /*
+  ~ * JBoss, Home of Professional Open Source.
+  ~ * Copyright 2014, Red Hat, Inc., and individual contributors
+  ~ * as indicated by the @author tags. See the copyright.txt file in the
+  ~ * distribution for a full listing of individual contributors.
+  ~ *
+  ~ * This is free software; you can redistribute it and/or modify it
+  ~ * under the terms of the GNU Lesser General Public License as
+  ~ * published by the Free Software Foundation; either version 2.1 of
+  ~ * the License, or (at your option) any later version.
+  ~ *
+  ~ * This software is distributed in the hope that it will be useful,
+  ~ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ * Lesser General Public License for more details.
+  ~ *
+  ~ * You should have received a copy of the GNU Lesser General Public
+  ~ * License along with this software; if not, write to the Free
+  ~ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  ~ */
+  -->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>feature-pack</id>
+    <formats>
+       <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    
+    <!-- If war is filtered it will get corrupted. Only need to filter module.xml -->
+    <fileSets>
+        <fileSet>
+            <directory>target/${project.build.finalName}</directory>
+            <outputDirectory/>    
+            <filtered>true</filtered>
+            <includes>
+               <include>**/module.xml</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>target/${project.build.finalName}</directory>
+            <outputDirectory/>    
+            <filtered>false</filtered>
+            <excludes>
+               <exclude>**/module.xml</exclude>
+            </excludes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/distribution/feature-packs/server-feature-pack/feature-pack-build.xml b/distribution/feature-packs/server-feature-pack/feature-pack-build.xml
new file mode 100644
index 0000000..8737c28
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/feature-pack-build.xml
@@ -0,0 +1,39 @@
+<build xmlns="urn:wildfly:feature-pack-build:1.0">
+    <dependencies>
+        <artifact name="org.wildfly:wildfly-feature-pack" />
+    </dependencies>
+    <config>
+        <standalone template="configuration/standalone/template.xml" subsystems="configuration/standalone/subsystems.xml" output-file="standalone/configuration/standalone.xml" />
+        <domain template="configuration/domain/template.xml" subsystems="configuration/domain/subsystems.xml" output-file="domain/configuration/domain.xml" />
+    </config>
+
+    <mkdirs>
+    </mkdirs>
+<!--    <copy-artifacts>
+        <copy-artifact artifact="org.keycloak.subsystem:keycloak-server" to-location="standalone/configuration" extract="true">
+            
+            <filter pattern="**/keycloak-server.json" include="true"/>
+        </copy-artifact>
+    </copy-artifacts>    -->
+    <file-permissions>
+        <permission value="755">
+            <filter pattern="*.sh" include="true"/>
+        </permission>
+        <permission value="700">
+            <filter pattern="*/tmp/auth" include="true"/>
+        </permission>
+        <permission value="600">
+            <filter pattern="*-users.properties" include="true" />
+            <filter pattern="*/.installation" include="true"/>
+        </permission>
+    </file-permissions>
+    <line-endings>
+        <windows>
+            <filter pattern="*.bat" include="true"/>
+        </windows>
+        <unix>
+            <filter pattern="*.sh" include="true"/>
+            <filter pattern="*.conf" include="true"/>
+        </unix>
+    </line-endings>
+</build>
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/pom.xml b/distribution/feature-packs/server-feature-pack/pom.xml
new file mode 100644
index 0000000..c5bfc3e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/pom.xml
@@ -0,0 +1,149 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<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>
+        <groupId>org.keycloak</groupId>
+        <artifactId>feature-packs-parent</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    
+    <artifactId>keycloak-server-feature-pack</artifactId>
+
+    <name>Keycloak Feature Pack: Server</name>
+    <packaging>pom</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-dependencies-server-all</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak.subsystem</groupId>
+            <artifactId>keycloak-server</artifactId>
+            <version>${project.version}</version>
+            <type>war</type>
+        </dependency>   
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-wildfly-server-subsystem</artifactId>
+            <version>${project.version}</version>
+        </dependency>      
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-wildfly-extensions</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.wildfly</groupId>
+            <artifactId>wildfly-feature-pack</artifactId>
+            <type>zip</type>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-undertow-adapter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak.subsystem</groupId>
+            <artifactId>keycloak-server</artifactId>
+            <type>war</type>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions></executions>
+            </plugin>
+            <plugin>
+                <groupId>org.wildfly.build</groupId>
+                <artifactId>wildfly-feature-pack-build-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>feature-pack-build</id>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <phase>compile</phase>
+                        <configuration>
+                            <config-file>feature-pack-build.xml</config-file>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>assembly.xml</descriptor>
+                            </descriptors>
+                            <recompressZippedFiles>true</recompressZippedFiles>
+                            <finalName>${project.build.finalName}</finalName>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <outputDirectory>target/</outputDirectory>
+                            <workDirectory>target/assembly/work</workDirectory>
+                            <tarLongFileMode>gnu</tarLongFileMode>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.keycloak.subsystem</groupId>
+                                    <artifactId>keycloak-server</artifactId>
+                                    <version>${project.version}</version>
+                                    <type>war</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/${project.build.finalName}/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/auth-server</outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/subsystems.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/subsystems.xml
new file mode 100644
index 0000000..2dde48f
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/subsystems.xml
@@ -0,0 +1,138 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
+<config>
+   <subsystems name="default">
+      <!-- Each subsystem to be included relative to the src/main/resources directory -->
+      <subsystem>logging.xml</subsystem>
+      <subsystem>batch.xml</subsystem>
+      <subsystem>bean-validation.xml</subsystem>
+      <subsystem>keycloak-datasources.xml</subsystem>
+      <subsystem>ee.xml</subsystem>
+      <subsystem>ejb3.xml</subsystem>
+      <subsystem>io.xml</subsystem>
+      <subsystem>infinispan.xml</subsystem>
+      <subsystem>jaxrs.xml</subsystem>
+      <subsystem>jca.xml</subsystem>
+      <subsystem>jdr.xml</subsystem>
+      <subsystem supplement="domain">jmx.xml</subsystem>
+      <subsystem>jpa.xml</subsystem>
+      <subsystem>jsf.xml</subsystem>
+      <subsystem>mail.xml</subsystem>
+      <subsystem>naming.xml</subsystem>
+      <subsystem>pojo.xml</subsystem>
+      <subsystem>remoting.xml</subsystem>
+      <subsystem>resource-adapters.xml</subsystem>
+      <subsystem>request-controller.xml</subsystem>
+      <subsystem>sar.xml</subsystem>
+      <subsystem>security.xml</subsystem>
+      <subsystem>security-manager.xml</subsystem>
+      <subsystem>transactions.xml</subsystem>
+      <subsystem>undertow.xml</subsystem>
+      <subsystem>webservices.xml</subsystem>
+      <subsystem>weld.xml</subsystem>
+      <subsystem>keycloak-server.xml</subsystem>
+   </subsystems>
+   <subsystems name="ha">
+      <!-- Each subsystem to be included relative to the src/main/resources directory -->
+      <subsystem>logging.xml</subsystem>
+      <subsystem>batch.xml</subsystem>
+      <subsystem>bean-validation.xml</subsystem>
+      <subsystem>keycloak-datasources.xml</subsystem>
+      <subsystem>ee.xml</subsystem>
+      <subsystem supplement="ha">ejb3.xml</subsystem>
+      <subsystem>io.xml</subsystem>
+      <subsystem supplement="ha">infinispan.xml</subsystem>
+      <subsystem>jaxrs.xml</subsystem>
+      <subsystem>jca.xml</subsystem>
+      <subsystem>jdr.xml</subsystem>
+      <subsystem>jgroups.xml</subsystem>
+      <subsystem supplement="domain">jmx.xml</subsystem>
+      <subsystem>jpa.xml</subsystem>
+      <subsystem>jsf.xml</subsystem>
+      <subsystem>mail.xml</subsystem>
+      <subsystem>mod_cluster.xml</subsystem>
+      <subsystem>naming.xml</subsystem>
+      <subsystem>pojo.xml</subsystem>
+      <subsystem>remoting.xml</subsystem>
+      <subsystem>resource-adapters.xml</subsystem>
+      <subsystem>request-controller.xml</subsystem>
+      <subsystem>sar.xml</subsystem>
+      <subsystem>security.xml</subsystem>
+      <subsystem>security-manager.xml</subsystem>
+      <subsystem>transactions.xml</subsystem>
+      <subsystem supplement="ha">undertow.xml</subsystem>
+      <subsystem>webservices.xml</subsystem>
+      <subsystem>weld.xml</subsystem>
+      <subsystem>keycloak-server.xml</subsystem>
+   </subsystems>
+   <subsystems name="full">
+      <!-- Each subsystem to be included relative to the src/main/resources directory -->
+      <subsystem>logging.xml</subsystem>
+      <subsystem>batch.xml</subsystem>
+      <subsystem>bean-validation.xml</subsystem>
+      <subsystem>keycloak-datasources.xml</subsystem>
+      <subsystem supplement="full">ee.xml</subsystem>
+      <subsystem supplement="full">ejb3.xml</subsystem>
+      <subsystem>io.xml</subsystem>
+      <subsystem>infinispan.xml</subsystem>
+      <subsystem>iiop-openjdk.xml</subsystem>
+      <subsystem>jaxrs.xml</subsystem>
+      <subsystem>jca.xml</subsystem>
+      <subsystem>jdr.xml</subsystem>
+      <subsystem supplement="domain">jmx.xml</subsystem>
+      <subsystem>jpa.xml</subsystem>
+      <subsystem>jsf.xml</subsystem>
+      <subsystem>jsr77.xml</subsystem>
+      <subsystem>mail.xml</subsystem>
+      <subsystem>messaging.xml</subsystem>
+      <subsystem>naming.xml</subsystem>
+      <subsystem>pojo.xml</subsystem>
+      <subsystem>remoting.xml</subsystem>
+      <subsystem>resource-adapters.xml</subsystem>
+      <subsystem>request-controller.xml</subsystem>
+      <subsystem>sar.xml</subsystem>
+      <subsystem>security.xml</subsystem>
+      <subsystem>security-manager.xml</subsystem>
+      <subsystem>transactions.xml</subsystem>
+      <subsystem>undertow.xml</subsystem>
+      <subsystem>webservices.xml</subsystem>
+      <subsystem>weld.xml</subsystem>
+      <subsystem>keycloak-server.xml</subsystem>
+   </subsystems>
+   <subsystems name="full-ha">
+      <!-- Each subsystem to be included relative to the src/main/resources directory -->
+      <subsystem>logging.xml</subsystem>
+      <subsystem>batch.xml</subsystem>
+      <subsystem>bean-validation.xml</subsystem>
+      <subsystem>keycloak-datasources.xml</subsystem>
+      <subsystem supplement="full">ee.xml</subsystem>
+      <subsystem supplement="full-ha">ejb3.xml</subsystem>
+      <subsystem>io.xml</subsystem>
+      <subsystem supplement="ha">infinispan.xml</subsystem>
+      <subsystem>iiop-openjdk.xml</subsystem>
+      <subsystem>jaxrs.xml</subsystem>
+      <subsystem>jca.xml</subsystem>
+      <subsystem>jdr.xml</subsystem>
+      <subsystem>jgroups.xml</subsystem>
+      <subsystem supplement="domain">jmx.xml</subsystem>
+      <subsystem>jpa.xml</subsystem>
+      <subsystem>jsf.xml</subsystem>
+      <subsystem>jsr77.xml</subsystem>
+      <subsystem>mail.xml</subsystem>
+      <subsystem supplement="ha">messaging.xml</subsystem>
+      <subsystem>mod_cluster.xml</subsystem>
+      <subsystem>naming.xml</subsystem>
+      <subsystem>pojo.xml</subsystem>
+      <subsystem>remoting.xml</subsystem>
+      <subsystem>resource-adapters.xml</subsystem>
+      <subsystem>request-controller.xml</subsystem>
+      <subsystem>sar.xml</subsystem>
+      <subsystem>security.xml</subsystem>
+      <subsystem>security-manager.xml</subsystem>
+      <subsystem>transactions.xml</subsystem>
+      <subsystem supplement="ha">undertow.xml</subsystem>
+      <subsystem>webservices.xml</subsystem>
+      <subsystem>weld.xml</subsystem>
+      <subsystem>keycloak-server.xml</subsystem>
+   </subsystems>
+</config>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml
new file mode 100644
index 0000000..cf3cccc
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml
@@ -0,0 +1,88 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<domain xmlns="urn:jboss:domain:3.0">
+
+    <extensions>
+        <?EXTENSIONS?>
+    </extensions>
+
+    <system-properties>
+        <!-- IPv4 is not required, but setting this helps avoid unintended use of IPv6 -->
+        <property name="java.net.preferIPv4Stack" value="true"/>
+    </system-properties>
+
+    <management>
+        <access-control provider="simple">
+            <role-mapping>
+                <role name="SuperUser">
+                    <include>
+                        <user name="$local"/>
+                    </include>
+                </role>
+            </role-mapping>
+        </access-control>
+    </management>
+
+    <profiles>
+       <profile name="default">
+           <?SUBSYSTEMS socket-binding-group="standard-sockets"?>
+       </profile>
+       <profile name="ha">
+           <?SUBSYSTEMS socket-binding-group="ha-sockets"?>
+       </profile>
+       <profile name="full">
+           <?SUBSYSTEMS socket-binding-group="full-sockets"?>
+       </profile>
+       <profile name="full-ha">
+           <?SUBSYSTEMS socket-binding-group="full-ha-sockets"?>
+       </profile>
+    </profiles>
+
+    <!--
+         Named interfaces that can be referenced elsewhere in the configuration. The configuration
+         for how to associate these logical names with an actual network interface can either
+         be specified here or can be declared on a per-host basis in the equivalent element in host.xml.
+
+         These default configurations require the binding specification to be done in host.xml.
+    -->
+    <interfaces>
+        <interface name="management"/>
+        <interface name="public"/>
+        <interface name="unsecure"/>
+    </interfaces>
+
+    <socket-binding-groups>
+        <socket-binding-group name="standard-sockets" default-interface="public">
+            <!-- Needed for server groups using the 'default' profile  -->
+            <?SOCKET-BINDINGS?>
+        </socket-binding-group>
+        <socket-binding-group name="ha-sockets" default-interface="public">
+            <!-- Needed for server groups using the 'ha' profile  -->
+            <?SOCKET-BINDINGS?>
+        </socket-binding-group>
+        <socket-binding-group name="full-sockets" default-interface="public">
+            <!-- Needed for server groups using the 'full' profile  -->
+            <?SOCKET-BINDINGS?>
+        </socket-binding-group>
+        <socket-binding-group name="full-ha-sockets" default-interface="public">
+            <!-- Needed for server groups using the 'full-ha' profile  -->
+            <?SOCKET-BINDINGS?>
+        </socket-binding-group>
+    </socket-binding-groups>
+
+    <server-groups>
+        <server-group name="main-server-group" profile="full">
+            <jvm name="default">
+                <heap size="64m" max-size="512m"/>
+            </jvm>
+            <socket-binding-group ref="full-sockets"/>
+        </server-group>
+        <server-group name="other-server-group" profile="full-ha">
+            <jvm name="default">
+                <heap size="64m" max-size="512m"/>
+            </jvm>
+            <socket-binding-group ref="full-ha-sockets"/>
+        </server-group>
+    </server-groups>
+
+</domain>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/subsystems.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/subsystems.xml
new file mode 100644
index 0000000..fad3c38
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/subsystems.xml
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
+<config>
+   <subsystems>
+      <subsystem>logging.xml</subsystem>
+      <subsystem>batch.xml</subsystem>
+      <subsystem>bean-validation.xml</subsystem>
+      <subsystem>keycloak-datasources.xml</subsystem>
+      <subsystem>deployment-scanner.xml</subsystem>
+      <subsystem>ee.xml</subsystem>
+      <subsystem>ejb3.xml</subsystem>
+      <subsystem>io.xml</subsystem>
+      <subsystem>infinispan.xml</subsystem>
+      <subsystem>jaxrs.xml</subsystem>
+      <subsystem>jca.xml</subsystem>
+      <subsystem>jdr.xml</subsystem>
+      <subsystem>jmx.xml</subsystem>
+      <subsystem>jpa.xml</subsystem>
+      <subsystem>jsf.xml</subsystem>
+      <subsystem>mail.xml</subsystem>
+      <subsystem>naming.xml</subsystem>
+      <subsystem>pojo.xml</subsystem>
+      <subsystem>remoting.xml</subsystem>
+      <subsystem>resource-adapters.xml</subsystem>
+      <subsystem>request-controller.xml</subsystem>
+      <subsystem>sar.xml</subsystem>
+      <subsystem>security-manager.xml</subsystem>
+      <subsystem>security.xml</subsystem>
+      <subsystem>transactions.xml</subsystem>
+      <subsystem>undertow.xml</subsystem>
+      <subsystem>webservices.xml</subsystem>
+      <subsystem>weld.xml</subsystem>
+      <subsystem>keycloak-server.xml</subsystem>
+   </subsystems>
+</config>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml
new file mode 100644
index 0000000..2260468
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml
@@ -0,0 +1,87 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:3.0">
+
+    <extensions>
+        <?EXTENSIONS?>
+    </extensions>
+
+    <management>
+        <security-realms>
+            <security-realm name="ManagementRealm">
+                <authentication>
+                    <local default-user="$local" skip-group-loading="true" />
+                    <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization map-groups-to-roles="false">
+                    <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+            <security-realm name="ApplicationRealm">
+                <authentication>
+                    <local default-user="$local" allowed-users="*" skip-group-loading="true" />
+                    <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+                </authentication>
+                <authorization>
+                    <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+                </authorization>
+            </security-realm>
+        </security-realms>
+        <audit-log>
+            <formatters>
+               <json-formatter name="json-formatter"/>
+            </formatters>        
+            <handlers>
+               <file-handler name="file" formatter="json-formatter" relative-to="jboss.server.data.dir" path="audit-log.log"/>
+            </handlers>
+            <logger log-boot="true" log-read-only="false" enabled="false">
+               <handlers>
+                  <handler name="file"/>
+               </handlers>
+            </logger>
+        </audit-log>
+        <management-interfaces>
+            <http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">
+                <socket-binding http="management-http"/>
+            </http-interface>
+        </management-interfaces>
+        <access-control provider="simple">
+            <role-mapping>
+                <role name="SuperUser">
+                    <include>
+                        <user name="$local"/>
+                    </include>
+                </role>
+            </role-mapping>
+        </access-control>
+    </management>
+
+    <profile>
+
+        <?SUBSYSTEMS socket-binding-group="standard-sockets"?>
+
+    </profile>
+
+    <interfaces>
+        <interface name="management">
+            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+        </interface>
+        <interface name="public">
+            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+        </interface>
+        <!-- TODO - only show this if the jacorb subsystem is added  -->
+        <interface name="unsecure">
+            <!-- Used for IIOP sockets in the standard configuration.
+                 To secure JacORB you need to setup SSL -->
+            <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>
+        </interface>
+    </interfaces>
+
+    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+        <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+        <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
+
+        <?SOCKET-BINDINGS?>
+
+    </socket-binding-group>
+</server>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json b/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json
new file mode 100644
index 0000000..9f0d03e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/standalone/configuration/keycloak-server.json
@@ -0,0 +1,72 @@
+{
+    "admin": {
+        "realm": "master"
+    },
+
+    "eventsStore": {
+        "provider": "jpa",
+        "jpa": {
+            "exclude-events": [ "REFRESH_TOKEN" ]
+        }
+    },
+
+    "realm": {
+        "provider": "jpa"
+    },
+
+    "user": {
+        "provider": "jpa"
+    },
+
+    "userSessions": {
+        "provider" : "mem"
+    },
+
+    "realmCache": {
+        "provider": "mem"
+    },
+
+    "userCache": {
+        "provider": "mem",
+        "mem": {
+            "maxSize": 20000
+        }
+    },
+
+    "timer": {
+        "provider": "basic"
+    },
+
+    "theme": {
+        "default": "keycloak",
+        "staticMaxAge": 2592000,
+        "cacheTemplates": true,
+        "cacheThemes": true,
+        "folder": {
+          "dir": "${jboss.server.config.dir}/themes"
+        }
+    },
+
+    "login": {
+        "provider": "freemarker"
+    },
+
+    "account": {
+        "provider": "freemarker"
+    },
+
+    "email": {
+        "provider": "freemarker"
+    },
+
+    "scheduled": {
+        "interval": 900
+    },
+
+    "connectionsJpa": {
+        "default": {
+            "dataSource": "java:jboss/datasources/KeycloakDS",
+            "databaseSchema": "update"
+        }
+    }
+}
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/com/google/zxing/core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/com/google/zxing/core/main/module.xml
new file mode 100644
index 0000000..cc18aaa
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/com/google/zxing/core/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="com.google.zxing.core">
+    <resources>
+        <artifact name="${com.google.zxing:core}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/com/google/zxing/javase/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/com/google/zxing/javase/main/module.xml
new file mode 100644
index 0000000..b73ba9b
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/com/google/zxing/javase/main/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="com.google.zxing.javase">
+    <resources>
+        <artifact name="${com.google.zxing:javase}"/>
+    </resources>
+    <dependencies>
+        <module name="com.google.zxing.core"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml
new file mode 100644
index 0000000..10f1103
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/de/idyl/winzipaes/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="de.idyl.winzipaes">
+    <resources>
+        <!-- Insert resources here -->
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/net/iharder/base64/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/net/iharder/base64/main/module.xml
new file mode 100644
index 0000000..ba70430
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/net/iharder/base64/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="net.iharder.base64">
+    <resources>
+        <artifact name="${net.iharder:base64}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/freemarker/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/freemarker/main/module.xml
new file mode 100644
index 0000000..2043bef
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/freemarker/main/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.freemarker">
+    <resources>
+        <artifact name="${org.freemarker:freemarker}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.apache.log4j"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-account-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-account-api/main/module.xml
new file mode 100644
index 0000000..d36887e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-account-api/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-account-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-account-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-account-freemarker/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-account-freemarker/main/module.xml
new file mode 100644
index 0000000..1512a9e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-account-freemarker/main/module.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-account-freemarker">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-account-freemarker}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-forms-common-freemarker"/>
+        <module name="org.keycloak.keycloak-account-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.freemarker"/>
+        <module name="javax.api"/>
+        <module name="javax.ws.rs.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-core/main/module.xml
new file mode 100644
index 0000000..07dcd06
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-adapter-core/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-adapter-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-adapter-core}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="org.jboss.logging"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="net.iharder.base64"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-core/main/module.xml
new file mode 100644
index 0000000..f983726
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-core/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-broker-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-broker-core}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-oidc/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-oidc/main/module.xml
new file mode 100644
index 0000000..1a75cd1
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-oidc/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-broker-oidc">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-broker-oidc}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.ws.rs.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-saml/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-saml/main/module.xml
new file mode 100644
index 0000000..839d9f9
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-broker-saml/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-broker-saml">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-broker-saml}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api" />
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-saml-core"/>
+        <module name="org.keycloak.keycloak-saml-protocol"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.ws.rs.api"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-file/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-file/main/module.xml
new file mode 100644
index 0000000..ef1f1b2
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-file/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-file">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-file}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-export-import-api"/>
+        <module name="org.keycloak.keycloak-export-import-single-file"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-http-client/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-http-client/main/module.xml
new file mode 100755
index 0000000..f52288e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-http-client/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-http-client">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-http-client}"/>
+    </resources>
+    <exports>
+        <include path="META-INF/**"/>
+    </exports>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.apache.httpcomponents"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-infinispan/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-infinispan/main/module.xml
new file mode 100644
index 0000000..94a9f1a
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-infinispan/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-infinispan">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-infinispan}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.infinispan"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-jpa/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-jpa/main/module.xml
new file mode 100644
index 0000000..ef36ac3
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-jpa/main/module.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-jpa">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-jpa}"/>
+    </resources>
+    <exports>
+        <include path="META-INF/**"/>
+    </exports>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="javax.persistence.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.bouncycastle" />
+        <module name="javax.api"/>
+        <module name="org.hibernate" services="import"/>
+        <module name="org.javassist"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
new file mode 100644
index 0000000..8ade3fd
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-jpa-liquibase">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-jpa-liquibase}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-jpa"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.liquibase"/>
+        <module name="javax.persistence.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-mongo/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-mongo/main/module.xml
new file mode 100644
index 0000000..504023f
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-mongo/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-mongo">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-mongo}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.mongodb.mongo-java-driver"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-mongo-update/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-mongo-update/main/module.xml
new file mode 100644
index 0000000..621f06d
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-connections-mongo-update/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-mongo-update">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-connections-mongo-update}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-mongo"/>
+        <module name="org.mongodb.mongo-java-driver"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core/main/module.xml
new file mode 100644
index 0000000..b23c589
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core/main/module.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-core}"/>
+    </resources>
+    <dependencies>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+        <module name="javax.activation.api"/>
+        <module name="sun.jdk" optional="true" />
+        <module name="sun.jdk.jgss" optional="true" />
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core-jaxrs/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core-jaxrs/main/module.xml
new file mode 100644
index 0000000..c773354
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-core-jaxrs/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-core-jaxrs">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-core-jaxrs}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-email-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-email-api/main/module.xml
new file mode 100644
index 0000000..ed433b5
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-email-api/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-email-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-email-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-email-freemarker/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-email-freemarker/main/module.xml
new file mode 100644
index 0000000..a0c371f
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-email-freemarker/main/module.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-email-freemarker">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-email-freemarker}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-forms-common-freemarker"/>
+        <module name="org.keycloak.keycloak-email-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="javax.mail.api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.freemarker"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-api/main/module.xml
new file mode 100644
index 0000000..2f8c152
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-api/main/module.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-events-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-events-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-email/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-email/main/module.xml
new file mode 100644
index 0000000..255f830
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-email/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-events-email">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-events-email}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-email-api"/>
+        <module name="javax.mail.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-jboss-logging/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-jboss-logging/main/module.xml
new file mode 100644
index 0000000..5a6fe2b
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-jboss-logging/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-events-jboss-logging">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-events-jboss-logging}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="javax.ws.rs.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-jpa/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-jpa/main/module.xml
new file mode 100644
index 0000000..12c859e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-jpa/main/module.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-events-jpa">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-events-jpa}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-connections-jpa"/>
+        <module name="javax.persistence.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.javassist"/>
+        <module name="org.hibernate" services="import"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-mongo/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-mongo/main/module.xml
new file mode 100644
index 0000000..4e48e7f
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-events-mongo/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-events-mongo">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-events-mongo}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-connections-mongo"/>
+        <module name="org.mongodb.mongo-java-driver"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-api/main/module.xml
new file mode 100644
index 0000000..2e50335
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-api/main/module.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-export-import-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-export-import-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-dir/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-dir/main/module.xml
new file mode 100644
index 0000000..1cda32b
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-dir/main/module.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-export-import-dir">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-export-import-dir}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model"/>
+        <module name="org.keycloak.keycloak-export-import-api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-single-file/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-single-file/main/module.xml
new file mode 100644
index 0000000..a390929
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-single-file/main/module.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-export-import-single-file">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-export-import-single-file}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model"/>
+        <module name="org.keycloak.keycloak-export-import-api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-zip/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-zip/main/module.xml
new file mode 100644
index 0000000..a33365d
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-export-import-zip/main/module.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-export-import-zip">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-export-import-zip}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model"/>
+        <module name="org.keycloak.keycloak-export-import-api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="de.idyl.winzipaes"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-forms-common-freemarker/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-forms-common-freemarker/main/module.xml
new file mode 100644
index 0000000..c6c6325
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-forms-common-freemarker/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-forms-common-freemarker">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-forms-common-freemarker}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.freemarker"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-forms-common-themes/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-forms-common-themes/main/module.xml
new file mode 100644
index 0000000..0e12a97
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-forms-common-themes/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-forms-common-themes">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-forms-common-themes}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-forms-common-freemarker"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.freemarker"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-invalidation-cache-infinispan/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-invalidation-cache-infinispan/main/module.xml
new file mode 100644
index 0000000..572ab38
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-invalidation-cache-infinispan/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-invalidation-cache-infinispan">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-invalidation-cache-infinispan}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model"/>
+        <module name="org.keycloak.keycloak-connections-infinispan"/>
+        <module name="org.infinispan"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-invalidation-cache-model/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-invalidation-cache-model/main/module.xml
new file mode 100644
index 0000000..1844bc8
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-invalidation-cache-model/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-invalidation-cache-model">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-invalidation-cache-model}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-jboss-adapter-core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
new file mode 100644
index 0000000..6e5b217
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-jboss-adapter-core/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-jboss-adapter-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-jboss-adapter-core}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.picketbox"/>
+        <module name="org.keycloak.keycloak-adapter-core"/>
+        <module name="org.keycloak.keycloak-core"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-js-adapter/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-js-adapter/main/module.xml
new file mode 100644
index 0000000..d99ac75
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-js-adapter/main/module.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-js-adapter">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-js-adapter}"/>
+    </resources>
+    <dependencies>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-kerberos-federation/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-kerberos-federation/main/module.xml
new file mode 100644
index 0000000..4f9da8b
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-kerberos-federation/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-kerberos-federation">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-kerberos-federation}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="net.iharder.base64"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-ldap-federation/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-ldap-federation/main/module.xml
new file mode 100644
index 0000000..e8c9e4d
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-ldap-federation/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-ldap-federation">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-ldap-federation}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-kerberos-federation"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-login-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-login-api/main/module.xml
new file mode 100644
index 0000000..ff6f6ac
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-login-api/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-login-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-login-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-login-freemarker/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-login-freemarker/main/module.xml
new file mode 100644
index 0000000..1cb5c41
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-login-freemarker/main/module.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-login-freemarker">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-login-freemarker}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-forms-common-freemarker"/>
+        <module name="org.keycloak.keycloak-login-api"/>
+        <module name="org.keycloak.keycloak-email-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.freemarker"/>
+        <module name="javax.api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-api/main/module.xml
new file mode 100644
index 0000000..14a0a86
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-api/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.jboss.logging"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-file/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-file/main/module.xml
new file mode 100644
index 0000000..e3ae276
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-file/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-file">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-file}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-file"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-jpa/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-jpa/main/module.xml
new file mode 100644
index 0000000..4f50b7a
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-jpa/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-jpa">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-jpa}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-jpa" services="import"/>
+        <module name="javax.persistence.api"/>
+        <module name="net.iharder.base64"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.javassist"/>
+        <module name="org.hibernate" services="import"/>
+        <module name="org.bouncycastle" />
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-mongo/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-mongo/main/module.xml
new file mode 100644
index 0000000..702406c
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-mongo/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-mongo">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-mongo}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-mongo"/>
+        <module name="org.mongodb.mongo-java-driver"/>
+        <module name="net.iharder.base64"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-infinispan/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-infinispan/main/module.xml
new file mode 100644
index 0000000..23f94b1
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-infinispan/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-sessions-infinispan">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-sessions-infinispan}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-infinispan"/>
+        <module name="org.infinispan"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-jpa/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-jpa/main/module.xml
new file mode 100644
index 0000000..2033069
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-jpa/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-sessions-jpa">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-sessions-jpa}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-jpa"/>
+        <module name="javax.persistence.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.javassist"/>
+        <module name="org.hibernate" services="import"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-mem/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-mem/main/module.xml
new file mode 100644
index 0000000..6a1d101
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-mem/main/module.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-sessions-mem">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-sessions-mem}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-mongo/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-mongo/main/module.xml
new file mode 100644
index 0000000..6993680
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-model-sessions-mongo/main/module.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-model-sessions-mongo">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-model-sessions-mongo}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-mongo"/>
+        <module name="org.mongodb.mongo-java-driver"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-saml-core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-saml-core/main/module.xml
new file mode 100644
index 0000000..c09490e
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-saml-core/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-saml-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-saml-core}"/>
+    </resources>
+    <dependencies>
+        <module name="org.jboss.logging"/>
+        <module name="org.apache.santuario.xmlsec">
+            <imports>
+                <exclude path="javax/*"/>
+            </imports>
+        </module>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-saml-protocol/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-saml-protocol/main/module.xml
new file mode 100644
index 0000000..fc0cd15
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-saml-protocol/main/module.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-saml-protocol">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-saml-protocol}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-saml-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-events-api"/>
+        <module name="org.keycloak.keycloak-account-api"/>
+        <module name="org.keycloak.keycloak-email-api"/>
+        <module name="org.keycloak.keycloak-login-api"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.keycloak.keycloak-forms-common-freemarker"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="org.jboss.logging"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.resteasy.resteasy-crypto"/>
+        <module name="org.jboss.resteasy.resteasy-multipart-provider"/>
+        <module name="org.keycloak.keycloak-connections-http-client" services="import"/>
+
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server/main/module.xml
new file mode 100644
index 0000000..6c87781
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server/main/module.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-server">
+    <resources>
+        <artifact name="${org.keycloak.subsystem:keycloak-server}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-account-api" services="import"/>
+        <module name="org.keycloak.keycloak-account-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-connections-infinispan" services="import"/>
+        <module name="org.keycloak.keycloak-connections-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-connections-jpa-liquibase" services="import"/>
+        <module name="org.keycloak.keycloak-connections-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-connections-mongo-update" services="import"/>
+        <module name="org.keycloak.keycloak-connections-file" services="import"/>
+        <module name="org.keycloak.keycloak-core" services="import"/>
+        <module name="org.keycloak.keycloak-core-jaxrs" services="import"/>
+        <module name="org.keycloak.keycloak-email-api" services="import"/>
+        <module name="org.keycloak.keycloak-email-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-events-api" services="import"/>
+        <module name="org.keycloak.keycloak-events-email" services="import"/>
+        <module name="org.keycloak.keycloak-events-jboss-logging" services="import"/>
+        <module name="org.keycloak.keycloak-events-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-events-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-api" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-dir" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-zip" services="import"/>
+        <module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model" services="import"/>
+        <module name="org.keycloak.keycloak-js-adapter" services="import"/>
+        <module name="org.keycloak.keycloak-kerberos-federation" services="import"/>
+        <module name="org.keycloak.keycloak-ldap-federation" services="import"/>
+        <module name="org.keycloak.keycloak-login-api" services="import"/>
+        <module name="org.keycloak.keycloak-login-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-model-api" services="import"/>
+        <module name="org.keycloak.keycloak-model-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-model-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-mem" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-saml-protocol" services="import"/>
+        <module name="org.keycloak.keycloak-services" export="true" services="import"/>
+        <module name="org.keycloak.keycloak-social-core" services="import"/>
+        <module name="org.keycloak.keycloak-social-facebook" services="import"/>
+        <module name="org.keycloak.keycloak-social-github" services="import"/>
+        <module name="org.keycloak.keycloak-social-google" services="import"/>
+        <module name="org.keycloak.keycloak-social-twitter" services="import"/>
+        <module name="org.keycloak.keycloak-social-linkedin" services="import"/>
+        <module name="org.keycloak.keycloak-social-stackoverflow" services="import"/>
+        <module name="org.keycloak.keycloak-server-subsystem" services="import"/>
+        <module name="org.keycloak.keycloak-timer-api" services="import"/>
+        <module name="org.keycloak.keycloak-timer-basic" services="import"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml
new file mode 100644
index 0000000..5233767
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-server-subsystem/main/module.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-server-subsystem">
+    <properties>
+        <property name="keycloak-version" value="${project.version}"/>
+        <property name="auth-server-exploded" value="false"/>
+    </properties>
+
+    <resources>
+        <resource-root path="."/>
+        <artifact name="${org.keycloak:keycloak-wildfly-server-subsystem}"/>
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.jboss.staxmapper"/>
+        <module name="org.jboss.as.controller"/>
+        <module name="org.jboss.as.ee"/>
+        <module name="org.jboss.as.server"/>
+        <module name="org.jboss.modules"/>
+        <module name="org.jboss.msc"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.jboss.vfs"/>
+        <module name="org.jboss.as.web-common" optional="true"/>
+        <module name="org.jboss.as.web" optional="true"/>
+        <module name="org.jboss.as.version" optional="true"/>
+        <module name="org.keycloak.keycloak-wildfly-adapter" optional="true"/>
+        <module name="org.jboss.metadata"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-services/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-services/main/module.xml
new file mode 100644
index 0000000..598d5dd
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-services/main/module.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-services">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-services}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-account-api" services="import"/>
+        <module name="org.keycloak.keycloak-account-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-broker-core" services="import"/>
+        <module name="org.keycloak.keycloak-broker-oidc" services="import"/>
+        <module name="org.keycloak.keycloak-broker-saml" services="import"/>
+        <module name="org.keycloak.keycloak-connections-http-client" services="import"/>
+        <module name="org.keycloak.keycloak-connections-infinispan" services="import"/>
+        <module name="org.keycloak.keycloak-connections-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-connections-jpa-liquibase" services="import"/>
+        <module name="org.keycloak.keycloak-connections-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-connections-mongo-update" services="import"/>
+        <module name="org.keycloak.keycloak-connections-file" services="import"/>
+        <module name="org.keycloak.keycloak-core" services="import"/>
+        <module name="org.keycloak.keycloak-core-jaxrs" services="import"/>
+        <module name="org.keycloak.keycloak-email-api" services="import"/>
+        <module name="org.keycloak.keycloak-email-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-events-api" services="import"/>
+        <module name="org.keycloak.keycloak-events-email" services="import"/>
+        <module name="org.keycloak.keycloak-events-jboss-logging" services="import"/>
+        <module name="org.keycloak.keycloak-events-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-events-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-api" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-dir" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
+        <module name="org.keycloak.keycloak-export-import-zip" services="import"/>
+        <module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
+        <module name="org.keycloak.keycloak-invalidation-cache-model" services="import"/>
+        <module name="org.keycloak.keycloak-jboss-adapter-core" services="import"/>
+        <module name="org.keycloak.keycloak-js-adapter" services="import"/>
+        <module name="org.keycloak.keycloak-kerberos-federation" services="import"/>
+        <module name="org.keycloak.keycloak-ldap-federation" services="import"/>
+        <module name="org.keycloak.keycloak-login-api" services="import"/>
+        <module name="org.keycloak.keycloak-login-freemarker" services="import"/>
+        <module name="org.keycloak.keycloak-model-api" services="import"/>
+        <module name="org.keycloak.keycloak-model-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-model-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-model-file" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-infinispan" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-jpa" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-mem" services="import"/>
+        <module name="org.keycloak.keycloak-model-sessions-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-wildfly-extensions" services="import"/>
+
+        <module name="org.keycloak.keycloak-saml-protocol" services="import"/>
+        <module name="org.keycloak.keycloak-services" export="true" services="import"/>
+        <module name="org.keycloak.keycloak-social-core" services="import"/>
+        <module name="org.keycloak.keycloak-social-facebook" services="import"/>
+        <module name="org.keycloak.keycloak-social-github" services="import"/>
+        <module name="org.keycloak.keycloak-social-google" services="import"/>
+        <module name="org.keycloak.keycloak-social-twitter" services="import"/>
+        <module name="org.keycloak.keycloak-social-linkedin" services="import"/>
+        <module name="org.keycloak.keycloak-social-stackoverflow" services="import"/>
+        <module name="org.keycloak.keycloak-timer-api" services="import"/>
+        <module name="org.keycloak.keycloak-timer-basic" services="import"/>
+
+        <module name="javax.ws.rs.api"/>
+        <module name="org.jboss.resteasy.resteasy-jaxrs"/>
+        <module name="org.jboss.resteasy.resteasy-crypto"/>
+        <module name="org.jboss.resteasy.resteasy-multipart-provider"/>
+        <module name="javax.servlet.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="com.google.zxing.core"/>
+        <module name="com.google.zxing.javase"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.bouncycastle" />
+        <module name="net.iharder.base64"/>
+        <module name="javax.api"/>
+        <module name="javax.activation.api"/>
+        <module name="org.apache.httpcomponents"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-core/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-core/main/module.xml
new file mode 100644
index 0000000..836d5d6
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-core/main/module.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-core">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-core}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-facebook/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-facebook/main/module.xml
new file mode 100644
index 0000000..4c22779
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-facebook/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-facebook">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-facebook}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-broker-oidc"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-github/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-github/main/module.xml
new file mode 100644
index 0000000..9197bb0
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-github/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-github">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-github}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-broker-oidc"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-google/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-google/main/module.xml
new file mode 100644
index 0000000..bb56189
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-google/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-google">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-google}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-broker-oidc"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-linkedin/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-linkedin/main/module.xml
new file mode 100644
index 0000000..db38543
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-linkedin/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-linkedin">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-linkedin}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-broker-oidc"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-stackoverflow/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-stackoverflow/main/module.xml
new file mode 100644
index 0000000..5af13ce
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-stackoverflow/main/module.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-stackoverflow">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-stackoverflow}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-broker-oidc"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-twitter/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-twitter/main/module.xml
new file mode 100644
index 0000000..cf56209
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-social-twitter/main/module.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-social-twitter">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-social-twitter}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-social-core"/>
+        <module name="org.keycloak.keycloak-broker-core"/>
+        <module name="org.keycloak.keycloak-broker-oidc"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.twitter4j"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+        <module name="javax.ws.rs.api"/>
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-timer-api/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-timer-api/main/module.xml
new file mode 100644
index 0000000..7704916
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-timer-api/main/module.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-timer-api">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-timer-api}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-timer-basic/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-timer-basic/main/module.xml
new file mode 100644
index 0000000..e2279f9
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-timer-basic/main/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-timer-basic">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-timer-basic}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-timer-api"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-undertow-adapter/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-undertow-adapter/main/module.xml
new file mode 100644
index 0000000..9ba1cb2
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-undertow-adapter/main/module.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-undertow-adapter">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-undertow-adapter}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.bouncycastle" />
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="javax.servlet.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.jboss.xnio"/>
+        <module name="io.undertow.core"/>
+        <module name="io.undertow.servlet"/>
+        <module name="org.keycloak.keycloak-adapter-core"/>
+        <module name="org.keycloak.keycloak-core"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-adapter/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-adapter/main/module.xml
new file mode 100644
index 0000000..df7cc03
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-adapter/main/module.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-wildfly-adapter">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-wildfly-adapter}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.bouncycastle" />
+        <module name="org.codehaus.jackson.jackson-core-asl"/>
+        <module name="org.codehaus.jackson.jackson-mapper-asl"/>
+        <module name="org.codehaus.jackson.jackson-xc"/>
+        <module name="org.apache.httpcomponents" />
+        <module name="javax.servlet.api"/>
+        <module name="org.jboss.logging"/>
+        <module name="io.undertow.core"/>
+        <module name="io.undertow.servlet"/>
+        <module name="org.picketbox"/>
+        <module name="org.keycloak.keycloak-undertow-adapter"/>
+        <module name="org.keycloak.keycloak-adapter-core"/>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.jboss.xnio"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-extensions/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-extensions/main/module.xml
new file mode 100644
index 0000000..05a48e5
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/keycloak/keycloak-wildfly-extensions/main/module.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-wildfly-extensions">
+    <resources>
+        <artifact name="${org.keycloak:keycloak-wildfly-extensions}"/>
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.keycloak.keycloak-forms-common-freemarker"/>
+        <module name="org.keycloak.keycloak-forms-common-themes"/>
+        <module name="org.jboss.modules"/>
+    </dependencies>
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/liquibase/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/liquibase/main/module.xml
new file mode 100644
index 0000000..d75eef0
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/liquibase/main/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.liquibase">
+    <resources>
+        <artifact name="${org.liquibase:liquibase-core}"/>
+    </resources>
+    <dependencies>
+        <module name="org.apache.commons.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/mongodb/mongo-java-driver/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/mongodb/mongo-java-driver/main/module.xml
new file mode 100644
index 0000000..bb4acdd
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/mongodb/mongo-java-driver/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.mongodb.mongo-java-driver">
+    <resources>
+        <artifact name="${org.mongodb:mongo-java-driver}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/twitter4j/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/twitter4j/main/module.xml
new file mode 100644
index 0000000..70b84dc
--- /dev/null
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/base/org/twitter4j/main/module.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.twitter4j">
+    <resources>
+        <artifact name="${org.twitter4j:twitter4j-core}"/>
+    </resources>
+    <dependencies>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
diff --git a/distribution/modules/build.xml b/distribution/modules/build.xml
index 0fdcfa4..e7ede69 100755
--- a/distribution/modules/build.xml
+++ b/distribution/modules/build.xml
@@ -336,8 +336,11 @@
             <maven-resource group="org.keycloak" artifact="keycloak-wildfly-adapter"/>
         </module-def>
 
-        <module-def name="org.keycloak.keycloak-subsystem">
-            <maven-resource group="org.keycloak" artifact="keycloak-subsystem"/>
+        <module-def name="org.keycloak.keycloak-server-subsystem">
+            <maven-resource group="org.keycloak" artifact="keycloak-wildfly-server-subsystem"/>
+        </module-def>
+        <module-def name="org.keycloak.keycloak-adapter-subsystem">
+            <maven-resource group="org.keycloak" artifact="keycloak-wildfly-adapter-subsystem"/>
         </module-def>
         <module-def name="org.keycloak.keycloak-as7-subsystem">
             <maven-resource group="org.keycloak" artifact="keycloak-as7-subsystem"/>
diff --git a/distribution/modules/pom.xml b/distribution/modules/pom.xml
index da8260d..501e422 100755
--- a/distribution/modules/pom.xml
+++ b/distribution/modules/pom.xml
@@ -56,7 +56,13 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-subsystem</artifactId>
+            <artifactId>keycloak-wildfly-server-subsystem</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-wildfly-adapter-subsystem</artifactId>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.keycloak.subsystem</groupId>
@@ -174,7 +180,7 @@
                                     <artifactId>keycloak-server</artifactId>
                                     <type>war</type>
                                     <overWrite>true</overWrite>
-                                    <outputDirectory>${project.build.directory}/modules/org/keycloak/keycloak-subsystem/main/auth-server</outputDirectory>
+                                    <outputDirectory>${project.build.directory}/modules/org/keycloak/keycloak-server-subsystem/main/auth-server</outputDirectory>
                                 </artifactItem>
                             </artifactItems>
                         </configuration>
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-adapter-subsystem/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-adapter-subsystem/main/module.xml
new file mode 100755
index 0000000..3408a92
--- /dev/null
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-adapter-subsystem/main/module.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2014, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-adapter-subsystem">
+    <properties>
+        <property name="keycloak-version" value="${project.version}"/>
+    </properties>
+
+    <resources>
+        <resource-root path="."/>
+        <!-- Insert resources here -->
+    </resources>
+
+    <dependencies>
+        <module name="javax.api"/>
+        <module name="org.jboss.staxmapper"/>
+        <module name="org.jboss.as.controller"/>
+        <module name="org.jboss.as.ee"/>
+        <module name="org.jboss.as.server"/>
+        <module name="org.jboss.modules"/>
+        <module name="org.jboss.msc"/>
+        <module name="org.jboss.logging"/>
+        <module name="org.jboss.vfs"/>
+        <module name="org.jboss.as.web-common" optional="true"/>
+        <module name="org.jboss.as.web" optional="true"/>
+        <module name="org.jboss.as.version" optional="true"/>
+        <module name="org.keycloak.keycloak-as7-adapter" optional="true"/>
+        <module name="org.jboss.metadata"/>
+    </dependencies>
+</module>
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml
index ddf2475..9a7229f 100755
--- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml
@@ -10,6 +10,7 @@
         <module name="org.keycloak.keycloak-account-api" services="import"/>
         <module name="org.keycloak.keycloak-account-freemarker" services="import"/>
         <module name="org.keycloak.keycloak-adapter-core" services="import"/>
+        <module name="org.keycloak.keycloak-adapter-subsystem" services="import"/>
         <module name="org.keycloak.keycloak-as7-adapter" services="import"/>
         <module name="org.keycloak.keycloak-as7-subsystem" services="import"/>
         <module name="org.keycloak.keycloak-connections-infinispan" services="import"/>
@@ -57,7 +58,7 @@
         <module name="org.keycloak.keycloak-social-twitter" services="import"/>
         <module name="org.keycloak.keycloak-social-linkedin" services="import"/>
         <module name="org.keycloak.keycloak-social-stackoverflow" services="import"/>
-        <module name="org.keycloak.keycloak-subsystem" services="import"/>
+        <module name="org.keycloak.keycloak-server-subsystem" services="import"/>
         <module name="org.keycloak.keycloak-timer-api" services="import"/>
         <module name="org.keycloak.keycloak-timer-basic" services="import"/>
         <module name="org.keycloak.keycloak-undertow-adapter" services="import"/>
diff --git a/distribution/pom.xml b/distribution/pom.xml
index d09fbb8..8eeaafc 100755
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -37,5 +37,6 @@
         <module>server-overlay</module>
         <module>src-dist</module>
         <module>subsystem-war</module>
+        <module>feature-packs</module>
     </modules>
 </project>
diff --git a/distribution/server-dist/assembly.xml b/distribution/server-dist/assembly.xml
index b677d2c..6f0c028 100755
--- a/distribution/server-dist/assembly.xml
+++ b/distribution/server-dist/assembly.xml
@@ -8,55 +8,60 @@
 
     <includeBaseDirectory>true</includeBaseDirectory>
 
+    <!-- If war is filtered it will get corrupted. Only need to filter module.xml -->
     <fileSets>
         <fileSet>
-            <directory>${project.build.directory}/unpacked/wildfly-${wildfly.version}</directory>
-            <outputDirectory></outputDirectory>
+            <directory>target/${project.build.finalName}</directory>
+            <outputDirectory/>
+            <filtered>true</filtered>
+            <includes>
+                <include>**/module.xml</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>target/${project.build.finalName}</directory>
+            <outputDirectory/>
+            <filtered>false</filtered>
             <excludes>
-                <exclude>**/*.sh</exclude>
+                <exclude>**/module.xml</exclude>
                 <exclude>welcome-content/**</exclude>
-                <exclude>docs/**</exclude>
+                <exclude>appclient</exclude>
+                <exclude>appclient/*</exclude>
                 <exclude>standalone/deployments</exclude>
                 <exclude>standalone/deployments/*</exclude>
-                <exclude>standalone/configuration/standalone*.xml</exclude>
             </excludes>
         </fileSet>
         <fileSet>
-            <directory>${project.build.directory}/unpacked</directory>
-            <outputDirectory>standalone/configuration</outputDirectory>
+            <directory>src/main/welcome-content</directory>
+            <outputDirectory>welcome-content</outputDirectory>
             <includes>
-                <include>standalone*.xml</include>
+                <include>*.*</include>
             </includes>
         </fileSet>
         <fileSet>
-            <directory>${project.build.directory}/unpacked/wildfly-${wildfly.version}</directory>
-            <outputDirectory></outputDirectory>
+            <directory>../../forms/common-themes/src/main/resources/theme</directory>
+            <outputDirectory>standalone/configuration/themes</outputDirectory>
             <includes>
-                <include>**/*.sh</include>
+                <include>**/**</include>
             </includes>
-            <fileMode>0755</fileMode>
         </fileSet>
         <fileSet>
-            <directory>src/main/welcome-content</directory>
-            <outputDirectory>welcome-content</outputDirectory>
+            <directory>../../</directory>
             <includes>
-                <include>*.*</include>
+                <include>License.html</include>
             </includes>
+            <outputDirectory></outputDirectory>
         </fileSet>
     </fileSets>
 
-    <dependencySets>
-        <dependencySet>
-            <includes>
-                <include>org.keycloak:keycloak-server-overlay:zip</include>
-            </includes>
-            <outputDirectory></outputDirectory>
-            <unpack>true</unpack>
-            <unpackOptions>
-                <excludes>
-                    <exclude>standalone/configuration/standalone-keycloak.xml</exclude>
-                </excludes>
-            </unpackOptions>
-        </dependencySet>
-    </dependencySets>
+    <files>
+        <file>
+            <source>../server-overlay/src/main/themes/README.txt</source>
+            <outputDirectory>standalone/configuration/themes</outputDirectory>
+        </file>
+        <file>
+            <source>../server-overlay/src/main/providers/README.txt</source>
+            <outputDirectory>standalone/configuration/providers</outputDirectory>
+        </file>
+    </files>
 </assembly>
diff --git a/distribution/server-dist/pom.xml b/distribution/server-dist/pom.xml
index 07c00ea..cc76727 100755
--- a/distribution/server-dist/pom.xml
+++ b/distribution/server-dist/pom.xml
@@ -28,58 +28,26 @@
 
     <build>
         <finalName>keycloak-${project.version}</finalName>
+
         <plugins>
             <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-dependency-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>unpack-wildfly</id>
-                        <phase>prepare-package</phase>
-                        <goals>
-                            <goal>unpack</goal>
-                        </goals>
-                        <configuration>
-                            <artifactItems>
-                                <artifactItem>
-                                    <groupId>org.wildfly</groupId>
-                                    <artifactId>wildfly-dist</artifactId>
-                                    <version>${wildfly.version}</version>
-                                    <type>zip</type>
-                                    <outputDirectory>${project.build.directory}/unpacked</outputDirectory>
-                                </artifactItem>
-                            </artifactItems>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>xml-maven-plugin</artifactId>
-                <version>1.0</version>
+                <groupId>org.wildfly.build</groupId>
+                <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
                 <executions>
                     <execution>
-                        <id>generate-resources</id>
-                        <phase>package</phase>
+                        <id>server-provisioning</id>
                         <goals>
-                            <goal>transform</goal>
+                            <goal>build</goal>
                         </goals>
+                        <phase>compile</phase>
                         <configuration>
-                            <transformationSets>
-                                <transformationSet>
-                                    <dir>${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration</dir>
-                                    <stylesheet>src/main/xslt/standalone.xsl</stylesheet>
-                                    <includes>
-                                        <include>standalone*.xml</include>
-                                    </includes>
-                                    <outputDir>${project.build.directory}/unpacked</outputDir>
-                                </transformationSet>
-                            </transformationSets>
+                            <config-file>server-provisioning.xml</config-file>
                         </configuration>
                     </execution>
                 </executions>
             </plugin>
             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
                     <execution>
@@ -92,9 +60,11 @@
                             <descriptors>
                                 <descriptor>assembly.xml</descriptor>
                             </descriptors>
-                            <outputDirectory>target</outputDirectory>
-                            <workDirectory>target/assembly/work</workDirectory>
+                            <recompressZippedFiles>true</recompressZippedFiles>
+                            <finalName>${project.build.finalName}</finalName>
                             <appendAssemblyId>false</appendAssemblyId>
+                            <outputDirectory>${project.build.directory}</outputDirectory>
+                            <workDirectory>${project.build.directory}/assembly/work</workDirectory>
                             <tarLongFileMode>gnu</tarLongFileMode>
                         </configuration>
                     </execution>
diff --git a/distribution/server-dist/server-provisioning.xml b/distribution/server-dist/server-provisioning.xml
new file mode 100644
index 0000000..d414b95
--- /dev/null
+++ b/distribution/server-dist/server-provisioning.xml
@@ -0,0 +1,22 @@
+<!--
+~ JBoss, Home of Professional Open Source.
+~ Copyright 2015 Red Hat, Inc., and individual contributors
+~ as indicated by the @author tags.
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<server-provisioning xmlns="urn:wildfly:server-provisioning:1.0" extract-schemas="true" copy-module-artifacts="true">
+    <feature-packs>
+        <feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>     
+    </feature-packs>
+</server-provisioning>
\ No newline at end of file
diff --git a/distribution/server-overlay/src/main/xslt/standalone.xsl b/distribution/server-overlay/src/main/xslt/standalone.xsl
index 0180557..9e7d309 100755
--- a/distribution/server-overlay/src/main/xslt/standalone.xsl
+++ b/distribution/server-overlay/src/main/xslt/standalone.xsl
@@ -16,7 +16,8 @@
     <xsl:template match="//j:extensions">
         <xsl:copy>
             <xsl:apply-templates select="node()|@*"/>
-            <extension module="org.keycloak.keycloak-subsystem"/>
+            <extension module="org.keycloak.keycloak-server-subsystem"/>
+            <extension module="org.keycloak.keycloak-adapter-subsystem"/>
         </xsl:copy>
     </xsl:template>
 
@@ -38,7 +39,7 @@
     <xsl:template match="//j:profile">
         <xsl:copy>
             <xsl:apply-templates select="node()|@*"/>
-            <subsystem xmlns="urn:jboss:domain:keycloak:1.0">
+            <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
                 <auth-server name="main-auth-server">
                     <enabled>true</enabled>
                     <web-context>auth</web-context>
diff --git a/docbook/reference/en/en-US/modules/javascript-adapter.xml b/docbook/reference/en/en-US/modules/javascript-adapter.xml
index 80f04ed..30f8dd0 100755
--- a/docbook/reference/en/en-US/modules/javascript-adapter.xml
+++ b/docbook/reference/en/en-US/modules/javascript-adapter.xml
@@ -305,6 +305,23 @@ keycloak.updateToken(5).success(function(refreshed) {
 ]]></programlisting>
 
             </simplesect>
+
+            <simplesect>
+                <title>clearToken()</title>
+
+                <para>
+                    Clear authentication state, including tokens. This can be useful if application has detected the session
+                    has expired, for example if updating token fails. Invoking this results in onAuthLogout callback listener
+                    being invoked.
+                </para>
+
+                <programlisting><![CDATA[
+keycloak.updateToken(5).error(function() {
+    keycloak.clearToken();
+});
+]]></programlisting>
+
+            </simplesect>
         </section>
 
         <section>
diff --git a/docbook/reference/en/en-US/modules/server-installation.xml b/docbook/reference/en/en-US/modules/server-installation.xml
index e6cd134..9c321a2 100755
--- a/docbook/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/reference/en/en-US/modules/server-installation.xml
@@ -195,7 +195,7 @@
                         <term>databaseSchema</term>
                         <listitem>
                             <para>
-                                Value of database schema (Hibernate property "hibernate.hbm2ddl.auto" ).
+                                Specify if schema should be updated or validated. Valid values are "update" and "validate" ("update is default).
                             </para>
                         </listitem>
                     </varlistentry>
diff --git a/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java b/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java
new file mode 100644
index 0000000..4225501
--- /dev/null
+++ b/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java
@@ -0,0 +1,119 @@
+package org.keycloak.events.admin;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AdminEvent {
+
+    private long time;
+    
+    private String realmId;
+
+    private AuthDetails authDetails;
+
+    private OperationType operationType;
+
+    private String resourcePath;
+
+    private String representation;
+
+    private String error;
+    
+    /**
+     * Returns the time of the event
+     *
+     * @return time in millis
+     */
+    public long getTime() {
+        return time;
+    }
+
+    public void setTime(long time) {
+        this.time = time;
+    }
+    
+    /**
+     * Returns the id of the realm
+     *
+     * @return
+     */
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    /**
+     * Returns authentication details
+     *
+     * @return
+     */
+    public AuthDetails getAuthDetails() {
+        return authDetails;
+    }
+
+    public void setAuthDetails(AuthDetails authDetails) {
+        this.authDetails = authDetails;
+    }
+
+    /**
+     * Returns the type of the operation
+     *
+     * @return
+     */
+    public OperationType getOperationType() {
+        return operationType;
+    }
+
+    public void setOperationType(OperationType operationType) {
+        this.operationType = operationType;
+    }
+
+    /**
+     * Returns the path of the resource. For example:
+     * <ul>
+     *     <li><b>realms</b> - realm list</li>
+     *     <li><b>realms/master</b> - master realm</li>
+     *     <li><b>realms/clients/00d4b16f-f1f9-4e73-8366-d76b18f3e0e1</b> - client within the master realm</li>
+     * </ul>
+     *
+     * @return
+     */
+    public String getResourcePath() {
+        return resourcePath;
+    }
+
+    public void setResourcePath(String resourcePath) {
+        this.resourcePath = resourcePath;
+    }
+
+    /**
+     * Returns the updated JSON representation if <code>operationType</code> is <code>CREATE</code> or <code>UPDATE</code>.
+     * Otherwise returns <code>null</code>.
+     *
+     * @return
+     */
+    public String getRepresentation() {
+        return representation;
+    }
+
+    public void setRepresentation(String representation) {
+        this.representation = representation;
+    }
+
+    /**
+     * If the event was unsuccessful returns the error message. Otherwise returns <code>null</code>.
+     *
+     * @return
+     */
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+}
diff --git a/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java b/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java
new file mode 100644
index 0000000..d7b5fe4
--- /dev/null
+++ b/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java
@@ -0,0 +1,110 @@
+package org.keycloak.events.admin;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public interface AdminEventQuery {
+    
+    /**
+     * Search by resource realm
+     *
+     * @param realmId realm id
+     * @return Associated <code>AdminEventQuery</code> for method chaining
+     */
+    AdminEventQuery realm(String realmId);
+    
+    /**
+     * Search by authentication realm
+     *
+     * @param realmId realm name
+     * @return Associated <code>AdminEventQuery</code> for method chaining
+     */
+    AdminEventQuery authRealm(String realmId);
+    
+    /**
+     * Search by authenticated client
+     *
+     * @param clientId client uuid
+     * @return Associated <code>AdminEventQuery</code> for method chaining
+     */
+    AdminEventQuery authClient(String clientId);
+
+    /**
+     * Search by authenticated user
+     *
+     * @param userId user uuid
+     * @return Associated <code>AdminEventQuery</code> for method chaining
+     */
+    AdminEventQuery authUser(String userId);
+
+    /**
+     * Search by request ip address
+     *
+     * @param ipAddress
+     * @return Associated <code>AdminEventQuery</code> for method chaining
+     */
+    AdminEventQuery authIpAddress(String ipAddress);
+
+    /**
+     * Search by operation type
+     *
+     * @param operations
+     * @return <code>this</code> for method chaining
+     */
+    AdminEventQuery operation(OperationType... operations);
+
+    /**
+     * Search by resource path. Supports wildcards <code>*</code> and <code>**</code>. For example:
+     * <ul>
+     * <li><b>*&#47;master</b> - matches 'realms/master'</li>
+     * <li><b>**&#47;00d4b16f</b> - matches 'realms/master/clients/00d4b16f'</li>
+     * <li><b>realms&#47;master&#47;**</b> - matches anything under 'realms/master'</li>
+     * </ul>
+     *
+     * @param resourcePath
+     * @return <code>this</code> for method chaining
+     */
+    AdminEventQuery resourcePath(String resourcePath);
+
+    /**
+     * Search by events after the specified time
+     * 
+     * @param fromTime time in millis
+     * @return <code>this</code> for method chaining
+     */
+    AdminEventQuery fromTime(String fromTime);
+
+    /**
+     * Search by events before the specified time
+     * 
+     * @param toTime time in millis
+     * @return <code>this</code> for method chaining
+     */
+    AdminEventQuery toTime(String toTime);
+
+    /**
+     * Used for pagination
+     * 
+     * @param first first result to return
+     * @return <code>this</code> for method chaining
+     */
+    AdminEventQuery firstResult(int first);
+
+    /**
+     * Use for pagination
+     * 
+     * @param max the maximum results to return
+     * @return <code>this</code> for method chaining
+     */
+    AdminEventQuery maxResults(int max);
+
+    /**
+     * Executes the query and returns the results
+     * 
+     * @return
+     */
+    List<AdminEvent> getResultList();
+
+}
diff --git a/events/api/src/main/java/org/keycloak/events/admin/AuthDetails.java b/events/api/src/main/java/org/keycloak/events/admin/AuthDetails.java
new file mode 100644
index 0000000..d32eff1
--- /dev/null
+++ b/events/api/src/main/java/org/keycloak/events/admin/AuthDetails.java
@@ -0,0 +1,48 @@
+package org.keycloak.events.admin;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AuthDetails {
+
+    private String realmId;
+
+    private String clientId;
+
+    private String userId;
+
+    private String ipAddress;
+
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+}
diff --git a/events/api/src/main/java/org/keycloak/events/admin/AuthQuery.java b/events/api/src/main/java/org/keycloak/events/admin/AuthQuery.java
new file mode 100644
index 0000000..3be431f
--- /dev/null
+++ b/events/api/src/main/java/org/keycloak/events/admin/AuthQuery.java
@@ -0,0 +1,48 @@
+package org.keycloak.events.admin;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AuthQuery {
+
+    private String realmId;
+
+    private String clientId;
+
+    private String userId;
+
+    private String ipAddress;
+
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+}
diff --git a/events/api/src/main/java/org/keycloak/events/admin/OperationType.java b/events/api/src/main/java/org/keycloak/events/admin/OperationType.java
new file mode 100755
index 0000000..ca3ae20
--- /dev/null
+++ b/events/api/src/main/java/org/keycloak/events/admin/OperationType.java
@@ -0,0 +1,13 @@
+package org.keycloak.events.admin;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public enum OperationType {
+
+    CREATE,
+    UPDATE,
+    DELETE,
+    ACTION;
+
+}
diff --git a/events/api/src/main/java/org/keycloak/events/EventBuilder.java b/events/api/src/main/java/org/keycloak/events/EventBuilder.java
index 4945989..ee7a70a 100644
--- a/events/api/src/main/java/org/keycloak/events/EventBuilder.java
+++ b/events/api/src/main/java/org/keycloak/events/EventBuilder.java
@@ -7,6 +7,7 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+import org.keycloak.util.Time;
 
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -149,7 +150,7 @@ public class EventBuilder {
     }
 
     private void send() {
-        event.setTime(System.currentTimeMillis());
+        event.setTime(Time.toMillis(Time.currentTime()));
 
         if (store != null) {
             if (realm.getEnabledEventTypes() != null && !realm.getEnabledEventTypes().isEmpty() ? realm.getEnabledEventTypes().contains(event.getType().name()) : event.getType().isSaveByDefault()) {
diff --git a/events/api/src/main/java/org/keycloak/events/EventListenerProvider.java b/events/api/src/main/java/org/keycloak/events/EventListenerProvider.java
index 01ab302..957d639 100644
--- a/events/api/src/main/java/org/keycloak/events/EventListenerProvider.java
+++ b/events/api/src/main/java/org/keycloak/events/EventListenerProvider.java
@@ -1,5 +1,6 @@
 package org.keycloak.events;
 
+import org.keycloak.events.admin.AdminEvent;
 import org.keycloak.provider.Provider;
 
 /**
@@ -9,4 +10,6 @@ public interface EventListenerProvider extends Provider {
 
     public void onEvent(Event event);
 
+    public void onEvent(AdminEvent event, boolean includeRepresentation);
+
 }
diff --git a/events/api/src/main/java/org/keycloak/events/EventListenerSpi.java b/events/api/src/main/java/org/keycloak/events/EventListenerSpi.java
index 70cdea4..a16ad46 100644
--- a/events/api/src/main/java/org/keycloak/events/EventListenerSpi.java
+++ b/events/api/src/main/java/org/keycloak/events/EventListenerSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class EventListenerSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return false;
+    }
+
+    @Override
     public String getName() {
         return "eventsListener";
     }
diff --git a/events/api/src/main/java/org/keycloak/events/EventStoreProvider.java b/events/api/src/main/java/org/keycloak/events/EventStoreProvider.java
index c742556..afdaf92 100644
--- a/events/api/src/main/java/org/keycloak/events/EventStoreProvider.java
+++ b/events/api/src/main/java/org/keycloak/events/EventStoreProvider.java
@@ -1,5 +1,7 @@
 package org.keycloak.events;
 
+import org.keycloak.events.admin.AdminEventQuery;
+
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
@@ -7,10 +9,18 @@ public interface EventStoreProvider extends EventListenerProvider {
 
     public EventQuery createQuery();
 
+    public AdminEventQuery createAdminQuery();
+
     public void clear();
 
     public void clear(String realmId);
 
     public void clear(String realmId, long olderThan);
 
+    public void clearAdmin();
+
+    public void clearAdmin(String realmId);
+
+    public void clearAdmin(String realmId, long olderThan);
+
 }
diff --git a/events/api/src/main/java/org/keycloak/events/EventStoreSpi.java b/events/api/src/main/java/org/keycloak/events/EventStoreSpi.java
index 573fc86..af5f59f 100644
--- a/events/api/src/main/java/org/keycloak/events/EventStoreSpi.java
+++ b/events/api/src/main/java/org/keycloak/events/EventStoreSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class EventStoreSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "eventsStore";
     }
diff --git a/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
index 71a432a..400ef04 100755
--- a/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
+++ b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
@@ -3,6 +3,7 @@ package org.keycloak.events.email;
 import org.jboss.logging.Logger;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
+import org.keycloak.events.admin.AdminEvent;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventListenerProvider;
 import org.keycloak.events.EventType;
@@ -50,6 +51,11 @@ public class EmailEventListenerProvider implements EventListenerProvider {
     }
 
     @Override
+    public void onEvent(AdminEvent event, boolean includeRepresentation) {
+
+    }
+
+    @Override
     public void close() {
     }
 
diff --git a/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java b/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java
index dba4304..38283f7 100755
--- a/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java
+++ b/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java
@@ -1,6 +1,7 @@
 package org.keycloak.events.log;
 
 import org.jboss.logging.Logger;
+import org.keycloak.events.admin.AdminEvent;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventListenerProvider;
 import org.keycloak.models.KeycloakContext;
@@ -9,8 +10,8 @@ import org.keycloak.models.KeycloakSession;
 import javax.ws.rs.core.Cookie;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.Map;
-import java.util.logging.Level;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -66,29 +67,42 @@ public class JBossLoggingEventListenerProvider implements EventListenerProvider 
                     }
                 }
             }
+            
+            if(logger.isTraceEnabled()) {
+                setKeycloakContext(sb);
+            }
 
-            if (logger.isTraceEnabled()) {
-                KeycloakContext context = session.getContext();
-                UriInfo uriInfo = context.getUri();
-                HttpHeaders headers = context.getRequestHeaders();
-                if (uriInfo != null) {
-                    sb.append(", requestUri=");
-                    sb.append(uriInfo.getRequestUri().toString());
-                }
+            logger.log(logger.isTraceEnabled() ? Logger.Level.TRACE : level, sb.toString());
+        }
+    }
 
-                if (headers != null) {
-                    sb.append(", cookies=[");
-                    boolean f = true;
-                    for (Map.Entry<String, Cookie> e : headers.getCookies().entrySet()) {
-                        if (f) {
-                            f = false;
-                        } else {
-                            sb.append(", ");
-                        }
-                        sb.append(e.getValue().toString());
-                    }
-                    sb.append("]");
-                }
+    @Override
+    public void onEvent(AdminEvent adminEvent, boolean includeRepresentation) {
+        Logger.Level level = adminEvent.getError() != null ? errorLevel : successLevel;
+
+        if (logger.isEnabled(level)) {
+            StringBuilder sb = new StringBuilder();
+
+            sb.append("operationType=");
+            sb.append(adminEvent.getOperationType());
+            sb.append(", realmId=");
+            sb.append(adminEvent.getAuthDetails().getRealmId());
+            sb.append(", clientId=");
+            sb.append(adminEvent.getAuthDetails().getClientId());
+            sb.append(", userId=");
+            sb.append(adminEvent.getAuthDetails().getUserId());
+            sb.append(", ipAddress=");
+            sb.append(adminEvent.getAuthDetails().getIpAddress());
+            sb.append(", resourcePath=");
+            sb.append(adminEvent.getResourcePath());
+
+            if (adminEvent.getError() != null) {
+                sb.append(", error=");
+                sb.append(adminEvent.getError());
+            }
+            
+            if(logger.isTraceEnabled()) {
+                setKeycloakContext(sb);
             }
 
             logger.log(logger.isTraceEnabled() ? Logger.Level.TRACE : level, sb.toString());
@@ -98,5 +112,30 @@ public class JBossLoggingEventListenerProvider implements EventListenerProvider 
     @Override
     public void close() {
     }
+    
+    private void setKeycloakContext(StringBuilder sb) {
+        KeycloakContext context = session.getContext();
+        UriInfo uriInfo = context.getUri();
+        HttpHeaders headers = context.getRequestHeaders();
+        if (uriInfo != null) {
+            sb.append(", requestUri=");
+            sb.append(uriInfo.getRequestUri().toString());
+        }
+
+        if (headers != null) {
+            sb.append(", cookies=[");
+            boolean f = true;
+            for (Map.Entry<String, Cookie> e : headers.getCookies().entrySet()) {
+                if (f) {
+                    f = false;
+                } else {
+                    sb.append(", ");
+                }
+                sb.append(e.getValue().toString());
+            }
+            sb.append("]");
+        }
+        
+    }
 
 }
diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java b/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java
new file mode 100644
index 0000000..b814c5a
--- /dev/null
+++ b/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java
@@ -0,0 +1,137 @@
+package org.keycloak.events.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
+ */
+@Entity
+@Table(name="ADMIN_EVENT_ENTITY")
+public class AdminEventEntity {
+    
+    @Id
+    @Column(name="ID", length = 36)
+    private String id;
+    
+    @Column(name="ADMIN_EVENT_TIME")
+    private long time;
+    
+    @Column(name="REALM_ID")
+    private String realmId;
+    
+    @Column(name="OPERATION_TYPE")
+    private String operationType;
+    
+    @Column(name="AUTH_REALM_ID")
+    private String authRealmId;
+    
+    @Column(name="AUTH_CLIENT_ID")
+    private String authClientId;
+
+    @Column(name="AUTH_USER_ID")
+    private String authUserId;
+    
+    @Column(name="IP_ADDRESS")
+    private String authIpAddress;
+    
+    @Column(name="RESOURCE_PATH")
+    private String resourcePath;
+
+    @Column(name="REPRESENTATION", length = 25500)
+    private String representation;
+
+    @Column(name="ERROR")
+    private String error;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public long getTime() {
+        return time;
+    }
+
+    public void setTime(long time) {
+        this.time = time;
+    }
+
+    public String getRealmId() {
+        return realmId;
+    }
+
+    public void setRealmId(String realmId) {
+        this.realmId = realmId;
+    }
+
+    public String getOperationType() {
+        return operationType;
+    }
+
+    public void setOperationType(String operationType) {
+        this.operationType = operationType;
+    }
+
+    public String getAuthRealmId() {
+        return authRealmId;
+    }
+
+    public void setAuthRealmId(String authRealmId) {
+        this.authRealmId = authRealmId;
+    }
+
+    public String getAuthClientId() {
+        return authClientId;
+    }
+
+    public void setAuthClientId(String authClientId) {
+        this.authClientId = authClientId;
+    }
+
+    public String getAuthUserId() {
+        return authUserId;
+    }
+
+    public void setAuthUserId(String authUserId) {
+        this.authUserId = authUserId;
+    }
+
+    public String getAuthIpAddress() {
+        return authIpAddress;
+    }
+
+    public void setAuthIpAddress(String authIpAddress) {
+        this.authIpAddress = authIpAddress;
+    }
+
+    public String getResourcePath() {
+        return resourcePath;
+    }
+
+    public void setResourcePath(String resourcePath) {
+        this.resourcePath = resourcePath;
+    }
+
+    public String getRepresentation() {
+        return representation;
+    }
+
+    public void setRepresentation(String representation) {
+        this.representation = representation;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+}
diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java
new file mode 100644
index 0000000..f9ea14d
--- /dev/null
+++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java
@@ -0,0 +1,154 @@
+package org.keycloak.events.jpa;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.OperationType;
+
+/**
+ * @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
+ */
+public class JpaAdminEventQuery implements AdminEventQuery {
+    
+    private final EntityManager em;
+    private final CriteriaBuilder cb;
+    private final CriteriaQuery<AdminEventEntity> cq;
+    private final Root<AdminEventEntity> root;
+    private final ArrayList<Predicate> predicates;
+    private Integer firstResult;
+    private Integer maxResults;
+    
+    public JpaAdminEventQuery(EntityManager em) {
+        this.em = em;
+
+        cb = em.getCriteriaBuilder();
+        cq = cb.createQuery(AdminEventEntity.class);
+        root = cq.from(AdminEventEntity.class);
+        predicates = new ArrayList<Predicate>();
+    }
+    
+    @Override
+    public AdminEventQuery realm(String realmId) {
+        predicates.add(cb.equal(root.get("realmId"), realmId));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery operation(OperationType... operations) {
+        List<String> operationStrings = new LinkedList<String>();
+        for (OperationType e : operations) {
+            operationStrings.add(e.toString());
+        }
+        predicates.add(root.get("operationType").in(operationStrings));
+        return this;
+    }
+    
+    @Override
+    public AdminEventQuery authRealm(String authRealmId) {
+        predicates.add(cb.equal(root.get("authRealmId"), authRealmId));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authClient(String authClientId) {
+        predicates.add(cb.equal(root.get("authClientId"), authClientId));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authUser(String authUserId) {
+        predicates.add(cb.equal(root.get("authUserId"), authUserId));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authIpAddress(String ipAddress) {
+        predicates.add(cb.equal(root.get("authIpAddress"), ipAddress));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery resourcePath(String resourcePath) {
+        Expression<String> rPath = root.get("resourcePath");
+        predicates.add(cb.like(rPath, "%"+resourcePath+"%"));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery fromTime(String fromTime) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Long from = null;
+        try {
+            from = df.parse(fromTime).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        predicates.add(cb.greaterThanOrEqualTo(root.<Long>get("time"), from));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery toTime(String toTime) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Long to = null;
+        try {
+            to = df.parse(toTime).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        predicates.add(cb.lessThanOrEqualTo(root.<Long>get("time"), to));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery firstResult(int firstResult) {
+        this.firstResult = firstResult;
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery maxResults(int maxResults) {
+        this.maxResults = maxResults;
+        return this;
+    }
+
+    @Override
+    public List<AdminEvent> getResultList() {
+        if (!predicates.isEmpty()) {
+            cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
+        }
+
+        cq.orderBy(cb.desc(root.get("time")));
+
+        TypedQuery<AdminEventEntity> query = em.createQuery(cq);
+
+        if (firstResult != null) {
+            query.setFirstResult(firstResult);
+        }
+
+        if (maxResults != null) {
+            query.setMaxResults(maxResults);
+        }
+
+        List<AdminEvent> events = new LinkedList<AdminEvent>();
+        for (AdminEventEntity e : query.getResultList()) {
+            events.add(JpaEventStoreProvider.convertAdminEvent(e));
+        }
+
+        return events;
+    }
+    
+}
diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java
index 5e39d17..ffbf619 100644
--- a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java
+++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java
@@ -131,7 +131,7 @@ public class JpaEventQuery implements EventQuery {
 
         List<Event> events = new LinkedList<Event>();
         for (EventEntity e : query.getResultList()) {
-            events.add(JpaEventStoreProvider.convert(e));
+            events.add(JpaEventStoreProvider.convertEvent(e));
         }
 
         return events;
diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java
index 8fca6ec..d3ff4f8 100755
--- a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java
+++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java
@@ -3,12 +3,17 @@ package org.keycloak.events.jpa;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.type.TypeReference;
 import org.jboss.logging.Logger;
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.AuthDetails;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventQuery;
 import org.keycloak.events.EventStoreProvider;
 import org.keycloak.events.EventType;
 
 import javax.persistence.EntityManager;
+
 import java.io.IOException;
 import java.util.Map;
 import java.util.UUID;
@@ -51,49 +56,121 @@ public class JpaEventStoreProvider implements EventStoreProvider {
 
     @Override
     public void onEvent(Event event) {
-        em.persist(convert(event));
+        em.persist(convertEvent(event));
+    }
+
+    @Override
+    public AdminEventQuery createAdminQuery() {
+        return new JpaAdminEventQuery(em);
+    }
+
+    @Override
+    public void clearAdmin() {
+        em.createQuery("delete from AdminEventEntity").executeUpdate();
+    }
+
+    @Override
+    public void clearAdmin(String realmId) {
+        em.createQuery("delete from AdminEventEntity where realmId = :realmId").setParameter("realmId", realmId).executeUpdate();
+    }
+
+    @Override
+    public void clearAdmin(String realmId, long olderThan) {
+        em.createQuery("delete from AdminEventEntity where realmId = :realmId and time < :time").setParameter("realmId", realmId).setParameter("time", olderThan).executeUpdate();
+    }
+
+    @Override
+    public void onEvent(AdminEvent event, boolean includeRepresentation) {
+        em.persist(convertAdminEvent(event, includeRepresentation));
     }
 
     @Override
     public void close() {
     }
 
-    static EventEntity convert(Event o) {
-        EventEntity e = new EventEntity();
-        e.setId(UUID.randomUUID().toString());
-        e.setTime(o.getTime());
-        e.setType(o.getType().toString());
-        e.setRealmId(o.getRealmId());
-        e.setClientId(o.getClientId());
-        e.setUserId(o.getUserId());
-        e.setSessionId(o.getSessionId());
-        e.setIpAddress(o.getIpAddress());
-        e.setError(o.getError());
+    static EventEntity convertEvent(Event event) {
+        EventEntity eventEntity = new EventEntity();
+        eventEntity.setId(UUID.randomUUID().toString());
+        eventEntity.setTime(event.getTime());
+        eventEntity.setType(event.getType().toString());
+        eventEntity.setRealmId(event.getRealmId());
+        eventEntity.setClientId(event.getClientId());
+        eventEntity.setUserId(event.getUserId());
+        eventEntity.setSessionId(event.getSessionId());
+        eventEntity.setIpAddress(event.getIpAddress());
+        eventEntity.setError(event.getError());
         try {
-            e.setDetailsJson(mapper.writeValueAsString(o.getDetails()));
+            eventEntity.setDetailsJson(mapper.writeValueAsString(event.getDetails()));
         } catch (IOException ex) {
             logger.error("Failed to write log details", ex);
         }
-        return e;
-    }
-
-    static Event convert(EventEntity o) {
-        Event e = new Event();
-        e.setTime(o.getTime());
-        e.setType(EventType.valueOf(o.getType()));
-        e.setRealmId(o.getRealmId());
-        e.setClientId(o.getClientId());
-        e.setUserId(o.getUserId());
-        e.setSessionId(o.getSessionId());
-        e.setIpAddress(o.getIpAddress());
-        e.setError(o.getError());
+        return eventEntity;
+    }
+
+    static Event convertEvent(EventEntity eventEntity) {
+        Event event = new Event();
+        event.setTime(eventEntity.getTime());
+        event.setType(EventType.valueOf(eventEntity.getType()));
+        event.setRealmId(eventEntity.getRealmId());
+        event.setClientId(eventEntity.getClientId());
+        event.setUserId(eventEntity.getUserId());
+        event.setSessionId(eventEntity.getSessionId());
+        event.setIpAddress(eventEntity.getIpAddress());
+        event.setError(eventEntity.getError());
         try {
-            Map<String, String> details = mapper.readValue(o.getDetailsJson(), mapType);
-            e.setDetails(details);
+            Map<String, String> details = mapper.readValue(eventEntity.getDetailsJson(), mapType);
+            event.setDetails(details);
         } catch (IOException ex) {
             logger.error("Failed to read log details", ex);
         }
-        return e;
+        return event;
+    }
+    
+    static AdminEventEntity convertAdminEvent(AdminEvent adminEvent, boolean includeRepresentation) {
+        AdminEventEntity adminEventEntity = new AdminEventEntity();
+        adminEventEntity.setId(UUID.randomUUID().toString());
+        adminEventEntity.setTime(adminEvent.getTime());
+        adminEventEntity.setRealmId(adminEvent.getRealmId());
+        setAuthDetails(adminEventEntity, adminEvent.getAuthDetails());
+        adminEventEntity.setOperationType(adminEvent.getOperationType().toString());
+        adminEventEntity.setResourcePath(adminEvent.getResourcePath());
+        adminEventEntity.setError(adminEvent.getError());
+        
+        if(includeRepresentation) {
+            adminEventEntity.setRepresentation(adminEvent.getRepresentation());
+        }
+        return adminEventEntity;
+    }
+
+    static AdminEvent convertAdminEvent(AdminEventEntity adminEventEntity) {
+        AdminEvent adminEvent = new AdminEvent();
+        adminEvent.setTime(adminEventEntity.getTime());
+        adminEvent.setRealmId(adminEventEntity.getRealmId());
+        setAuthDetails(adminEvent, adminEventEntity);
+        adminEvent.setOperationType(OperationType.valueOf(adminEventEntity.getOperationType()));
+        adminEvent.setResourcePath(adminEventEntity.getResourcePath());
+        adminEvent.setError(adminEventEntity.getError());
+        
+        if(adminEventEntity.getRepresentation() != null) {
+            adminEvent.setRepresentation(adminEventEntity.getRepresentation());
+        }
+        return adminEvent;
+    }
+    
+    private static void setAuthDetails(AdminEventEntity adminEventEntity, AuthDetails authDetails) {
+        adminEventEntity.setAuthRealmId(authDetails.getRealmId());
+        adminEventEntity.setAuthClientId(authDetails.getClientId());
+        adminEventEntity.setAuthUserId(authDetails.getUserId());
+        adminEventEntity.setAuthIpAddress(authDetails.getIpAddress());
+    }
+    
+    private static void setAuthDetails(AdminEvent adminEvent, AdminEventEntity adminEventEntity) {
+        AuthDetails authDetails = new AuthDetails();
+        authDetails.setRealmId(adminEventEntity.getAuthRealmId());
+        authDetails.setClientId(adminEventEntity.getAuthClientId());
+        authDetails.setUserId(adminEventEntity.getAuthUserId());
+        authDetails.setIpAddress(adminEventEntity.getAuthIpAddress());
+        adminEvent.setAuthDetails(authDetails);
     }
 
 }
diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java
new file mode 100644
index 0000000..c614d76
--- /dev/null
+++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java
@@ -0,0 +1,132 @@
+package org.keycloak.events.mongo;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.OperationType;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+
+public class MongoAdminEventQuery implements AdminEventQuery{
+    
+    private Integer firstResult;
+    private Integer maxResults;
+    private DBCollection audit;
+    private final BasicDBObject query;
+
+    public MongoAdminEventQuery(DBCollection audit) {
+        this.audit = audit;
+        query = new BasicDBObject();
+    }
+    
+    @Override
+    public AdminEventQuery realm(String realmId) {
+        query.put("realmId", realmId);
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery operation(OperationType... operations) {
+        List<String> operationStrings = new LinkedList<String>();
+        for (OperationType e : operations) {
+            operationStrings.add(e.toString());
+        }
+        query.put("operationType", new BasicDBObject("$in", operationStrings));
+        return this;
+    }
+    
+    @Override
+    public AdminEventQuery authRealm(String authRealmId) {
+        query.put("authRealmId", authRealmId);
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authClient(String authClientId) {
+        query.put("authClientId", authClientId);
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authUser(String authUserId) {
+        query.put("authUserId", authUserId);
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authIpAddress(String ipAddress) {
+        query.put("authIpAddress", ipAddress);
+        return this;
+    }
+    
+    @Override
+    public AdminEventQuery resourcePath(String resourcePath) {
+        query.put("resourcePath", Pattern.compile(resourcePath));
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery fromTime(String fromTime) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Long from = null;
+        try {
+            from = df.parse(fromTime).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        query.put("time", BasicDBObjectBuilder.start("$gte", from).get());
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery toTime(String toTime) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Long to = null;
+        try {
+            to = df.parse(toTime).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        query.put("time", BasicDBObjectBuilder.start("$lte", to).get());
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery firstResult(int firstResult) {
+        this.firstResult = firstResult;
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery maxResults(int maxResults) {
+        this.maxResults = maxResults;
+        return this;
+    }
+
+    @Override
+    public List<AdminEvent> getResultList() {
+        DBCursor cur = audit.find(query).sort(new BasicDBObject("time", -1));
+        if (firstResult != null) {
+            cur.skip(firstResult);
+        }
+        if (maxResults != null) {
+            cur.limit(maxResults);
+        }
+
+        List<AdminEvent> events = new LinkedList<AdminEvent>();
+        while (cur.hasNext()) {
+            events.add(MongoEventStoreProvider.convertAdminEvent((BasicDBObject) cur.next()));
+        }
+
+        return events;
+    }
+
+}
diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java
index c2569cc..75165c7 100755
--- a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java
+++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java
@@ -118,7 +118,7 @@ public class MongoEventQuery implements EventQuery {
 
         List<Event> events = new LinkedList<Event>();
         while (cur.hasNext()) {
-            events.add(MongoEventStoreProvider.convert((BasicDBObject) cur.next()));
+            events.add(MongoEventStoreProvider.convertEvent((BasicDBObject) cur.next()));
         }
 
         return events;
diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java
index 65b6573..27e1ea5 100755
--- a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java
+++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java
@@ -3,6 +3,11 @@ package org.keycloak.events.mongo;
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCollection;
 import com.mongodb.DBObject;
+
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.AuthDetails;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventQuery;
 import org.keycloak.events.EventStoreProvider;
@@ -15,11 +20,13 @@ import java.util.Map;
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class MongoEventStoreProvider implements EventStoreProvider {
-
+    
     private DBCollection events;
+    private DBCollection adminEvents;
 
-    public MongoEventStoreProvider(DBCollection events) {
+    public MongoEventStoreProvider(DBCollection events, DBCollection adminEvents) {
         this.events = events;
+        this.adminEvents = adminEvents;
     }
 
     @Override
@@ -47,27 +54,55 @@ public class MongoEventStoreProvider implements EventStoreProvider {
 
     @Override
     public void onEvent(Event event) {
-        events.insert(convert(event));
+        events.insert(convertEvent(event));
+    }
+
+    @Override
+    public AdminEventQuery createAdminQuery() {
+        return new MongoAdminEventQuery(adminEvents);
+    }
+
+    @Override
+    public void clearAdmin() {
+        adminEvents.remove(new BasicDBObject());
+    }
+
+    @Override
+    public void clearAdmin(String realmId) {
+        adminEvents.remove(new BasicDBObject("realmId", realmId));
+    }
+
+    @Override
+    public void clearAdmin(String realmId, long olderThan) {
+        BasicDBObject q = new BasicDBObject();
+        q.put("realmId", realmId);
+        q.put("time", new BasicDBObject("$lt", olderThan));
+        adminEvents.remove(q);
+    }
+
+    @Override
+    public void onEvent(AdminEvent adminEvent, boolean includeRepresentation) {
+        adminEvents.insert(convertAdminEvent(adminEvent, includeRepresentation));
     }
 
     @Override
     public void close() {
     }
 
-    static DBObject convert(Event o) {
+    static DBObject convertEvent(Event event) {
         BasicDBObject e = new BasicDBObject();
-        e.put("time", o.getTime());
-        e.put("type", o.getType().toString());
-        e.put("realmId", o.getRealmId());
-        e.put("clientId", o.getClientId());
-        e.put("userId", o.getUserId());
-        e.put("sessionId", o.getSessionId());
-        e.put("ipAddress", o.getIpAddress());
-        e.put("error", o.getError());
+        e.put("time", event.getTime());
+        e.put("type", event.getType().toString());
+        e.put("realmId", event.getRealmId());
+        e.put("clientId", event.getClientId());
+        e.put("userId", event.getUserId());
+        e.put("sessionId", event.getSessionId());
+        e.put("ipAddress", event.getIpAddress());
+        e.put("error", event.getError());
 
         BasicDBObject details = new BasicDBObject();
-        if (o.getDetails() != null) {
-            for (Map.Entry<String, String> entry : o.getDetails().entrySet()) {
+        if (event.getDetails() != null) {
+            for (Map.Entry<String, String> entry : event.getDetails().entrySet()) {
                 details.put(entry.getKey(), entry.getValue());
             }
         }
@@ -76,16 +111,16 @@ public class MongoEventStoreProvider implements EventStoreProvider {
         return e;
     }
 
-    static Event convert(BasicDBObject o) {
-        Event e = new Event();
-        e.setTime(o.getLong("time"));
-        e.setType(EventType.valueOf(o.getString("type")));
-        e.setRealmId(o.getString("realmId"));
-        e.setClientId(o.getString("clientId"));
-        e.setUserId(o.getString("userId"));
-        e.setSessionId(o.getString("sessionId"));
-        e.setIpAddress(o.getString("ipAddress"));
-        e.setError(o.getString("error"));
+    static Event convertEvent(BasicDBObject o) {
+        Event event = new Event();
+        event.setTime(o.getLong("time"));
+        event.setType(EventType.valueOf(o.getString("type")));
+        event.setRealmId(o.getString("realmId"));
+        event.setClientId(o.getString("clientId"));
+        event.setUserId(o.getString("userId"));
+        event.setSessionId(o.getString("sessionId"));
+        event.setIpAddress(o.getString("ipAddress"));
+        event.setError(o.getString("error"));
 
         BasicDBObject d = (BasicDBObject) o.get("details");
         if (d != null) {
@@ -93,10 +128,57 @@ public class MongoEventStoreProvider implements EventStoreProvider {
             for (Object k : d.keySet()) {
                 details.put((String) k, d.getString((String) k));
             }
-            e.setDetails(details);
+            event.setDetails(details);
+        }
+
+        return event;
+    }
+    
+    private static DBObject convertAdminEvent(AdminEvent adminEvent, boolean includeRepresentation) {
+        BasicDBObject e = new BasicDBObject();
+        e.put("time", adminEvent.getTime());
+        e.put("realmId", adminEvent.getRealmId());
+        e.put("operationType", adminEvent.getOperationType().toString());
+        setAuthDetails(e, adminEvent.getAuthDetails());
+        e.put("resourcePath", adminEvent.getResourcePath());
+        e.put("error", adminEvent.getError());
+        
+        if(includeRepresentation) {
+            e.put("representation", adminEvent.getRepresentation());
         }
 
         return e;
     }
+    
+    static AdminEvent convertAdminEvent(BasicDBObject o) {
+        AdminEvent adminEvent = new AdminEvent();
+        adminEvent.setTime(o.getLong("time"));
+        adminEvent.setRealmId(o.getString("realmId"));
+        adminEvent.setOperationType(OperationType.valueOf(o.getString("operationType")));
+        setAuthDetails(adminEvent, o);
+        adminEvent.setResourcePath(o.getString("resourcePath"));
+        adminEvent.setError(o.getString("error"));
+        
+        if(o.getString("representation") != null) {
+            adminEvent.setRepresentation(o.getString("representation"));
+        }
+        return adminEvent;
+    }
+
+    private static void setAuthDetails(BasicDBObject e, AuthDetails authDetails) {
+        e.put("authRealmId", authDetails.getRealmId());
+        e.put("authClientId", authDetails.getClientId());
+        e.put("authUserId", authDetails.getUserId());
+        e.put("authIpAddress", authDetails.getIpAddress());
+    }
+    
+    private static void setAuthDetails(AdminEvent adminEvent, BasicDBObject o) {
+        AuthDetails authDetails = new AuthDetails();
+        authDetails.setRealmId(o.getString("authRealmId"));
+        authDetails.setClientId(o.getString("authClientId"));
+        authDetails.setUserId(o.getString("authUserId"));
+        authDetails.setIpAddress(o.getString("authIpAddress"));
+        adminEvent.setAuthDetails(authDetails);
+    }
 
 }
diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java
index db4adeb..cbf41ac 100755
--- a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java
+++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java
@@ -24,9 +24,12 @@ public class MongoEventStoreProviderFactory implements EventStoreProviderFactory
         MongoConnectionProvider connection = session.getProvider(MongoConnectionProvider.class);
 
         DBCollection collection = connection.getDB().getCollection("events");
+        DBCollection adminCollection = connection.getDB().getCollection("adminEvents");
+        
         collection.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
+        adminCollection.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
 
-        return new MongoEventStoreProvider(collection);
+        return new MongoEventStoreProvider(collection, adminCollection);
     }
 
     @Override
diff --git a/events/syslog/src/main/java/org/keycloak/events/log/SysLoggingEventListenerProvider.java b/events/syslog/src/main/java/org/keycloak/events/log/SysLoggingEventListenerProvider.java
index 0536286..14188a8 100755
--- a/events/syslog/src/main/java/org/keycloak/events/log/SysLoggingEventListenerProvider.java
+++ b/events/syslog/src/main/java/org/keycloak/events/log/SysLoggingEventListenerProvider.java
@@ -1,5 +1,6 @@
 package org.keycloak.events.log;
 
+import org.keycloak.events.admin.AdminEvent;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventListenerProvider;
 import org.productivity.java.syslog4j.SyslogConstants;
@@ -59,6 +60,33 @@ public class SysLoggingEventListenerProvider implements EventListenerProvider {
     }
 
     @Override
+    public void onEvent(AdminEvent adminEvent, boolean includeRepresentation) {
+        int level = adminEvent.getError() != null ? SyslogConstants.LEVEL_ERROR : SyslogConstants.LEVEL_INFO;
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("operationType=");
+        sb.append(adminEvent.getOperationType());
+        sb.append(", realmId=");
+        sb.append(adminEvent.getAuthDetails().getRealmId());
+        sb.append(", clientId=");
+        sb.append(adminEvent.getAuthDetails().getClientId());
+        sb.append(", userId=");
+        sb.append(adminEvent.getAuthDetails().getUserId());
+        sb.append(", ipAddress=");
+        sb.append(adminEvent.getAuthDetails().getIpAddress());
+        sb.append(", resourcePath=");
+        sb.append(adminEvent.getResourcePath());
+
+        if (adminEvent.getError() != null) {
+            sb.append(", error=");
+            sb.append(adminEvent.getError());
+        }
+
+        syslogger.log(level, sb.toString());
+    }
+
+    @Override
     public void close() {
     }
 
diff --git a/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
index 97c5645..9c1bac9 100755
--- a/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
+++ b/examples/demo-template/admin-access-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -3,7 +3,7 @@
         <dependencies>
             <!-- the Demo code uses classes in these modules.  These are optional to import if you are not using
                  Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
-            <module name="org.apache.httpcomponents" slot="4.3"/>
+            <module name="org.apache.httpcomponents"/>
         </dependencies>
     </deployment>
 </jboss-deployment-structure>
\ No newline at end of file
diff --git a/examples/demo-template/customer-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/demo-template/customer-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
index 97c5645..9c1bac9 100755
--- a/examples/demo-template/customer-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
+++ b/examples/demo-template/customer-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -3,7 +3,7 @@
         <dependencies>
             <!-- the Demo code uses classes in these modules.  These are optional to import if you are not using
                  Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
-            <module name="org.apache.httpcomponents" slot="4.3"/>
+            <module name="org.apache.httpcomponents"/>
         </dependencies>
     </deployment>
 </jboss-deployment-structure>
\ No newline at end of file
diff --git a/examples/demo-template/pom.xml b/examples/demo-template/pom.xml
index 2e10aa1..eb179f0 100755
--- a/examples/demo-template/pom.xml
+++ b/examples/demo-template/pom.xml
@@ -37,4 +37,25 @@
         <module>third-party</module>
         <module>third-party-cdi</module>
     </modules>
+
+    <profiles>
+        <profile>
+            <id>no-keycloak-json</id>
+            <activation>
+                <property>
+                    <name>no-keycloak-json</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-war-plugin</artifactId>
+                        <configuration>
+                            <packagingExcludes>**/keycloak.json</packagingExcludes>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/examples/demo-template/product-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/demo-template/product-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
index 97c5645..9c1bac9 100755
--- a/examples/demo-template/product-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
+++ b/examples/demo-template/product-app/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -3,7 +3,7 @@
         <dependencies>
             <!-- the Demo code uses classes in these modules.  These are optional to import if you are not using
                  Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
-            <module name="org.apache.httpcomponents" slot="4.3"/>
+            <module name="org.apache.httpcomponents"/>
         </dependencies>
     </deployment>
 </jboss-deployment-structure>
\ No newline at end of file
diff --git a/examples/demo-template/third-party/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/demo-template/third-party/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
index 97c5645..9c1bac9 100755
--- a/examples/demo-template/third-party/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
+++ b/examples/demo-template/third-party/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -3,7 +3,7 @@
         <dependencies>
             <!-- the Demo code uses classes in these modules.  These are optional to import if you are not using
                  Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
-            <module name="org.apache.httpcomponents" slot="4.3"/>
+            <module name="org.apache.httpcomponents"/>
         </dependencies>
     </deployment>
 </jboss-deployment-structure>
\ No newline at end of file
diff --git a/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
index 97c5645..9c1bac9 100755
--- a/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
+++ b/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -3,7 +3,7 @@
         <dependencies>
             <!-- the Demo code uses classes in these modules.  These are optional to import if you are not using
                  Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
-            <module name="org.apache.httpcomponents" slot="4.3"/>
+            <module name="org.apache.httpcomponents"/>
         </dependencies>
     </deployment>
 </jboss-deployment-structure>
\ No newline at end of file
diff --git a/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java
index 8bd001f..d81288e 100755
--- a/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java
+++ b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java
@@ -1,5 +1,7 @@
 package org.keycloak.examples.providers.events;
 
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventListenerProvider;
 import org.keycloak.events.EventType;
@@ -13,9 +15,11 @@ import java.util.Set;
 public class SysoutEventListenerProvider implements EventListenerProvider {
 
     private Set<EventType> excludedEvents;
+    private Set<OperationType> excludedAdminOperations;
 
-    public SysoutEventListenerProvider(Set<EventType> excludedEvents) {
+    public SysoutEventListenerProvider(Set<EventType> excludedEvents, Set<OperationType> excludedAdminOpearations) {
         this.excludedEvents = excludedEvents;
+        this.excludedAdminOperations = excludedAdminOpearations;
     }
 
     @Override
@@ -28,6 +32,16 @@ public class SysoutEventListenerProvider implements EventListenerProvider {
         }
     }
 
+    @Override
+    public void onEvent(AdminEvent event, boolean includeRepresentation) {
+        // Ignore excluded operations
+        if (excludedAdminOperations != null && excludedAdminOperations.contains(event.getOperationType())) {
+            return;
+        } else {
+            System.out.println("EVENT: " + toString(event));
+        }
+    }
+
     private String toString(Event event) {
         StringBuilder sb = new StringBuilder();
 
@@ -64,7 +78,31 @@ public class SysoutEventListenerProvider implements EventListenerProvider {
 
         return sb.toString();
     }
+    
+    private String toString(AdminEvent adminEvent) {
+        StringBuilder sb = new StringBuilder();
 
+        sb.append("operationType=");
+        sb.append(adminEvent.getOperationType());
+        sb.append(", realmId=");
+        sb.append(adminEvent.getAuthDetails().getRealmId());
+        sb.append(", clientId=");
+        sb.append(adminEvent.getAuthDetails().getClientId());
+        sb.append(", userId=");
+        sb.append(adminEvent.getAuthDetails().getUserId());
+        sb.append(", ipAddress=");
+        sb.append(adminEvent.getAuthDetails().getIpAddress());
+        sb.append(", resourcePath=");
+        sb.append(adminEvent.getResourcePath());
+
+        if (adminEvent.getError() != null) {
+            sb.append(", error=");
+            sb.append(adminEvent.getError());
+        }
+        
+        return sb.toString();
+    }
+    
     @Override
     public void close() {
     }
diff --git a/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java
index 3f87d81..e7eb8d5 100755
--- a/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java
+++ b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java
@@ -4,6 +4,7 @@ import org.keycloak.Config;
 import org.keycloak.events.EventListenerProvider;
 import org.keycloak.events.EventListenerProviderFactory;
 import org.keycloak.events.EventType;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 
@@ -16,10 +17,11 @@ import java.util.Set;
 public class SysoutEventListenerProviderFactory implements EventListenerProviderFactory {
 
     private Set<EventType> excludedEvents;
+    private Set<OperationType> excludedAdminOperations;
 
     @Override
     public EventListenerProvider create(KeycloakSession session) {
-        return new SysoutEventListenerProvider(excludedEvents);
+        return new SysoutEventListenerProvider(excludedEvents, excludedAdminOperations);
     }
 
     @Override
@@ -31,6 +33,14 @@ public class SysoutEventListenerProviderFactory implements EventListenerProvider
                 excludedEvents.add(EventType.valueOf(e));
             }
         }
+        
+        String[] excludesOperations = config.getArray("excludesOperations");
+        if (excludesOperations != null) {
+            excludedAdminOperations = new HashSet<>();
+            for (String e : excludesOperations) {
+                excludedAdminOperations.add(OperationType.valueOf(e));
+            }
+        }
     }
 
     @Override
diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java
new file mode 100644
index 0000000..6b3a5da
--- /dev/null
+++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java
@@ -0,0 +1,174 @@
+package org.keycloak.examples.providers.events;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.OperationType;
+
+/**
+ * @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
+ */
+public class MemAdminEventQuery implements AdminEventQuery {
+    
+    private List<AdminEvent> adminEvents;
+
+    private int first;
+    private int max;
+
+    public MemAdminEventQuery(List<AdminEvent> events) {
+        this.adminEvents = events;
+    }
+
+
+    @Override
+    public AdminEventQuery realm(String realmId) {
+        Iterator<AdminEvent> itr = adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!itr.next().getRealmId().equals(realmId)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery operation(OperationType... operations) {
+        Iterator<AdminEvent> itr = this.adminEvents.iterator();
+        while (itr.hasNext()) {
+            AdminEvent next = itr.next();
+            boolean include = false;
+            for (OperationType e : operations) {
+                if (next.getOperationType().equals(e)) {
+                    include = true;
+                    break;
+                }
+            }
+            if (!include) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+    
+    @Override
+    public AdminEventQuery authRealm(String authRealmId) {
+        Iterator<AdminEvent> itr = adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!itr.next().getAuthDetails().getRealmId().equals(authRealmId)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authClient(String authClientId) {
+        Iterator<AdminEvent> itr = adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!itr.next().getAuthDetails().getClientId().equals(authClientId)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authUser(String authUserId) {
+        Iterator<AdminEvent> itr = adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!itr.next().getAuthDetails().getUserId().equals(authUserId)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery authIpAddress(String ipAddress) {
+        Iterator<AdminEvent> itr = adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!itr.next().getAuthDetails().getIpAddress().equals(ipAddress)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery resourcePath(String resourcePath) {
+        Iterator<AdminEvent> itr = this.adminEvents.iterator();
+        while (itr.hasNext()) {
+            if(!Pattern.compile(resourcePath).matcher(itr.next().getResourcePath()).find()) {
+                itr.remove();
+            }
+        }
+        return (AdminEventQuery) this;
+    }
+
+    @Override
+    public AdminEventQuery fromTime(String fromTime) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Long from = null;
+        try {
+            from = df.parse(fromTime).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        
+        Iterator<AdminEvent> itr = this.adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!(itr.next().getTime() >= from)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery toTime(String toTime) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+        Long to = null;
+        try {
+            to = df.parse(toTime).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        
+        Iterator<AdminEvent> itr = this.adminEvents.iterator();
+        while (itr.hasNext()) {
+            if (!(itr.next().getTime() <= to)) {
+                itr.remove();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery firstResult(int result) {
+        this.first = result;
+        return this;
+    }
+
+    @Override
+    public AdminEventQuery maxResults(int results) {
+        this.max = results;
+        return this;
+    }
+
+    @Override
+    public List<AdminEvent> getResultList() {
+        if (adminEvents.size() < first) {
+            return Collections.emptyList();
+        }
+        int end = first + max <= adminEvents.size() ? first + max : adminEvents.size();
+
+        return adminEvents.subList(first, end);
+    }
+        
+}
diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java
index 592455c..e0b2d4c 100755
--- a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java
+++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java
@@ -1,5 +1,8 @@
 package org.keycloak.examples.providers.events;
 
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventQuery;
 import org.keycloak.events.EventStoreProvider;
@@ -16,10 +19,16 @@ import java.util.Set;
 public class MemEventStoreProvider implements EventStoreProvider {
     private final List<Event> events;
     private final Set<EventType> excludedEvents;
+    private final List<AdminEvent> adminEvents;
+    private final Set<OperationType> excludedOperations;
 
-    public MemEventStoreProvider(List<Event> events, Set<EventType> excludedEvents) {
+    public MemEventStoreProvider(List<Event> events, Set<EventType> excludedEvents, 
+            List<AdminEvent> adminEvents, Set<OperationType> excludedOperations) {
         this.events = events;
         this.excludedEvents = excludedEvents;
+        
+        this.adminEvents = adminEvents;
+        this.excludedOperations = excludedOperations;
     }
 
     @Override
@@ -65,6 +74,48 @@ public class MemEventStoreProvider implements EventStoreProvider {
     }
 
     @Override
+    public AdminEventQuery createAdminQuery() {
+        return new MemAdminEventQuery(new LinkedList<>(adminEvents));
+    }
+
+    @Override
+    public void clearAdmin() {
+
+    }
+
+    @Override
+    public void clearAdmin(String realmId) {
+        synchronized(adminEvents) {
+            Iterator<AdminEvent> itr = adminEvents.iterator();
+            while (itr.hasNext()) {
+                if (itr.next().getRealmId().equals(realmId)) {
+                    itr.remove();
+                }
+            }
+        }
+    }
+
+    @Override
+    public void clearAdmin(String realmId, long olderThan) {
+        synchronized(adminEvents) {
+            Iterator<AdminEvent> itr = adminEvents.iterator();
+            while (itr.hasNext()) {
+                AdminEvent e = itr.next();
+                if (e.getRealmId().equals(realmId) && e.getTime() < olderThan) {
+                    itr.remove();
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onEvent(AdminEvent adminEvent, boolean includeRepresentation) {
+        if (excludedOperations == null || !excludedOperations.contains(adminEvent.getOperationType())) {
+            adminEvents.add(0, adminEvent);
+        }
+    }
+
+    @Override
     public void close() {
     }
 
diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java
index 83fd80e..d09b1a3 100755
--- a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java
+++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java
@@ -5,6 +5,8 @@ import org.keycloak.events.Event;
 import org.keycloak.events.EventStoreProvider;
 import org.keycloak.events.EventStoreProviderFactory;
 import org.keycloak.events.EventType;
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 
@@ -20,12 +22,13 @@ import java.util.Set;
 public class MemEventStoreProviderFactory implements EventStoreProviderFactory {
 
     private List<Event> events;
-
     private Set<EventType> excludedEvents;
+    private List<AdminEvent> adminEvents;
+    private Set<OperationType> excludedOperations;
 
     @Override
     public EventStoreProvider create(KeycloakSession session) {
-        return new MemEventStoreProvider(events, excludedEvents);
+        return new MemEventStoreProvider(events, excludedEvents, adminEvents, excludedOperations);
     }
 
     @Override
@@ -39,6 +42,14 @@ public class MemEventStoreProviderFactory implements EventStoreProviderFactory {
                 excludedEvents.add(EventType.valueOf(e));
             }
         }
+        
+        String excludesOperations = config.get("excludesOperations");
+        if (excludesOperations != null) {
+            excludedOperations = new HashSet<>();
+            for (String e : excludesOperations.split(",")) {
+                excludedOperations.add(OperationType.valueOf(e));
+            }
+        }
     }
 
     @Override
@@ -49,6 +60,8 @@ public class MemEventStoreProviderFactory implements EventStoreProviderFactory {
     public void close() {
         events = null;
         excludedEvents = null;
+        adminEvents = null;
+        excludedOperations = null;
     }
 
     @Override
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
index 6ec2960..208cc6a 100644
--- 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
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class ExportSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "export";
     }
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
index b562f3f..90cb6ac 100644
--- 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
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class ImportSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "import";
     }
diff --git a/forms/account-api/src/main/java/org/keycloak/account/AccountSpi.java b/forms/account-api/src/main/java/org/keycloak/account/AccountSpi.java
index e956b14..2c9843e 100644
--- a/forms/account-api/src/main/java/org/keycloak/account/AccountSpi.java
+++ b/forms/account-api/src/main/java/org/keycloak/account/AccountSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class AccountSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "account";
     }
diff --git a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ThemeSpi.java b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ThemeSpi.java
index c3d738b..94db863 100644
--- a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ThemeSpi.java
+++ b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ThemeSpi.java
@@ -8,6 +8,12 @@ import org.keycloak.provider.Spi;
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class ThemeSpi implements Spi {
+
+    @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
     @Override
     public String getName() {
         return "theme";
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
index 3ee1fbe..56f6008 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
@@ -303,6 +303,18 @@ module.config([ '$routeProvider', function($routeProvider) {
             },
             controller : 'RealmEventsCtrl'
         })
+        .when('/realms/:realm/admin-events', {
+            templateUrl : resourceUrl + '/partials/realm-events-admin.html',
+            resolve : {
+                realm : function(RealmLoader) {
+                    return RealmLoader();
+                },
+                serverInfo : function(ServerInfoLoader) {
+                    return ServerInfoLoader();
+                }
+            },
+            controller : 'RealmAdminEventsCtrl'
+        })
         .when('/realms/:realm/events-settings', {
             templateUrl : resourceUrl + '/partials/realm-events-config.html',
             resolve : {
@@ -1387,7 +1399,6 @@ module.directive('kcReadOnly', function() {
 
             scope.$watch(attrs.kcReadOnly, function(readOnly) {
                 if (readOnly) {
-                    console.debug('readonly');
                     element.find('input').each(disable);
                     element.find('button').each(disable);
                     element.find('select').each(disable);
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
index f8ad7c3..f60e20e 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -122,10 +122,6 @@ module.controller('RealmDropdownCtrl', function($scope, Realm, Current, Auth, $l
     $scope.changeRealm = function(selectedRealm) {
         $location.url("/realms/" + selectedRealm);
     }
-
-    $scope.refresh = function() {
-         Current.refresh();
-    }
 });
 
 module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $http, WhoAmI, $location, Dialog, Notifications, Auth) {
@@ -1180,7 +1176,7 @@ module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, real
     }
 });
 
-module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
+module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, RealmAdminEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
     $scope.realm = realm;
 
     $scope.eventsConfig = eventsConfig;
@@ -1198,7 +1194,7 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
     $scope.eventSelectOptions = {
         'multiple': true,
         'simple_tags': true,
-        'tags': serverInfo.eventTypes
+        'tags': serverInfo.enums['eventType']
     };
 
     var oldCopy = angular.copy($scope.eventsConfig);
@@ -1238,6 +1234,14 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
             });
         });
     };
+    
+    $scope.clearAdminEvents = function() {
+        Dialog.confirmDelete($scope.realm.realm, 'admin-events', function() {
+            RealmAdminEvents.remove({ id : $scope.realm.realm }, function() {
+                Notifications.success("The admin events has been cleared.");
+            });
+        });
+    };
 });
 
 module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, serverInfo) {
@@ -1247,7 +1251,7 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, server
     $scope.eventSelectOptions = {
         'multiple': true,
         'simple_tags': true,
-        'tags': serverInfo.eventTypes
+        'tags': serverInfo.enums['eventType']
     };
 
     $scope.query = {
@@ -1308,6 +1312,105 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, server
     $scope.update();
 });
 
+module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, realm, serverInfo, $modal, $filter) {
+    $scope.realm = realm;
+    $scope.page = 0;
+
+    $scope.query = {
+    	id : realm.realm,
+        max : 5,
+        first : 0
+    }
+
+    $scope.adminEnabledEventOperationsOptions = {
+        'multiple': true,
+        'simple_tags': true,
+        'tags': serverInfo.enums['operationType']
+    };
+    
+    $scope.update = function() {
+    	$scope.query.first = 0;
+        for (var i in $scope.query) {
+            if ($scope.query[i] === '') {
+                delete $scope.query[i];
+           }
+        }
+        $scope.events = RealmAdminEvents.query($scope.query);
+    }
+    
+    $scope.reset = function() {
+    	$scope.query.first = 0;
+    	$scope.query.max = 5;
+    	$scope.query.operationTypes = '';
+    	$scope.query.resourcePath = '';
+    	$scope.query.authRealm = '';
+    	$scope.query.authClient = '';
+    	$scope.query.authUser = '';
+    	$scope.query.authIpAddress = '';
+    	$scope.query.dateFrom = '';
+    	$scope.query.dateTo = '';
+    	
+    	$scope.update();
+    }
+    
+    $scope.queryUpdate = function() {
+        for (var i in $scope.query) {
+            if ($scope.query[i] === '') {
+                delete $scope.query[i];
+           }
+        }
+        $scope.events = RealmAdminEvents.query($scope.query);
+    }
+    
+    $scope.firstPage = function() {
+        $scope.query.first = 0;
+        $scope.queryUpdate();
+    }
+
+    $scope.previousPage = function() {
+        $scope.query.first -= parseInt($scope.query.max);
+        if ($scope.query.first < 0) {
+            $scope.query.first = 0;
+        }
+        $scope.queryUpdate();
+    }
+
+    $scope.nextPage = function() {
+        $scope.query.first += parseInt($scope.query.max);
+        $scope.queryUpdate();
+    }
+
+    $scope.update();
+    
+    $scope.viewRepresentation = function(event) {
+        $modal.open({
+            templateUrl: resourceUrl + '/partials/modal/realm-events-admin-representation.html',
+            controller: 'RealmAdminEventsModalCtrl',
+            resolve: {
+                event: function () {
+                    return event;
+                }
+            }
+        })
+    }
+
+    $scope.viewAuth = function(event) {
+        $modal.open({
+            templateUrl: resourceUrl + '/partials/modal/realm-events-admin-auth.html',
+            controller: 'RealmAdminEventsModalCtrl',
+            resolve: {
+                event: function () {
+                    return event;
+                }
+            }
+        })
+    }
+});
+
+module.controller('RealmAdminEventsModalCtrl', function($scope, $filter, event) {
+    $scope.event = event;
+});
+
 module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, TimeUnit) {
     console.log('RealmBruteForceCtrl');
 
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
index 7708821..e9f09a2 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
@@ -180,6 +180,12 @@ module.factory('RealmEvents', function($resource) {
     });
 });
 
+module.factory('RealmAdminEvents', function($resource) {
+    return $resource(authUrl + '/admin/realms/:id/admin-events', {
+        id : '@realm'
+    });
+});
+
 module.factory('RealmLDAPConnectionTester', function($resource) {
     return $resource(authUrl + '/admin/realms/:realm/testLDAPConnection');
 });
@@ -824,15 +830,13 @@ module.factory('ClientOrigins', function($resource) {
     });
 });
 
-module.factory('Current', function(Realm, $route) {
+module.factory('Current', function(Realm, $route, $rootScope) {
     var current = {};
 
     current.realms = {};
     current.realm = null;
-    current.clients = {};
-    current.client = null;
 
-    current.refresh = function() {
+    $rootScope.$on('$routeChangeStart', function() {
         current.realm = null;
         current.realms = Realm.query(null, function(realms) {
             if ($route.current.params.realm) {
@@ -843,9 +847,7 @@ module.factory('Current', function(Realm, $route) {
                 }
             }
         });
-    }
-
-    current.refresh();
+    });
 
     return current;
 });
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/modal/realm-events-admin-auth.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/modal/realm-events-admin-auth.html
new file mode 100644
index 0000000..8f765f0
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/modal/realm-events-admin-auth.html
@@ -0,0 +1,8 @@
+<div style="padding: 20px 20px 0 20px">
+<table class="table table-striped table-bordered">
+    <tr><td width="100px">Realm</td><td>{{event.authDetails.realmId}}</td></tr>
+    <tr><td width="100px">Client</td><td>{{event.authDetails.clientId}}</td></tr>
+    <tr><td width="100px">User</td><td>{{event.authDetails.userId}}</td></tr>
+    <tr><td width="100px">IP Address</td><td>{{event.authDetails.ipAddress}}</td></tr>
+</table>
+</div>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/modal/realm-events-admin-representation.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/modal/realm-events-admin-representation.html
new file mode 100644
index 0000000..837a164
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/modal/realm-events-admin-representation.html
@@ -0,0 +1,3 @@
+<div style="padding: 20px 20px 10px 20px">
+	<pre ng-bind = "{{event.representation}} | json"></pre>
+</div>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html
index 7c45014..8df1629 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events.html
@@ -5,7 +5,8 @@
     </h1>
 
     <ul class="nav nav-tabs">
-        <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">View</a></li>
+        <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">Login Events</a></li>
+        <li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">Admin Events</a></li>
         <li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
     </ul>
 
@@ -121,4 +122,4 @@
     </table>
 </div>
 
-<kc-menu></kc-menu>
+<kc-menu></kc-menu>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html
new file mode 100755
index 0000000..8469d71
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html
@@ -0,0 +1,127 @@
+<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
+    <h1>
+        <span><strong>Admin Events</strong> {{realm.realm|capitalize}}</span>
+        <kc-tooltip>Displays saved admin events for the realm. Events are related to admin account, for example a realm creation. To enable persisted events go to config.</kc-tooltip>
+    </h1>
+    
+    <ul class="nav nav-tabs">
+        <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">Login Events</a></li>
+        <li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">Admin Events</a></li>
+        <li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
+    </ul>
+    <h2></h2>
+
+    <div id="content">
+        <table class="table table-striped table-bordered">
+            <thead>
+            <tr>
+                <th class="kc-table-actions" colspan="5">
+                    <div class="pull-right">
+                        <select data-ng-model="query.max" data-ng-click="update()" class="btn btn-default">
+                            <option>5</option>
+                            <option>10</option>
+                            <option>50</option>
+                            <option>100</option>
+                        </select>
+                        <button class="btn btn-default" data-ng-click="filter = !filter">
+                            <span class="glyphicon glyphicon-plus" data-ng-show="!filter"></span>
+                            <span class="glyphicon glyphicon-minus" data-ng-show="filter"></span>
+                            Filter
+                        </button>
+                        <button class="btn btn-default btn-primary" data-ng-click="update()">Update</button>
+                        <button class="btn btn-default btn-primary" data-ng-click="reset()">Reset</button>
+                    </div>
+                    <form class="form-horizontal" data-ng-show="filter">
+                        <div class="form-group">
+      			            <label class="col-sm-2 control-label" for="adminEnabledEventOperations">Operation Types</label>
+                    	    <div class="col-sm-5">
+                                <input ui-select2="adminEnabledEventOperationsOptions" id="adminEnabledEventOperations" ng-model="query.operationTypes" data-placeholder="Select operations..."/>
+			                </div>
+			            </div>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label" for="resource">Resource Path</label>
+                            <div class="col-sm-4">
+                                <input class="form-control" type="text" id="resource" name="resource" data-ng-model="query.resourcePath">
+                            </div>
+                            <span tooltip-placement="right" tooltip="Filter by resource path. Supports wildcards '*' to match a single part of the path and '**' matches multiple parts. For example 'realms/*/clients/asbc' matches client with id asbc in any realm, while or 'realms/master/**' matches anything in the master realm." class="fa fa-info-circle"></span>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label" for="dateFrom">Date (From)</label>
+                            <div class="col-sm-4">
+                                <input class="form-control" type="date" id="dateFrom" name="dateFrom" data-ng-model="query.dateFrom">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label" for="dateTo">Date (To)</label>
+                            <div class="col-sm-4">
+                                <input class="form-control" type="date" id="dateTo" name="dateTo" data-ng-model="query.dateTo">
+                            </div>
+                        </div>
+
+                        <fieldset>
+                            <legend><span class="text">Authentication Details</span></legend>
+
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label" for="realm">Realm</label>
+                                <div class="col-sm-4">
+                                    <input class="form-control" type="text" id="realm" name="realm" data-ng-model="query.authRealm">
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label" for="client">Client</label>
+                                <div class="col-sm-4">
+                                    <input class="form-control" type="text" id="client" name="client" data-ng-model="query.authClient">
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label" for="user">User</label>
+                                <div class="col-sm-4">
+                                    <input class="form-control" type="text" id="user" name="user" data-ng-model="query.authUser">
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label" for="ipAddress">IP Address</label>
+                                <div class="col-sm-4">
+                                    <input class="form-control" type="text" id="ipAddress" name="ipAddress" data-ng-model="query.authIpAddress">
+                                </div>
+                            </div>
+                        </fieldset>
+
+                    </form>
+                </th>
+            </tr>
+            <tr>
+                <th width="100px">Time</th>
+                <th width="180px">Operation Type</th>
+                <th width="180px">Resource Path</th>
+                <th>Details</th>
+            </tr>
+            </thead>
+            <tfoot>
+            <tr>
+            	<td colspan="7">
+                	<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-double-left"></i></button>
+                	<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0"><i data-ng-class="query.first == 0 && 'text-muted'" class="fa fa-angle-left"></i></button>
+                	<button data-ng-click="nextPage()" class="next" ng-disabled="events.length < query.max"><i data-ng-class="events.length < query.max && 'text-muted'" class="fa fa-angle-right"></i></button>
+            	</td>
+            </tr>
+            </tfoot>
+            <tbody>
+                <tr data-ng-repeat="event in events">
+                    <td>{{event.time|date:'shortDate'}}<br>{{event.time|date:'mediumTime'}}</td>
+                    <td data-ng-class="events-error">{{event.operationType}}</td>
+                    <td>{{event.resourcePath}}</td>
+                    <td>
+                        <button type="button" class="btn btn-default btn-xs" data-ng-click="viewAuth(event)">
+                            Auth
+                        </button>
+                        <button type="button" class="btn btn-default btn-xs" data-ng-click="viewRepresentation(event)" data-ng-show="event.representation">
+                            Representation
+                        </button>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+<kc-menu></kc-menu>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html
index 1b34385..11c2f00 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html
@@ -1,70 +1,114 @@
 <div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
-    <h1><strong>Events</strong> {{realm.realm|capitalize}}</span> Events</h1>
+    <h1>
+        <span><strong>Events Config</strong> {{realm.realm|capitalize}}</span>
+        <kc-tooltip>Displays configuration options to enable persistence of user and admin events.</kc-tooltip>
+    </h1>
 
     <ul class="nav nav-tabs">
-        <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">View</a></li>
+        <li data-ng-class="(path[2] == 'events') && 'active'"><a href="#/realms/{{realm.realm}}/events">Login Events</a></li>
+        <li data-ng-class="(path[2] == 'admin-events') && 'active'"><a href="#/realms/{{realm.realm}}/admin-events">Admin Events</a></li>
         <li data-ng-class="(path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events-settings">Config</a></li>
     </ul>
+    <div id="content">
+        <h2><span>{{realm.realm}}</span> Events Config</h2>
 
-    <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageEvents">
-        <fieldset class="border-top">
-            <div class="form-group">
-                <label class="col-md-2 control-label" for="enabled">Save Events</label>
-                <div class="col-md-6">
-                    <input ng-model="eventsConfig.eventsEnabled" name="enabled" id="enabled" onoffswitch />
+        <form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageEvents">
+
+            <fieldset class="border-top">
+                <div class="form-group">
+                    <label class="col-md-2 control-label" for="eventsListeners" class="control-label">Event Listeners</label>
+
+                    <div class="col-md-6">
+                        <select ui-select2 ng-model="eventsConfig.eventsListeners" data-placeholder="Select an action..." multiple>
+                            <option ng-repeat="listener in eventListeners" value="{{listener}}">{{listener}}</option>
+                        </select>
+                    </div>
+
+                    <span tooltip-placement="right" tooltip="Configure what listeners receive events for the realm." class="fa fa-info-circle"></span>
                 </div>
-                <kc-tooltip>If enabled events are saved to the database which makes events available to the admin and account management consoles.</kc-tooltip>
-            </div>
+            </fieldset>
 
-            <div class="form-group" data-ng-show="eventsConfig.eventsEnabled">
-                <label class="col-md-2 control-label" for="enabledEventTypes" class="control-label">Saved Types</label>
+            <fieldset>
+                <legend><span class="text">Login Events Settings</span></legend>
 
-                <div class="col-md-6">
-                    <input ui-select2="eventSelectOptions" id="enabledEventTypes" ng-model="eventsConfig.enabledEventTypes" data-placeholder="Select event types..."/>
+                <div class="form-group">
+                    <label class="col-md-2 control-label" for="enabled">Save Events</label>
+                    <div class="col-md-6">
+                        <input ng-model="eventsConfig.eventsEnabled" name="enabled" id="enabled" onoffswitch />
+                    </div>
+                    <span tooltip-placement="right" tooltip="If enabled login events are saved to the database which makes events available to the admin and account management consoles." class="fa fa-info-circle"></span>
                 </div>
 
-                <kc-tooltip>Configure what event types are saved. By default events related to login and users modifying their accounts are persisted.</kc-tooltip>
-            </div>
+                <div class="form-group" data-ng-show="eventsConfig.eventsEnabled">
+                    <label class="col-md-2 control-label" for="enabledEventTypes" class="control-label">Saved Types</label>
 
-            <div class="form-group" data-ng-show="access.manageEvents && eventsConfig.eventsEnabled">
-                <label class="col-md-2 control-label" for="password">Clear Events</label>
-                <div class="col-md-6">
-                    <button class="btn btn-danger" type="submit" data-ng-click="clearEvents()" >Clear Events</button>
+                    <div class="col-md-6">
+                        <input ui-select2="eventSelectOptions" id="enabledEventTypes" ng-model="eventsConfig.enabledEventTypes" data-placeholder="Select event types..."/>
+                    </div>
+
+                    <span tooltip-placement="right" tooltip="Configure what event types are saved. By default events related to login and users modifying their accounts are persisted." class="fa fa-info-circle"></span>
                 </div>
-                <kc-tooltip>Deletes all events in the database.</kc-tooltip>
-            </div>
-            <div class="form-group input-select" data-ng-show="eventsConfig.eventsEnabled">
-                <label class="col-md-2 control-label" for="expiration">Expiration</label>
-                <div class="col-md-6 form-inline">
-                    <input class="form-control" type="number" data-ng-model="eventsConfig.eventsExpiration" id="expiration" name="expiration" min="0"/>
-                    <select class="form-control" name="expirationUnit" data-ng-model="eventsConfig.expirationUnit" >
-                        <option>Minutes</option>
-                        <option>Hours</option>
-                        <option>Days</option>
-                    </select>
+
+                <div class="form-group" data-ng-show="access.manageEvents && eventsConfig.eventsEnabled">
+                    <label class="col-md-2 control-label" for="password">Clear Events</label>
+                    <div class="col-md-6">
+                        <button class="btn btn-danger" type="submit" data-ng-click="clearEvents()" >Clear Events</button>
+                    </div>
+                    <span tooltip-placement="right" tooltip="Deletes all events in the database." class="fa fa-info-circle"></span>
                 </div>
-                <div class="col-sm-1"></div>
-                <kc-tooltip>Sets the expiration for events. Expired events are periodically deleted from the database.</kc-tooltip>
-            </div>
+                <div class="form-group input-select" data-ng-show="eventsConfig.eventsEnabled">
+                    <label class="col-md-2 control-label" for="expiration">Expiration</label>
+                    <div class="col-md-6">
+                        <input class="form-control" type="number" data-ng-model="eventsConfig.eventsExpiration" id="expiration" name="expiration" min="0"/>
+                    </div>
+                    <div class="col-md-2 select-kc">
+                        <select name="expirationUnit" data-ng-model="eventsConfig.expirationUnit" >
+                            <option>Minutes</option>
+                            <option>Hours</option>
+                            <option>Days</option>
+                        </select>
+                    <span tooltip-placement="right" tooltip="Sets the expiration for events. Expired events are periodically deleted from the database." class="fa fa-info-circle"></span>
+                    </div>
+                </div>
+            </fieldset>
+
+
+            <fieldset>
+                <legend><span class="text">Admin Events Settings</span></legend>
 
-            <div class="form-group">
-                <label class="col-md-2 control-label" for="eventsListeners" class="control-label">Listeners</label>
+                <div class="form-group">
+                    <label class="col-md-2 control-label" for="adminEventsEnabled">Save Events</label>
+                    <div class="col-md-6">
+                        <input ng-model="eventsConfig.adminEventsEnabled" name="adminEventsEnabled" id="adminEventsEnabled" onoffswitch />
+                    </div>
 
-                <div class="col-md-6">
-                    <select ui-select2 ng-model="eventsConfig.eventsListeners" data-placeholder="Select an action..." multiple>
-                        <option ng-repeat="listener in eventListeners" value="{{listener}}">{{listener}}</option>
-                    </select>
+                    <span tooltip-placement="right" tooltip="If enabled admin events are saved to the database which makes events available to the admin console." class="fa fa-info-circle"></span>
                 </div>
 
-                <kc-tooltip>Configure what listeners receive events for the realm.</kc-tooltip>
-            </div>
-        </fieldset>
+                <div class="form-group" data-ng-show="eventsConfig.adminEventsEnabled">
+                    <label class="col-md-2 control-label" for="adminEventsDetailsEnabled">Include Representation</label>
+                    <div class="col-md-6">
+                        <input ng-model="eventsConfig.adminEventsDetailsEnabled" name="adminEventsDetailsEnabled" id="adminEventsDetailsEnabled" onoffswitch />
+                    </div>
 
-        <div class="pull-right form-actions" data-ng-show="access.manageEvents">
-            <button data-kc-reset data-ng-show="changed">Clear changes</button>
-            <button data-kc-save data-ng-show="changed">Save</button>
-        </div>
-    </form>
-</div>
+                    <span tooltip-placement="right" tooltip="Include JSON representation for create and update requests." class="fa fa-info-circle"></span>
+                </div>
+                
+                <div class="form-group" data-ng-show="access.manageEvents && eventsConfig.adminEventsEnabled">
+                    <label class="col-md-2 control-label" for="password">Clear Admin Events</label>
+                    <div class="col-md-6">
+                        <button class="btn btn-danger" type="submit" data-ng-click="clearAdminEvents()" >Clear Admin Events</button>
+                    </div>
+                    <span tooltip-placement="right" tooltip="Deletes all admin events in the database." class="fa fa-info-circle"></span>
+                </div>
+                
+            </fieldset>
 
-<kc-menu></kc-menu>
+                <div class="pull-right form-actions" data-ng-show="access.manageEvents">
+                <button data-kc-reset data-ng-show="changed">Clear changes</button>
+                <button data-kc-save data-ng-show="changed">Save</button>
+            </div>
+        </form>
+    </div>
+</div>
+<kc-menu></kc-menu>
\ No newline at end of file
diff --git a/forms/email-api/src/main/java/org/keycloak/email/EmailSpi.java b/forms/email-api/src/main/java/org/keycloak/email/EmailSpi.java
index cb2877b..cde73ce 100644
--- a/forms/email-api/src/main/java/org/keycloak/email/EmailSpi.java
+++ b/forms/email-api/src/main/java/org/keycloak/email/EmailSpi.java
@@ -8,6 +8,12 @@ import org.keycloak.provider.Spi;
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class EmailSpi implements Spi {
+
+    @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
     @Override
     public String getName() {
         return "email";
diff --git a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/AdminEventBean.java b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/AdminEventBean.java
new file mode 100644
index 0000000..ca225fc
--- /dev/null
+++ b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/AdminEventBean.java
@@ -0,0 +1,37 @@
+package org.keycloak.email.freemarker.beans;
+
+import java.util.Date;
+
+import org.keycloak.events.admin.AdminEvent;
+
+/**
+ * @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
+ */
+public class AdminEventBean {
+    
+    private AdminEvent adminEvent;
+
+    public AdminEventBean(AdminEvent adminEvent) {
+        this.adminEvent = adminEvent;
+    }
+
+    public Date getDate() {
+        return new Date(adminEvent.getTime());
+    }
+
+    public String getOperationType() {
+        return adminEvent.getOperationType().toString().toLowerCase();
+    }
+
+    public String getClient() {
+        return adminEvent.getAuthDetails().getClientId();
+    }
+
+    public String getIpAddress() {
+        return adminEvent.getAuthDetails().getIpAddress();
+    }
+    
+    public String getResourcePath() {
+        return adminEvent.getResourcePath();
+    }
+}
diff --git a/forms/login-api/src/main/java/org/keycloak/login/LoginFormsSpi.java b/forms/login-api/src/main/java/org/keycloak/login/LoginFormsSpi.java
index 74f5b4a..f99292a 100644
--- a/forms/login-api/src/main/java/org/keycloak/login/LoginFormsSpi.java
+++ b/forms/login-api/src/main/java/org/keycloak/login/LoginFormsSpi.java
@@ -8,6 +8,12 @@ import org.keycloak.provider.Spi;
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class LoginFormsSpi implements Spi {
+
+    @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
     @Override
     public String getName() {
         return "login";
diff --git a/integration/js/src/main/resources/keycloak.js b/integration/js/src/main/resources/keycloak.js
index 13b813b..7ff1959 100755
--- a/integration/js/src/main/resources/keycloak.js
+++ b/integration/js/src/main/resources/keycloak.js
@@ -336,6 +336,16 @@
             return promise.promise;
         }
 
+        kc.clearToken = function() {
+            if (kc.token) {
+                setToken(null, null, null);
+                kc.onAuthLogout && kc.onAuthLogout();
+                if (kc.loginRequired) {
+                    kc.login();
+                }
+            }
+        }
+
         function getRealmUrl() {
             if (kc.authServerUrl.charAt(kc.authServerUrl.length - 1) == '/') {
                 return kc.authServerUrl + 'realms/' + encodeURIComponent(kc.realm);
@@ -463,16 +473,6 @@
             return promise.promise;
         }
 
-        function clearToken() {
-            if (kc.token) {
-                setToken(null, null, null);
-                kc.onAuthLogout && kc.onAuthLogout();
-                if (kc.loginRequired) {
-                    kc.login();
-                }
-            }
-        }
-
         function setToken(token, refreshToken, idToken) {
             if (token) {
                 kc.token = token;
@@ -697,7 +697,7 @@
                 if ((!kc.sessionId || kc.sessionId == data.session) && data.loggedIn) {
                     promise.setSuccess();
                 } else {
-                    clearToken();
+                    kc.clearToken();
                     promise.setError();
                 }
             };
@@ -832,7 +832,7 @@
                             if (error) {
                                 promise.setError();
                             } else {
-                                clearToken();
+                                kc.clearToken();
                                 promise.setSuccess();
                             }
                         });
diff --git a/integration/keycloak-as7-subsystem/pom.xml b/integration/keycloak-as7-subsystem/pom.xml
index 7eb6c22..f1ee2ed 100755
--- a/integration/keycloak-as7-subsystem/pom.xml
+++ b/integration/keycloak-as7-subsystem/pom.xml
@@ -71,25 +71,25 @@
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-naming</artifactId>
-            <version>7.1.1.Final</version>
+            <version>${jboss.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-server</artifactId>
-            <version>7.1.1.Final</version>
+            <version>${jboss.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-ee</artifactId>
-            <version>7.1.1.Final</version>
+            <version>${jboss.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.jboss.as</groupId>
             <artifactId>jboss-as-web</artifactId>
-            <version>7.1.1.Final</version>
+            <version>${jboss.version}</version>
         </dependency>
 
         <dependency>
diff --git a/integration/pom.xml b/integration/pom.xml
index f79be4e..5c1f132 100755
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -22,9 +22,7 @@
         <module>as7-eap6/adapter</module>
         <module>jetty</module>
         <module>undertow</module>
-        <module>wildfly-adapter</module>
-        <module>wildfly-extensions</module>
-        <module>keycloak-subsystem</module>
+        <module>wildfly</module>
         <module>keycloak-as7-subsystem</module>
         <module>js</module>
         <module>installed</module>
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java
index 4e50685..153f20c 100644
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProvider.java
@@ -6,8 +6,10 @@ import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -17,18 +19,28 @@ import java.util.List;
  * @version $Revision: 1 $
  */
 public class KeycloakAuthenticationProvider implements AuthenticationProvider {
+    private GrantedAuthoritiesMapper grantedAuthoritiesMapper;
+
+    public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) {
+        this.grantedAuthoritiesMapper = grantedAuthoritiesMapper;
+    }
 
     @Override
     public Authentication authenticate(Authentication authentication) throws AuthenticationException {
-
         KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
         List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
 
         for (String role : token.getAccount().getRoles()) {
             grantedAuthorities.add(new KeycloakRole(role));
         }
+        return new KeycloakAuthenticationToken(token.getAccount(), mapAuthorities(grantedAuthorities));
+    }
 
-        return new KeycloakAuthenticationToken(token.getAccount(), grantedAuthorities);
+    private Collection<? extends GrantedAuthority> mapAuthorities(
+            Collection<? extends GrantedAuthority> authorities) {
+        return grantedAuthoritiesMapper != null
+            ? grantedAuthoritiesMapper.mapAuthorities(authorities)
+            : authorities;
     }
 
     @Override
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java
index 2879a06..6a64765 100644
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/authentication/KeycloakLogoutHandler.java
@@ -1,14 +1,16 @@
 package org.keycloak.adapters.springsecurity.authentication;
 
 import org.keycloak.adapters.KeycloakDeployment;
+import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
 import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
+import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.web.authentication.logout.LogoutHandler;
 import org.springframework.util.Assert;
-import org.springframework.web.util.UriComponentsBuilder;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -22,7 +24,6 @@ import java.io.IOException;
  */
 public class KeycloakLogoutHandler implements LogoutHandler {
 
-    public static final String SSO_LOGOUT_COMPLETE_PARAM = "sso_complete";
     private static final Logger log = LoggerFactory.getLogger(KeycloakLogoutHandler.class);
 
     private AdapterDeploymentContextBean deploymentContextBean;
@@ -40,30 +41,24 @@ public class KeycloakLogoutHandler implements LogoutHandler {
             return;
         }
 
-        if (Boolean.valueOf(request.getParameter(SSO_LOGOUT_COMPLETE_PARAM))) {
-            // already logged out
-            return;
-        }
-
         try {
             handleSingleSignOut(request, response);
         } catch (IOException e) {
-            throw new IllegalStateException("Unable to redirect to SSO url!", e);
+            throw new IllegalStateException("Unable to make logout admin request!", e);
         }
 
     }
 
-    protected String createRedirectUrl(HttpServletRequest request) {
-
-        return UriComponentsBuilder.fromHttpUrl(request.getRequestURL().toString())
-                .replaceQueryParam(SSO_LOGOUT_COMPLETE_PARAM, true).build().toUriString();
-    }
-
     protected void handleSingleSignOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
 
+        KeycloakAuthenticationToken authentication = (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
         KeycloakDeployment deployment = deploymentContextBean.getDeployment();
-        String redirectUrl = createRedirectUrl(request);
+        RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) authentication.getAccount().getKeycloakSecurityContext();
 
-        response.sendRedirect(deployment.getLogoutUrl().queryParam("redirect_uri", redirectUrl).build().toASCIIString());
+        try {
+            session.logout(deployment);
+        } catch (Exception e) {
+            log.error("Unable to complete Keycloak single sign out", e);
+        }
     }
 }
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java
index 34dd14d..6cbcbe6 100644
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/config/KeycloakWebSecurityConfigurerAdapter.java
@@ -17,8 +17,8 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
 import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
 import org.springframework.security.web.AuthenticationEntryPoint;
 import org.springframework.security.web.authentication.logout.LogoutFilter;
-import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter;
 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
 
 /**
  * Provides a convenient base class for creating a {@link WebSecurityConfigurer}
@@ -37,13 +37,11 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
         return new AdapterDeploymentContextBean();
     }
 
-    @Bean
     protected AuthenticationEntryPoint authenticationEntryPoint()
     {
         return new KeycloakAuthenticationEntryPoint();
     }
 
-    @Bean
     protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() {
         return new KeycloakAuthenticationProvider();
     }
@@ -69,7 +67,6 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
         return  new HttpSessionManager();
     }
 
-    @Bean
     protected KeycloakLogoutHandler keycloakLogoutHandler() {
         return new KeycloakLogoutHandler(adapterDeploymentContextBean());
     }
@@ -78,12 +75,20 @@ public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityCo
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
+
         http
+                .csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())
+                .and()
                 .sessionManagement()
                 .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                 .and()
                 .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
-                .addFilterBefore(keycloakAuthenticationProcessingFilter(), X509AuthenticationFilter.class)
-                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint());
+                .addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
+                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
+                .and()
+                .logout()
+                .addLogoutHandler(keycloakLogoutHandler())
+                .logoutUrl("/sso/logout").permitAll()
+                .logoutSuccessUrl("/");
     }
 }
diff --git a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java
index c0b5759..ade1b21 100644
--- a/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java
+++ b/integration/spring-security/src/main/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponse.java
@@ -1,11 +1,15 @@
 package org.keycloak.adapters.springsecurity.facade;
 
 import org.keycloak.adapters.HttpFacade.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 
 /**
  * Concrete Keycloak {@link Response response} implementation wrapping an {@link HttpServletResponse}.
@@ -15,6 +19,7 @@ import java.io.OutputStream;
  */
 class WrappedHttpServletResponse implements Response {
 
+    private static final Logger log = LoggerFactory.getLogger(WrappedHttpServletResponse.class);
     private final HttpServletResponse response;
 
     /**
@@ -50,11 +55,23 @@ class WrappedHttpServletResponse implements Response {
 
         cookie.setMaxAge(maxAge);
         cookie.setSecure(secure);
-        cookie.setHttpOnly(httpOnly);
+        this.setHttpOnly(cookie, httpOnly);
 
         response.addCookie(cookie);
     }
 
+    private void setHttpOnly(Cookie cookie, boolean httpOnly) {
+        Method method;
+        try {
+            method = Cookie.class.getMethod("setHttpOnly", boolean.class);
+            method.invoke(cookie, httpOnly);
+        } catch (NoSuchMethodException e) {
+            log.warn("Unable to set httpOnly on cookie [{}]; no such method on javax.servlet.http.Cookie", cookie.getName());
+        } catch (ReflectiveOperationException e) {
+            log.error("Unable to set httpOnly on cookie [{}]", cookie.getName(), e);
+        }
+    }
+
     @Override
     public void setStatus(int status) {
         response.setStatus(status);
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java
index a94ea11..6f81c0b 100644
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/authentication/KeycloakAuthenticationProviderTest.java
@@ -8,6 +8,8 @@ import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
 import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
 import org.mockito.internal.util.collections.Sets;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
 import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
 
 import java.security.Principal;
@@ -20,14 +22,12 @@ import static org.mockito.Mockito.*;
  * Keycloak authentication provider tests.
  */
 public class KeycloakAuthenticationProviderTest {
-
     private KeycloakAuthenticationProvider provider = new KeycloakAuthenticationProvider();
     private KeycloakAuthenticationToken token;
     private Set<String> roles = Sets.newSet("user", "admin");
 
     @Before
     public void setUp() throws Exception {
-
         Principal principal = mock(Principal.class);
         RefreshableKeycloakSecurityContext securityContext = mock(RefreshableKeycloakSecurityContext.class);
         KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, securityContext);
@@ -39,7 +39,7 @@ public class KeycloakAuthenticationProviderTest {
     public void testAuthenticate() throws Exception {
         Authentication result = provider.authenticate(token);
         assertNotNull(result);
-        assertEquals(roles.size(), result.getAuthorities().size());
+        assertEquals(roles, AuthorityUtils.authorityListToSet(result.getAuthorities()));
         assertTrue(result.isAuthenticated());
         assertNotNull(result.getPrincipal());
         assertNotNull(result.getCredentials());
@@ -51,4 +51,16 @@ public class KeycloakAuthenticationProviderTest {
         assertTrue(provider.supports(KeycloakAuthenticationToken.class));
         assertFalse(provider.supports(PreAuthenticatedAuthenticationToken.class));
     }
+
+    @Test
+    public void testGrantedAuthoritiesMapper() throws Exception {
+        SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
+        grantedAuthorityMapper.setPrefix("ROLE_");
+        grantedAuthorityMapper.setConvertToUpperCase(true);
+        provider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
+
+        Authentication result = provider.authenticate(token);
+        assertEquals(Sets.newSet("ROLE_USER", "ROLE_ADMIN"),
+            AuthorityUtils.authorityListToSet(result.getAuthorities()));
+    }
 }
diff --git a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java
index 408d9c5..2dd3a8c 100644
--- a/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java
+++ b/integration/spring-security/src/test/java/org/keycloak/adapters/springsecurity/facade/WrappedHttpServletResponseTest.java
@@ -48,6 +48,7 @@ public class WrappedHttpServletResponseTest {
         assertEquals(COOKIE_DOMAIN, mockResponse.getCookie(COOKIE_NAME).getDomain());
         assertEquals(maxAge, mockResponse.getCookie(COOKIE_NAME).getMaxAge());
         assertEquals(COOKIE_VALUE, mockResponse.getCookie(COOKIE_NAME).getValue());
+        assertEquals(true, mockResponse.getCookie(COOKIE_NAME).isHttpOnly());
     }
 
     @Test
diff --git a/integration/wildfly/pom.xml b/integration/wildfly/pom.xml
new file mode 100644
index 0000000..25df76d
--- /dev/null
+++ b/integration/wildfly/pom.xml
@@ -0,0 +1,22 @@
+<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-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <name>Keycloak WildFly Integration</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-wildfly-integration-pom</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>wildfly-adapter</module>
+        <module>wildfly-extensions</module>
+        <module>wildfly-server-subsystem</module>
+        <module>wildfly-adapter-subsystem</module>
+    </modules>
+</project>
\ No newline at end of file
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
new file mode 100644
index 0000000..b759b38
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
@@ -0,0 +1 @@
+org.keycloak.subsystem.adapter.extension.KeycloakExtension
diff --git a/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/subsystem-templates/keycloak-adapter.xml b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/subsystem-templates/keycloak-adapter.xml
new file mode 100644
index 0000000..a2187f6
--- /dev/null
+++ b/integration/wildfly/wildfly-adapter-subsystem/src/main/resources/subsystem-templates/keycloak-adapter.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
+<config>
+   <extension-module>org.keycloak.keycloak-adapter-subsystem</extension-module>
+   <subsystem xmlns="urn:jboss:domain:keycloak:1.1">
+   </subsystem>
+</config>
diff --git a/integration/wildfly/wildfly-server-subsystem/pom.xml b/integration/wildfly/wildfly-server-subsystem/pom.xml
new file mode 100755
index 0000000..71bb0fd
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+~ Copyright 2013 JBoss Inc
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~       http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.keycloak</groupId>
+        <artifactId>keycloak-parent</artifactId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>keycloak-wildfly-server-subsystem</artifactId>
+    <name>Keycloak Server Subsystem</name>
+    <description/>
+    <packaging>jar</packaging>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <redirectTestOutputToFile>false</redirectTestOutputToFile>
+                    <enableAssertions>true</enableAssertions>
+                    <systemProperties>
+                        <property>
+                            <name>jboss.home</name>
+                            <value>${jboss.home}</value>
+                        </property>
+                    </systemProperties>
+                    <includes>
+                        <include>**/*TestCase.java</include>
+                    </includes>
+                </configuration>
+            </plugin>            
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.wildfly.core</groupId>
+            <artifactId>wildfly-controller</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.wildfly.core</groupId>
+            <artifactId>wildfly-server</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.wildfly</groupId>
+            <artifactId>wildfly-web-common</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging-annotations</artifactId>
+            <version>${jboss-logging-tools.version}</version>
+            <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
+            projects that depend on this project.-->
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging-processor</artifactId>
+            <!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
+            projects that depend on this project.-->
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.wildfly.core</groupId>
+            <artifactId>wildfly-subsystem-test-framework</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-wildfly-adapter</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java
new file mode 100755
index 0000000..7f86d79
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakAdapterConfigService.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.server.extension;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
+
+/**
+ * This service keeps track of the entire Keycloak management model so as to provide
+ * adapter configuration to each deployment at deploy time.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public final class KeycloakAdapterConfigService {
+
+    private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
+
+    public static KeycloakAdapterConfigService getInstance() {
+        return INSTANCE;
+    }
+
+    // key=auth-server deployment name; value=web-context
+    private final Map<String, String> webContexts = new HashMap<String, String>();
+
+
+
+    private KeycloakAdapterConfigService() {
+    }
+
+    public void addServerDeployment(String deploymentName, String webContext) {
+        this.webContexts.put(deploymentName, webContext);
+    }
+
+    public String getWebContext(String deploymentName) {
+        return webContexts.get(deploymentName);
+    }
+
+    public void removeServerDeployment(String deploymentName) {
+        this.webContexts.remove(deploymentName);
+    }
+
+    public boolean isWebContextUsed(String webContext) {
+        return webContexts.containsValue(webContext);
+    }
+
+    public boolean isKeycloakServerDeployment(String deploymentName) {
+        return this.webContexts.containsKey(deploymentName);
+    }
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java
new file mode 100755
index 0000000..b40eb35
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakDependencyProcessor.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.server.extension;
+
+import org.jboss.as.server.deployment.Attachments;
+import org.jboss.as.server.deployment.DeploymentPhaseContext;
+import org.jboss.as.server.deployment.DeploymentUnit;
+import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
+import org.jboss.as.server.deployment.DeploymentUnitProcessor;
+import org.jboss.as.server.deployment.module.ModuleDependency;
+import org.jboss.as.server.deployment.module.ModuleSpecification;
+import org.jboss.modules.Module;
+import org.jboss.modules.ModuleIdentifier;
+import org.jboss.modules.ModuleLoader;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public abstract class KeycloakDependencyProcessor implements DeploymentUnitProcessor {
+
+    private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core");
+    private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-adapter-core");
+    private static final ModuleIdentifier KEYCLOAK_CORE = ModuleIdentifier.create("org.keycloak.keycloak-core");
+
+    @Override
+    public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
+        final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
+
+        // Next phase, need to detect if this is a Keycloak deployment.  If not, don't add the modules.
+
+        final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
+        final ModuleLoader moduleLoader = Module.getBootModuleLoader();
+        addCommonModules(moduleSpecification, moduleLoader);
+        addPlatformSpecificModules(moduleSpecification, moduleLoader);
+    }
+
+    private void addCommonModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
+        // ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
+        moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false));
+        moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false));
+        moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE, false, false, false, false));
+    }
+
+    abstract protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader);
+
+    @Override
+    public void undeploy(DeploymentUnit du) {
+
+    }
+
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java
new file mode 100755
index 0000000..145b475
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakExtension.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import org.jboss.as.controller.Extension;
+import org.jboss.as.controller.ExtensionContext;
+import org.jboss.as.controller.ModelVersion;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.ResourceDefinition;
+import org.jboss.as.controller.SubsystemRegistration;
+import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
+import org.jboss.as.controller.parsing.ExtensionParsingContext;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.keycloak.subsystem.server.extension.authserver.AuthServerDefinition;
+import org.keycloak.subsystem.server.logging.KeycloakLogger;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
+
+
+/**
+ * Main Extension class for the subsystem.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class KeycloakExtension implements Extension {
+
+    public static final String SUBSYSTEM_NAME = "keycloak-server";
+    public static final String NAMESPACE = "urn:jboss:domain:keycloak-server:1.1";
+    private static final KeycloakSubsystemParser PARSER = new KeycloakSubsystemParser();
+    static final PathElement PATH_SUBSYSTEM = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+    private static final String RESOURCE_NAME = KeycloakExtension.class.getPackage().getName() + ".LocalDescriptions";
+    private static final ModelVersion MGMT_API_VERSION = ModelVersion.create(1,1,0);
+    static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+    private static final ResourceDefinition KEYCLOAK_SUBSYSTEM_RESOURCE = new KeycloakSubsystemDefinition();
+    static final AuthServerDefinition AUTH_SERVER_DEFINITION = new AuthServerDefinition();
+
+    public static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
+        StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
+        for (String kp : keyPrefix) {
+            prefix.append('.').append(kp);
+        }
+        return new StandardResourceDescriptionResolver(prefix.toString(), RESOURCE_NAME, KeycloakExtension.class.getClassLoader(), true, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void initializeParsers(final ExtensionParsingContext context) {
+        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakExtension.NAMESPACE, PARSER);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void initialize(final ExtensionContext context) {
+        KeycloakLogger.ROOT_LOGGER.debug("Activating Keycloak Extension");
+        final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MGMT_API_VERSION);
+
+        ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
+        registration.registerSubModel(AUTH_SERVER_DEFINITION);
+        subsystem.registerXMLElementWriter(PARSER);
+    }
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java
new file mode 100755
index 0000000..622c010
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemAdd.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import org.jboss.as.controller.AbstractBoottimeAddStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.server.AbstractDeploymentChainStep;
+import org.jboss.as.server.DeploymentProcessorTarget;
+import org.jboss.as.server.deployment.Phase;
+import org.jboss.dmr.ModelNode;
+
+import org.jboss.as.server.deployment.DeploymentUnitProcessor;
+import org.keycloak.subsystem.server.extension.authserver.KeycloakServerDeploymentProcessor;
+
+/**
+ * The Keycloak subsystem add update handler.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler {
+
+    static final KeycloakSubsystemAdd INSTANCE = new KeycloakSubsystemAdd();
+
+    @Override
+    protected void performBoottime(final OperationContext context, ModelNode operation, final ModelNode model) {
+        context.addStep(new AbstractDeploymentChainStep() {
+            @Override
+            protected void execute(DeploymentProcessorTarget processorTarget) {
+                processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME, Phase.DEPENDENCIES, 0, chooseDependencyProcessor());
+                processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME,
+                        Phase.POST_MODULE, // PHASE
+                        Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
+                        new KeycloakServerDeploymentProcessor());
+            }
+        }, OperationContext.Stage.RUNTIME);
+    }
+
+    private DeploymentUnitProcessor chooseDependencyProcessor() {
+        return new KeycloakDependencyProcessorWildFly();
+    }
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java
new file mode 100644
index 0000000..f553188
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemDefinition.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.keycloak.subsystem.server.extension;
+
+import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+
+/**
+ * Definition of subsystem=keycloak.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+public class KeycloakSubsystemDefinition extends SimpleResourceDefinition {
+    protected KeycloakSubsystemDefinition() {
+        super(KeycloakExtension.SUBSYSTEM_PATH,
+                KeycloakExtension.getResourceDescriptionResolver("subsystem"),
+                KeycloakSubsystemAdd.INSTANCE,
+                ReloadRequiredRemoveStepHandler.INSTANCE
+        );
+    }
+
+    @Override
+    public void registerOperations(ManagementResourceRegistration resourceRegistration) {
+        super.registerOperations(resourceRegistration);
+        resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
+    }
+
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java
new file mode 100755
index 0000000..921c576
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakSubsystemParser.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import org.keycloak.subsystem.server.extension.authserver.AuthServerDefinition;
+import org.jboss.as.controller.AttributeDefinition;
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
+import org.jboss.as.controller.operations.common.Util;
+import org.jboss.as.controller.parsing.ParseUtils;
+import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+import org.jboss.staxmapper.XMLElementReader;
+import org.jboss.staxmapper.XMLElementWriter;
+import org.jboss.staxmapper.XMLExtendedStreamReader;
+import org.jboss.staxmapper.XMLExtendedStreamWriter;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The subsystem parser, which uses stax to read and write to and from xml
+ */
+class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<List<ModelNode>>, XMLElementWriter<SubsystemMarshallingContext> {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void readElement(final XMLExtendedStreamReader reader, final List<ModelNode> list) throws XMLStreamException {
+        // Require no attributes
+        ParseUtils.requireNoAttributes(reader);
+        ModelNode addKeycloakSub = Util.createAddOperation(PathAddress.pathAddress(KeycloakExtension.PATH_SUBSYSTEM));
+        list.add(addKeycloakSub);
+
+        while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
+            if (reader.getLocalName().equals(AuthServerDefinition.TAG_NAME)) {
+                readAuthServer(reader, list);
+            }
+        }
+    }
+
+    // used for debugging
+    private int nextTag(XMLExtendedStreamReader reader) throws XMLStreamException {
+        return reader.nextTag();
+    }
+
+    private void readAuthServer(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
+        String authServerName = readNameAttribute(reader);
+        ModelNode addAuthServer = new ModelNode();
+        addAuthServer.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
+        PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
+                                                   PathElement.pathElement(AuthServerDefinition.TAG_NAME, authServerName));
+        addAuthServer.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
+
+        while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
+            String tagName = reader.getLocalName();
+            SimpleAttributeDefinition def = AuthServerDefinition.lookup(tagName);
+            if (def == null) throw new XMLStreamException("Unknown auth-server tag " + tagName);
+            def.parseAndSetParameter(reader.getElementText(), addAuthServer, reader);
+        }
+
+        list.add(addAuthServer);
+    }
+
+    // expects that the current tag will have one single attribute called "name"
+    private String readNameAttribute(XMLExtendedStreamReader reader) throws XMLStreamException {
+        String name = null;
+        for (int i = 0; i < reader.getAttributeCount(); i++) {
+            String attr = reader.getAttributeLocalName(i);
+            if (attr.equals("name")) {
+                name = reader.getAttributeValue(i);
+                continue;
+            }
+            throw ParseUtils.unexpectedAttribute(reader, i);
+        }
+        if (name == null) {
+            throw ParseUtils.missingRequired(reader, Collections.singleton("name"));
+        }
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
+        context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
+        writeAuthServers(writer, context);
+        writer.writeEndElement();
+    }
+
+    private void writeAuthServers(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
+        if (!context.getModelNode().get(AuthServerDefinition.TAG_NAME).isDefined()) {
+            return;
+        }
+        for (Property authServer : context.getModelNode().get(AuthServerDefinition.TAG_NAME).asPropertyList()) {
+            writer.writeStartElement(AuthServerDefinition.TAG_NAME);
+            writer.writeAttribute("name", authServer.getName());
+            ModelNode authServerElements = authServer.getValue();
+            for (AttributeDefinition element : AuthServerDefinition.ALL_ATTRIBUTES) {
+                element.marshallAsElement(authServerElements, writer);
+            }
+
+            writer.writeEndElement();
+        }
+    }
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
new file mode 100755
index 0000000..bf6053b
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakLogger.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.logging;
+
+import org.jboss.logging.BasicLogger;
+import org.jboss.logging.Logger;
+import org.jboss.logging.annotations.LogMessage;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageLogger;
+
+import static org.jboss.logging.Logger.Level.INFO;
+
+/**
+ * This interface to be fleshed out later when error messages are fully externalized.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
+ */
+@MessageLogger(projectCode = "KEYCLOAK")
+public interface KeycloakLogger extends BasicLogger {
+
+    /**
+     * A logger with a category of the package name.
+     */
+    KeycloakLogger ROOT_LOGGER = Logger.getMessageLogger(KeycloakLogger.class, "org.jboss.keycloak");
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
new file mode 100755
index 0000000..710c054
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/java/org/keycloak/subsystem/server/logging/KeycloakMessages.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.logging;
+
+import org.jboss.logging.Messages;
+import org.jboss.logging.annotations.MessageBundle;
+
+/**
+ * This interface to be fleshed out later when error messages are fully externalized.
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2012 Red Hat Inc.
+ */
+@MessageBundle(projectCode = "KEYCLOAK")
+public interface KeycloakMessages {
+
+    /**
+     * The messages
+     */
+    KeycloakMessages MESSAGES = Messages.getBundle(KeycloakMessages.class);
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/integration/wildfly/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
new file mode 100644
index 0000000..36b9edb
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
@@ -0,0 +1 @@
+org.keycloak.subsystem.server.extension.KeycloakExtension
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties b/integration/wildfly/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
new file mode 100755
index 0000000..f09e3bd
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/resources/org/keycloak/subsystem/server/extension/LocalDescriptions.properties
@@ -0,0 +1,26 @@
+keycloak-server.subsystem=Keycloak subsystem
+keycloak-server.subsystem.add=Operation Adds Keycloak subsystem
+keycloak-server.subsystem.remove=Operation removes Keycloak subsystem
+keycloak-server.subsystem.auth-server=Keycloak Auth Server
+keycloak-server.subsystem.realm=A Keycloak realm.
+keycloak-server.subsystem.secure-deployment=A deployment secured by Keycloak.
+
+
+keycloak-server.auth-server=A Keycloak Auth Server
+keycloak-server.auth-server.add=Add an Auth Server to the subsystem.
+keycloak-server.auth-server.remove=Remove an Auth Server from the subsystem.
+keycloak-server.auth-server.add-provider=Add a provider service jar to the Keycloak auth server.
+keycloak-server.auth-server.add-provider.uploaded-file-name=The file name of the provider service jar to be added or updated.
+keycloak-server.auth-server.add-provider.bytes-to-upload=The bytes of the provider service jar to be added or updated.
+keycloak-server.auth-server.add-provider.redeploy=Redeploy the auth server after adding the provider.  Ignored if auth server is disabled.
+keycloak-server.auth-server.add-provider.overwrite=Overwrite even if the uploaded-file-name already exists as an overlay.
+keycloak-server.auth-server.list-overlays=List the overlays uploaded for this auth server.
+keycloak-server.auth-server.remove-overlay=Remove a provider jar, theme jar, or keycloak-server.json that has been uploaded to the auth server.
+keycloak-server.auth-server.remove-overlay.overlay-file-path=The uploaded path and file name of the overlay to be removed.
+keycloak-server.auth-server.remove-overlay.redeploy=Redeploy the auth server after removing the overlay.
+keycloak-server.auth-server.update-server-config=Upload a new keycloak-server.json configuration file for the Keycloak auth server.
+keycloak-server.auth-server.update-server-config.bytes-to-upload=The bytes of the keycloak-server.json file to be added or updated.
+keycloak-server.auth-server.update-server-config.redeploy=Redeploy the auth server after updating the server config.
+keycloak-server.auth-server.update-server-config.overwrite=Overwrite even if keycloak-server.json already exitss as an overlay.
+keycloak-server.auth-server.enabled=Enable or disable the Auth Server.
+keycloak-server.auth-server.web-context=Web context the auth-server will use.  Also, the module name of the auth-server deployment.
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd b/integration/wildfly/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
new file mode 100755
index 0000000..a8dd28e
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/resources/schema/wildfly-keycloak-server_1_1.xsd
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           targetNamespace="urn:jboss:domain:keycloak-server:1.1"
+           xmlns="urn:jboss:domain:keycloak-server:1.1"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           version="1.0">
+
+    <!-- The subsystem root element -->
+    <xs:element name="subsystem" type="subsystem-type"/>
+
+    <xs:complexType name="subsystem-type">
+        <xs:annotation>
+            <xs:documentation>
+                <![CDATA[
+                    The Keycloak server subsystem, used to configure the Keycloak server
+                ]]>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="auth-server" maxOccurs="1" minOccurs="0" type="auth-server-type"/>
+        </xs:choice>
+    </xs:complexType>
+
+    <xs:complexType name="auth-server-type">
+        <xs:all>
+            <xs:element name="web-context" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="enabled" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+        </xs:all>
+        <xs:attribute name="name" type="xs:string" use="required">
+            <xs:annotation>
+                <xs:documentation>The name of the war archive containing the Keycloak server web application.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+    </xs:complexType>
+
+</xs:schema>
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml b/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
new file mode 100644
index 0000000..9f05130
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-datasources.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
+<config>
+    <extension-module>org.jboss.as.connector</extension-module>
+    <subsystem xmlns="urn:jboss:domain:datasources:3.0">
+        <datasources>
+            <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
+                <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+                <driver>h2</driver>
+                <security>
+                    <user-name>sa</user-name>
+                    <password>sa</password>
+                </security>
+            </datasource>
+            <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+                <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+                <driver>h2</driver>
+                <security>
+                    <user-name>sa</user-name>
+                    <password>sa</password>
+                </security>
+            </datasource>
+            <drivers>
+                <driver name="h2" module="com.h2database.h2">
+                    <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+                </driver>
+            </drivers>
+        </datasources>
+    </subsystem>
+</config>
diff --git a/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml b/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
new file mode 100644
index 0000000..7f66f74
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/main/resources/subsystem-templates/keycloak-server.xml
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--  Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
+<config>
+   <extension-module>org.keycloak.keycloak-server-subsystem</extension-module>
+   <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+      <auth-server name="main-auth-server">
+         <enabled>true</enabled>
+         <web-context>auth</web-context>
+      </auth-server>
+   </subsystem>
+</config>
diff --git a/integration/wildfly/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java b/integration/wildfly/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java
new file mode 100755
index 0000000..9f29a6f
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/SubsystemParsingTestCase.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.keycloak.subsystem.server.extension;
+
+import java.io.IOException;
+
+import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
+import org.jboss.dmr.ModelNode;
+import org.junit.Test;
+
+/**
+ * Tests all management expects for subsystem, parsing, marshaling, model definition and other
+ * Here is an example that allows you a fine grained controller over what is tested and how. So it can give you ideas what can be done and tested.
+ * If you have no need for advanced testing of subsystem you look at {@link AbstractSubsystemBaseTest} that testes same stuff but most of the code
+ * is hidden inside of test harness
+ *
+ * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
+ * @author Tomaz Cerar
+ * @author Marko Strukelj
+ */
+public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
+
+    public SubsystemParsingTestCase() {
+        super(KeycloakExtension.SUBSYSTEM_NAME, new KeycloakExtension());
+    }
+
+    @Test
+    public void testJson() throws Exception {
+        ModelNode node = new ModelNode();
+        node.get("enabled").set(true);
+        node.get("web-context").set("auth");
+
+        System.out.println("json=" + node.toJSONString(false));
+    }
+
+    @Override
+    protected String getSubsystemXml() throws IOException {
+        return readResource("keycloak-server-1.1.xml");
+    }
+
+    @Override
+    protected String getSubsystemXsdPath() throws Exception {
+        return "schema/wildfly-keycloak-server_1_1.xsd";
+    }
+
+    @Override
+    protected String[] getSubsystemTemplatePaths() throws IOException {
+        return new String[]{
+            "/subsystem-templates/keycloak-server.xml"
+        };
+    }
+}
diff --git a/integration/wildfly/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml b/integration/wildfly/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml
new file mode 100644
index 0000000..f05f8d1
--- /dev/null
+++ b/integration/wildfly/wildfly-server-subsystem/src/test/resources/org/keycloak/subsystem/server/extension/keycloak-server-1.1.xml
@@ -0,0 +1,6 @@
+<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+    <auth-server name="main-auth-server">
+        <enabled>true</enabled>
+        <web-context>auth</web-context>
+    </auth-server>
+</subsystem>
\ No newline at end of file
diff --git a/misc/UpdatingDatabaseSchema.md b/misc/UpdatingDatabaseSchema.md
index 274669c..375d909 100644
--- a/misc/UpdatingDatabaseSchema.md
+++ b/misc/UpdatingDatabaseSchema.md
@@ -37,7 +37,7 @@ You can also have Liquibase and Hibernate create one for you. To do this follow 
 3. Make a copy of the database:  
    `cp keycloak.h2.db keycloak-old.h2.db`    
 3. Run KeycloakServer to make Hibernate update the schema:  
-   `mvn -f testsuite/integration exec:java -Pkeycloak-server -Dkeycloak.connectionsJpa.url='jdbc:h2:keycloak' -Dkeycloak.connectionsJpa.databaseSchema='development-update'`
+   `mvn -f testsuite/integration/pom.xml exec:java -Pkeycloak-server -Dkeycloak.connectionsJpa.url='jdbc:h2:keycloak' -Dkeycloak.connectionsJpa.databaseSchema='development-update'`
 4. Wait until server is completely started, then stop it
 5. View the difference:                                       
    `mvn -f connections/jpa-liquibase/pom.xml liquibase:diff -Durl=jdbc:h2:keycloak-old -DreferenceUrl=jdbc:h2:keycloak`
@@ -76,4 +76,4 @@ It should be added last to the `DefaultMongoUpdaterProvider#updates` array.
 Testing database migration
 --------------------------
 
-Get the database from an old version of Keycloak that includes the demo applications. Start the server with this and test it.
\ No newline at end of file
+Get the database from an old version of Keycloak that includes the demo applications. Start the server with this and test it.
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java b/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java
index a0e5959..62dcd68 100755
--- a/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationModelManager.java
@@ -16,16 +16,15 @@ public class MigrationModelManager {
         String storedVersion = model.getStoredVersion();
         if (MigrationModel.LATEST_VERSION.equals(storedVersion)) return;
         ModelVersion stored = null;
-        if (storedVersion == null) stored = new ModelVersion(0, 0, 0);
-        else stored = new ModelVersion(storedVersion);
+        if (storedVersion != null) new ModelVersion(storedVersion);
 
-        if (stored.lessThan(MigrationTo1_2_0_CR1.VERSION)) {
-            logger.info("Migrating older model to 1.2.0.RC1 updates");
+        if (stored == null || stored.lessThan(MigrationTo1_2_0_CR1.VERSION)) {
+            if (stored != null) {
+                logger.debug("Migrating older model to 1.2.0.RC1 updates");
+            }
             new MigrationTo1_2_0_CR1().migrate(session);
         }
 
         model.setStoredVersion(MigrationModel.LATEST_VERSION);
-
-
     }
 }
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java b/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
index f6b768c..e599146 100644
--- a/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class MigrationSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "migration";
     }
diff --git a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
index 3c978f9..718a1c5 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java
@@ -63,7 +63,10 @@ public class RealmEntity extends AbstractIdentifiableEntity {
     private long eventsExpiration;
     private List<String> eventsListeners = new ArrayList<String>();
     private List<String> enabledEventTypes = new ArrayList<String>();
-
+    
+    protected boolean adminEventsEnabled;
+    protected boolean adminEventsDetailsEnabled;
+    
     private String masterAdminClient;
 
     private boolean internationalizationEnabled;
@@ -391,6 +394,22 @@ public class RealmEntity extends AbstractIdentifiableEntity {
         this.enabledEventTypes = enabledEventTypes;
     }
     
+    public boolean isAdminEventsEnabled() {
+        return adminEventsEnabled;
+    }
+
+    public void setAdminEventsEnabled(boolean adminEventsEnabled) {
+        this.adminEventsEnabled = adminEventsEnabled;
+    }
+
+    public boolean isAdminEventsDetailsEnabled() {
+        return adminEventsDetailsEnabled;
+    }
+
+    public void setAdminEventsDetailsEnabled(boolean adminEventsDetailsEnabled) {
+        this.adminEventsDetailsEnabled = adminEventsDetailsEnabled;
+    }
+
     public String getMasterAdminClient() {
         return masterAdminClient;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 8b901a2..dca2067 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -232,7 +232,15 @@ public interface RealmModel extends RoleContainerModel {
     Set<String> getEnabledEventTypes();
 
     void setEnabledEventTypes(Set<String> enabledEventTypes);
+    
+    boolean isAdminEventsEnabled();
+
+    void setAdminEventsEnabled(boolean enabled);
+    
+    boolean isAdminEventsDetailsEnabled();
 
+    void setAdminEventsDetailsEnabled(boolean enabled);
+    
     ClientModel getMasterAdminClient();
 
     void setMasterAdminClient(ClientModel client);
diff --git a/model/api/src/main/java/org/keycloak/models/RealmSpi.java b/model/api/src/main/java/org/keycloak/models/RealmSpi.java
index 1c1429c..f531cd9 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmSpi.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class RealmSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "realm";
     }
diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationSpi.java b/model/api/src/main/java/org/keycloak/models/UserFederationSpi.java
index 6a22337..c17c02a 100755
--- a/model/api/src/main/java/org/keycloak/models/UserFederationSpi.java
+++ b/model/api/src/main/java/org/keycloak/models/UserFederationSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class UserFederationSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return false;
+    }
+
+    @Override
     public String getName() {
         return "userFederation";
     }
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionSpi.java b/model/api/src/main/java/org/keycloak/models/UserSessionSpi.java
index e470db5..8755660 100644
--- a/model/api/src/main/java/org/keycloak/models/UserSessionSpi.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionSpi.java
@@ -12,6 +12,11 @@ public class UserSessionSpi implements Spi {
     public static final String NAME = "userSessions";
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return NAME;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/UserSpi.java b/model/api/src/main/java/org/keycloak/models/UserSpi.java
index e68299c..1d6cd74 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSpi.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class UserSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "user";
     }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 2a8da38..84248fd 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -14,6 +14,7 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
+
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.FederatedIdentityRepresentation;
@@ -192,6 +193,10 @@ public class ModelToRepresentation {
             rep.setEnabledEventTypes(new LinkedList<String>(realm.getEnabledEventTypes()));
         }
         
+        rep.setAdminEventsEnabled(realm.isAdminEventsEnabled());
+        
+        rep.setAdminEventsDetailsEnabled(realm.isAdminEventsDetailsEnabled());
+        
         return rep;
     }
 
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
index 45221e5..578ecc9 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -410,10 +410,15 @@ public class RepresentationToModel {
         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.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
         if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
         if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<>(rep.getEventsListeners()));
         if (rep.getEnabledEventTypes() != null) realm.setEnabledEventTypes(new HashSet<>(rep.getEnabledEventTypes()));
+        
+        if (rep.isAdminEventsEnabled() != null) realm.setAdminEventsEnabled(rep.isAdminEventsEnabled());
+        if (rep.isAdminEventsDetailsEnabled() != null) realm.setAdminEventsDetailsEnabled(rep.isAdminEventsDetailsEnabled());
+        
 
         if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
 
diff --git a/model/api/src/main/java/org/keycloak/provider/Spi.java b/model/api/src/main/java/org/keycloak/provider/Spi.java
index 03b9afc..be68251 100644
--- a/model/api/src/main/java/org/keycloak/provider/Spi.java
+++ b/model/api/src/main/java/org/keycloak/provider/Spi.java
@@ -5,6 +5,7 @@ package org.keycloak.provider;
  */
 public interface Spi {
 
+    public boolean isPrivate();
     public String getName();
     public Class<? extends Provider> getProviderClass();
     public Class<? extends ProviderFactory> getProviderFactoryClass();
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
index cdd658a..d835102 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java
@@ -959,6 +959,26 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
+    public boolean isAdminEventsEnabled() {
+        return realm.isAdminEventsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsEnabled(boolean enabled) {
+        realm.setAdminEventsEnabled(enabled);
+    }
+
+    @Override
+    public boolean isAdminEventsDetailsEnabled() {
+        return realm.isAdminEventsDetailsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsDetailsEnabled(boolean enabled) {
+        realm.setAdminEventsDetailsEnabled(enabled);
+    }
+    
+    @Override
     public ClientModel getMasterAdminClient() {
         return this.masterAdminApp;
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProviderSpi.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProviderSpi.java
index f6bbfd5..300b8f0 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProviderSpi.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheRealmProviderSpi.java
@@ -11,6 +11,11 @@ import org.keycloak.provider.Spi;
 public class CacheRealmProviderSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "realmCache";
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
index 6c0fae5..9e0affa 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
@@ -11,6 +11,11 @@ import org.keycloak.provider.Spi;
 public class CacheUserProviderSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "userCache";
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
index e490814..22f57a9 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
@@ -79,6 +79,9 @@ public class CachedRealm {
     private long eventsExpiration;
     private Set<String> eventsListeners = new HashSet<String>();
     private Set<String> enabledEventTypes = new HashSet<String>();
+    protected boolean adminEventsEnabled;
+    protected Set<String> adminEnabledEventOperations = new HashSet<String>();
+    protected boolean adminEventsDetailsEnabled;
     private List<String> defaultRoles = new LinkedList<String>();
     private Map<String, String> realmRoles = new HashMap<String, String>();
     private Map<String, String> clients = new HashMap<String, String>();
@@ -153,6 +156,10 @@ public class CachedRealm {
         eventsExpiration = model.getEventsExpiration();
         eventsListeners.addAll(model.getEventsListeners());
         enabledEventTypes.addAll(model.getEnabledEventTypes());
+        
+        adminEventsEnabled = model.isAdminEventsEnabled();
+        adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled();
+        
         defaultRoles.addAll(model.getDefaultRoles());
         masterAdminClient = model.getMasterAdminClient().getId();
 
@@ -350,6 +357,18 @@ public class CachedRealm {
         return enabledEventTypes;
     }
 
+    public boolean isAdminEventsEnabled() {
+        return adminEventsEnabled;
+    }
+
+    public Set<String> getAdminEnabledEventOperations() {
+        return adminEnabledEventOperations;
+    }
+
+    public boolean isAdminEventsDetailsEnabled() {
+        return adminEventsDetailsEnabled;
+    }
+
     public List<UserFederationProviderModel> getUserFederationProviders() {
         return userFederationProviders;
     }
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 68a65ac..33f2356 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
@@ -751,6 +751,30 @@ public class RealmAdapter implements RealmModel {
     }
     
     @Override
+    public boolean isAdminEventsEnabled() {
+        if (updated != null) return updated.isAdminEventsEnabled();
+        return cached.isAdminEventsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsEnabled(boolean enabled) {
+        getDelegateForUpdate();
+        updated.setAdminEventsEnabled(enabled);
+    }
+
+    @Override
+    public boolean isAdminEventsDetailsEnabled() {
+        if (updated != null) return updated.isAdminEventsDetailsEnabled();
+        return cached.isAdminEventsDetailsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsDetailsEnabled(boolean enabled) {
+        getDelegateForUpdate();
+        updated.setAdminEventsDetailsEnabled(enabled);
+    }
+    
+    @Override
     public ClientModel getMasterAdminClient() {
         return cacheSession.getRealm(Config.getAdminRealm()).getClientById(cached.getMasterAdminClient());
     }
@@ -923,4 +947,5 @@ public class RealmAdapter implements RealmModel {
         }
         return null;
     }
+
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index efdb4a8..cdf314c 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -134,7 +134,13 @@ public class RealmEntity {
     @Column(name="VALUE")
     @CollectionTable(name="REALM_ENABLED_EVENT_TYPES", joinColumns={ @JoinColumn(name="REALM_ID") })
     protected Set<String> enabledEventTypes = new HashSet<String>();
-
+    
+    @Column(name="ADMIN_EVENTS_ENABLED")
+    protected boolean adminEventsEnabled;
+    
+    @Column(name="ADMIN_EVENTS_DETAILS_ENABLED")
+    protected boolean adminEventsDetailsEnabled;
+    
     @OneToOne
     @JoinColumn(name="MASTER_ADMIN_CLIENT")
     protected ClientEntity masterAdminClient;
@@ -437,6 +443,22 @@ public class RealmEntity {
         this.enabledEventTypes = enabledEventTypes;
     }
     
+    public boolean isAdminEventsEnabled() {
+        return adminEventsEnabled;
+    }
+
+    public void setAdminEventsEnabled(boolean adminEventsEnabled) {
+        this.adminEventsEnabled = adminEventsEnabled;
+    }
+
+    public boolean isAdminEventsDetailsEnabled() {
+        return adminEventsDetailsEnabled;
+    }
+
+    public void setAdminEventsDetailsEnabled(boolean adminEventsDetailsEnabled) {
+        this.adminEventsDetailsEnabled = adminEventsDetailsEnabled;
+    }
+
     public ClientEntity getMasterAdminClient() {
         return masterAdminClient;
     }
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 8618ddb..66b94d0 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
@@ -22,6 +22,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
+
 import java.security.Key;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -1065,8 +1066,30 @@ public class RealmAdapter implements RealmModel {
         realm.setEnabledEventTypes(enabledEventTypes);
         em.flush();
     }
+    
+    @Override
+    public boolean isAdminEventsEnabled() {
+        return realm.isAdminEventsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsEnabled(boolean enabled) {
+        realm.setAdminEventsEnabled(enabled);
+        em.flush();
+    }
 
     @Override
+    public boolean isAdminEventsDetailsEnabled() {
+        return realm.isAdminEventsDetailsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsDetailsEnabled(boolean enabled) {
+        realm.setAdminEventsDetailsEnabled(enabled);
+        em.flush();
+    }
+    
+    @Override
     public ClientModel getMasterAdminClient() {
         return new ClientAdapter(this, em, session, realm.getMasterAdminClient());
     }
@@ -1327,4 +1350,5 @@ public class RealmAdapter implements RealmModel {
         mapping.setConfig(config);
         return mapping;
     }
+
 }
\ No newline at end of file
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 fb08290..d797de9 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
@@ -2,6 +2,7 @@ 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.enums.SslRequired;
 import org.keycloak.models.ClientModel;
@@ -985,8 +986,31 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         }
         updateRealm();
     }
+    
+    @Override
+    public boolean isAdminEventsEnabled() {
+        return realm.isAdminEventsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsEnabled(boolean enabled) {
+        realm.setAdminEventsEnabled(enabled);
+        updateRealm();
+        
+    }
 
     @Override
+    public boolean isAdminEventsDetailsEnabled() {
+        return realm.isAdminEventsDetailsEnabled();
+    }
+
+    @Override
+    public void setAdminEventsDetailsEnabled(boolean enabled) {
+        realm.setAdminEventsDetailsEnabled(enabled);
+        updateRealm();
+    }
+    
+    @Override
     public ClientModel getMasterAdminClient() {
         MongoClientEntity appData = getMongoStore().loadEntity(MongoClientEntity.class, realm.getMasterAdminClient(), invocationContext);
         return appData != null ? new ClientAdapter(session, this, appData, invocationContext) : null;

pom.xml 208(+200 -8)

diff --git a/pom.xml b/pom.xml
index 07246fb..796918a 100755
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.jboss</groupId>
         <artifactId>jboss-parent</artifactId>
-        <version>14</version>
+        <version>16</version>
     </parent>
 
     <name>Keycloak</name>
@@ -20,18 +20,26 @@
     <properties>
         <apacheds.version>2.0.0-M17</apacheds.version>
         <apacheds.codec.version>1.0.0-M23</apacheds.codec.version>
+        <org.apache.james.apache-mime4j.version>0.6</org.apache.james.apache-mime4j.version>
         <base64.version>2.3.8</base64.version>
         <bouncycastle.crypto.version>1.50</bouncycastle.crypto.version>
         <jackson.version>1.9.9</jackson.version>
         <apache.httpcomponents.version>4.3.6</apache.httpcomponents.version>
         <apache.httpcomponents.httpcore.version>4.3.3</apache.httpcomponents.httpcore.version>
         <resteasy.version>3.0.10.Final</resteasy.version>
+        <resteasy.version.latest>3.0.10.Final</resteasy.version.latest>
+        <joda-time.version>2.7</joda-time.version>
+        <keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version>
+        <!-- <undertow.version>1.1.0.Final</undertow.version> -->
         <undertow.version>1.1.1.Final</undertow.version>
         <picketlink.version>2.7.0.Final</picketlink.version>
         <mongo.driver.version>2.11.3</mongo.driver.version>
         <jboss.logging.version>3.1.4.GA</jboss.logging.version>
         <syslog4j.version>0.9.30</syslog4j.version>
         <jboss-logging-tools.version>1.2.0.Beta1</jboss-logging-tools.version>
+        <jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>1.0.4.Final</jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>
+        <io.netty.version>4.0.26.Final</io.netty.version> 
+        <xnio.netty.netty-xnio-transport.version>0.1.1.Final</xnio.netty.netty-xnio-transport.version>
         <hibernate.javax.persistence.version>1.0.1.Final</hibernate.javax.persistence.version>
         <hibernate.entitymanager.version>4.0.1.Final</hibernate.entitymanager.version>
         <h2.version>1.3.168</h2.version>
@@ -40,17 +48,22 @@
         <dom4j.version>1.6.1</dom4j.version>
         <xml-apis.version>1.4.01</xml-apis.version>
         <mysql.version>5.1.25</mysql.version>
-        <slf4j.version>1.5.10</slf4j.version>
+        <slf4j.version>1.7.7.jbossorg-1</slf4j.version>
+        <wildfly.version>9.0.0.CR1</wildfly.version>
+        <wildfly.core.version>1.0.0.CR1</wildfly.core.version>
+        <wildfly.build-tools.version>1.0.0.Alpha8</wildfly.build-tools.version>
         <jboss.version>7.1.1.Final</jboss.version>
-        <wildfly.version>8.2.0.Final</wildfly.version>
-        <wildfly.core.version>1.0.0.Alpha12</wildfly.core.version>
         <servlet.api.30.version>1.0.2.Final</servlet.api.30.version>
         <google.zxing.version>2.2</google.zxing.version>
         <google.client.version>1.14.1-beta</google.client.version>
+        <github.relaxng.version>2011.1</github.relaxng.version>
         <winzipaes.version>1.0.1</winzipaes.version>
         <freemarker.version>2.3.20</freemarker.version>
         <twitter4j.version>3.0.5</twitter4j.version>
         <selenium.version>2.35.0</selenium.version>
+        <sun.istack.version>2.21</sun.istack.version>
+        <sun.jaxb.version>2.2.11</sun.jaxb.version>
+        <sun.xsom.version>20140925</sun.xsom.version>
         <javax.mail.version>1.4.5</javax.mail.version>
         <infinispan.version>6.0.2.Final</infinispan.version>
         <liquibase.version>3.3.2</liquibase.version>
@@ -58,7 +71,7 @@
         <osgi.version>4.2.0</osgi.version>
         <pax.web.version>3.1.2</pax.web.version>
         <jmeter.version>2.10</jmeter.version>
-        <junit.version>4.11</junit.version>
+        <junit.version>4.12</junit.version>
         <hamcrest.version>1.3</hamcrest.version>
         <log4j.version>1.2.17</log4j.version>
         <greenmail.version>1.3.1b</greenmail.version>
@@ -141,13 +154,68 @@
     <dependencyManagement>
         <dependencies>
             <dependency>
+                <groupId>com.github.relaxng</groupId>
+                <artifactId>relaxngDatatype</artifactId>
+                <version>${github.relaxng.version}</version>
+            </dependency>
+        <dependency>
+            <groupId>com.sun.istack</groupId>
+            <artifactId>istack-commons-runtime</artifactId>
+            <version>${sun.istack.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.istack</groupId>
+            <artifactId>istack-commons-tools</artifactId>
+            <version>${sun.istack.version}</version>
+        </dependency>
+            <dependency>
+                <groupId>com.sun.xml.bind.external</groupId>
+                <artifactId>rngom</artifactId>
+                <version>${sun.jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.sun.xsom</groupId>
+                <artifactId>xsom</artifactId>
+                <version>${sun.xsom.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jaxb</groupId>
+                <artifactId>jaxb-core</artifactId>
+                <version>${sun.jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jaxb</groupId>
+                <artifactId>jaxb-runtime</artifactId>
+                <version>${sun.jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jaxb</groupId>
+                <artifactId>jaxb-xjc</artifactId>
+                <version>${sun.jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jaxb</groupId>
+                <artifactId>codemodel</artifactId>
+                <version>${sun.jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jaxb</groupId>
+                <artifactId>txw2</artifactId>
+                <version>${sun.jaxb.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>joda-time</groupId>
+                <artifactId>joda-time</artifactId>
+                <version>${joda-time.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcprov-jdk15on</artifactId>
                 <version>${bouncycastle.crypto.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.bouncycastle</groupId>
-			    <artifactId>bcpkix-jdk15on</artifactId>
+                <artifactId>bcpkix-jdk15on</artifactId>
                 <version>${bouncycastle.crypto.version}</version>
             </dependency>
             <dependency>
@@ -198,6 +266,31 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.jboss.spec.javax.xml.bind</groupId>
+                <artifactId>jboss-jaxb-api_2.2_spec</artifactId>
+                <version>${jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-all</artifactId>
+                <version>${io.netty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jboss.xnio.netty</groupId>
+                <artifactId>netty-xnio-transport</artifactId>
+                <version>${xnio.netty.netty-xnio-transport.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.keycloak</groupId>
+                <artifactId>keycloak-wildfly-adapter-subsystem</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.keycloak</groupId>
+                <artifactId>keycloak-undertow-adapter</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>io.undertow</groupId>
                 <artifactId>undertow-servlet</artifactId>
                 <version>${undertow.version}</version>
@@ -418,7 +511,12 @@
                 <version>${slf4j.version}</version>
                 <scope>test</scope>
             </dependency>
-
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>jcl-over-slf4j</artifactId>
+                <version>${slf4j.version}</version>
+            </dependency>
+            <!-- Needed for picketlink perf test -->
             <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
@@ -441,6 +539,28 @@
                <version>${apache.httpcomponents.httpcore.version}</version>
            </dependency>
             <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpmime</artifactId>
+                <version>${keycloak.apache.httpcomponents.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>commons-logging</groupId>
+                        <artifactId>commons-logging</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.james</groupId>
+                <artifactId>apache-mime4j</artifactId>
+                <version>${org.apache.james.apache-mime4j.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>commons-logging</groupId>
+                        <artifactId>commons-logging</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
                 <groupId>org.wildfly.core</groupId>
                 <artifactId>wildfly-controller</artifactId>
                 <version>${wildfly.core.version}</version>
@@ -456,6 +576,18 @@
                 <version>${wildfly.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.wildfly</groupId>
+                <artifactId>wildfly-feature-pack</artifactId>
+                <version>${wildfly.version}</version>
+                <type>zip</type>
+            </dependency>
+            <dependency>
+                <groupId>org.wildfly</groupId>
+                <artifactId>wildfly-web-feature-pack</artifactId>
+                <version>${wildfly.version}</version>
+                <type>zip</type>
+            </dependency>
+            <dependency>
                 <groupId>org.wildfly.core</groupId>
                 <artifactId>wildfly-subsystem-test</artifactId>
                 <version>${wildfly.core.version}</version>
@@ -463,6 +595,18 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.wildfly</groupId>
+                <artifactId>wildfly-undertow</artifactId>
+                <version>${wildfly.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.wildfly.core</groupId>
+                <artifactId>wildfly-subsystem-test-framework</artifactId>
+                <version>${wildfly.core.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
                 <groupId>org.wildfly.core</groupId>
                 <artifactId>wildfly-core-feature-pack</artifactId>
                 <type>pom</type>
@@ -481,7 +625,7 @@
             </dependency>
             <dependency>
                 <groupId>org.wildfly</groupId>
-                <artifactId>wildfly-undertow</artifactId>
+                <artifactId>wildfly-web-common</artifactId>
                 <version>${wildfly.version}</version>
             </dependency>
             <dependency>
@@ -1098,6 +1242,54 @@
                     <artifactId>liquibase-maven-plugin</artifactId>
                     <version>${liquibase.version}</version>
                 </plugin>
+                <!--plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>buildnumber-maven-plugin</artifactId>
+                    <version>1.3</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <version>2.3.7</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>build-helper-maven-plugin</artifactId>
+                    <version>1.7</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>2.6</version>
+                    <configuration>
+                        <encoding>${project.build.sourceEncoding}</encoding>
+                        <nonFilteredFileExtensions>
+                          <nonFilteredFileExtension>jar</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>war</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>ear</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>swf</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>zip</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>bz2</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>gz</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>acp</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>bin</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>odt</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>doc</nonFilteredFileExtension>
+                          <nonFilteredFileExtension>xls</nonFilteredFileExtension>
+                        </nonFilteredFileExtensions>
+                    </configuration>
+                </plugin-->
+                <plugin>
+                    <groupId>org.wildfly.build</groupId>
+                    <artifactId>wildfly-feature-pack-build-maven-plugin</artifactId>
+                    <version>${wildfly.build-tools.version}</version>
+                </plugin> 
+                <plugin>
+                    <groupId>org.wildfly.build</groupId>
+                    <artifactId>wildfly-server-provisioning-maven-plugin</artifactId>
+                    <version>${wildfly.build-tools.version}</version>
+                </plugin>                 
             </plugins>
         </pluginManagement>
     </build>
diff --git a/services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java b/services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java
index 6fe071e..e59a45a 100755
--- a/services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java
+++ b/services/src/main/java/org/keycloak/exportimport/ClientImportSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class ClientImportSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "client-import";
     }
diff --git a/services/src/main/java/org/keycloak/protocol/LoginProtocolSpi.java b/services/src/main/java/org/keycloak/protocol/LoginProtocolSpi.java
index ef73b34..6ac5496 100755
--- a/services/src/main/java/org/keycloak/protocol/LoginProtocolSpi.java
+++ b/services/src/main/java/org/keycloak/protocol/LoginProtocolSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class LoginProtocolSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "login-protocol";
     }
diff --git a/services/src/main/java/org/keycloak/protocol/ProtocolMapperSpi.java b/services/src/main/java/org/keycloak/protocol/ProtocolMapperSpi.java
index 421319e..1b98e07 100755
--- a/services/src/main/java/org/keycloak/protocol/ProtocolMapperSpi.java
+++ b/services/src/main/java/org/keycloak/protocol/ProtocolMapperSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class ProtocolMapperSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return false;
+    }
+
+    @Override
     public String getName() {
         return "protocol-mapper";
     }
diff --git a/services/src/main/java/org/keycloak/services/ErrorResponse.java b/services/src/main/java/org/keycloak/services/ErrorResponse.java
index e7539a1..5937e12 100755
--- a/services/src/main/java/org/keycloak/services/ErrorResponse.java
+++ b/services/src/main/java/org/keycloak/services/ErrorResponse.java
@@ -11,9 +11,7 @@ import javax.ws.rs.core.Response;
 public class ErrorResponse {
 
     public static Response exists(String message) {
-        ErrorRepresentation error = new ErrorRepresentation();
-        error.setErrorMessage(message);
-        return Response.status(Response.Status.CONFLICT).entity(error).type(MediaType.APPLICATION_JSON).build();
+        return ErrorResponse.error(message, Response.Status.CONFLICT);
     }
 
     public static Response error(String message, Response.Status status) {
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 88d9eb5..f2caef8 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -168,6 +168,9 @@ public class RealmManager {
         if(rep.getEnabledEventTypes() != null) {
             realm.setEnabledEventTypes(new HashSet<String>(rep.getEnabledEventTypes()));
         }
+        
+        realm.setAdminEventsEnabled(rep.isAdminEventsEnabled());
+        realm.setAdminEventsDetailsEnabled(rep.isAdminEventsDetailsEnabled());
     }
 
     // Should be RealmManager moved to model/api instead of referencing methods this way?
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java
new file mode 100644
index 0000000..a0c15f3
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java
@@ -0,0 +1,314 @@
+package org.keycloak.services.resources.admin;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jboss.logging.Logger;
+import org.keycloak.ClientConnection;
+import org.keycloak.broker.provider.IdentityProviderFactory;
+import org.keycloak.events.EventListenerProvider;
+import org.keycloak.events.EventStoreProvider;
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AuthDetails;
+import org.keycloak.events.admin.OperationType;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.IdentityProviderMapperModel;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.util.JsonSerialization;
+import org.keycloak.util.Time;
+
+public class AdminEventBuilder {
+    
+    private static final Logger log = Logger.getLogger(AdminEventBuilder.class);
+
+    private EventStoreProvider store;
+    private List<EventListenerProvider> listeners;
+    private RealmModel realm;
+    private AdminEvent adminEvent;
+
+    public AdminEventBuilder(RealmModel realm, AdminAuth auth, KeycloakSession session, ClientConnection clientConnection) {
+        this.realm = realm;
+        adminEvent = new AdminEvent();
+
+        if (realm.isAdminEventsEnabled()) {
+            EventStoreProvider store = session.getProvider(EventStoreProvider.class);
+            if (store != null) {
+                this.store = store;
+            } else {
+                log.error("Admin Events enabled, but no event store provider configured");
+            }
+        }
+
+        if (realm.getEventsListeners() != null && !realm.getEventsListeners().isEmpty()) {
+            this.listeners = new LinkedList<>();
+            for (String id : realm.getEventsListeners()) {
+                EventListenerProvider listener = session.getProvider(EventListenerProvider.class, id);
+                if (listener != null) {
+                    listeners.add(listener);
+                } else {
+                    log.error("Event listener '" + id + "' registered, but provider not found");
+                }
+            }
+        }
+
+        authRealm(auth.getRealm());
+        authClient(auth.getClient());
+        authUser(auth.getUser());
+        authIpAddress(clientConnection.getRemoteAddr());
+    }
+    
+    public AdminEventBuilder realm(RealmModel realm) {
+        adminEvent.setRealmId(realm.getId());
+        return this;
+    }
+    
+    public AdminEventBuilder realm(String realmId) {
+        adminEvent.setRealmId(realmId);
+        return this;
+    }
+    
+    public AdminEventBuilder operation(OperationType e) {
+        adminEvent.setOperationType(e);
+        return this;
+    }
+
+    public AdminEventBuilder authRealm(RealmModel realm) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setRealmId(realm.getId());
+        } else {
+            authDetails.setRealmId(realm.getId());
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+
+    public AdminEventBuilder authRealm(String realmId) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setRealmId(realmId);
+        } else {
+            authDetails.setRealmId(realmId);
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+
+    public AdminEventBuilder authClient(ClientModel client) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setClientId(client.getId());
+        } else {
+            authDetails.setClientId(client.getId());
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+
+    public AdminEventBuilder authClient(String clientId) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setClientId(clientId);
+        } else {
+            authDetails.setClientId(clientId);
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+
+    public AdminEventBuilder authUser(UserModel user) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setUserId(user.getId());
+        } else {
+            authDetails.setUserId(user.getId());
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+
+    public AdminEventBuilder authUser(String userId) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setUserId(userId);
+        } else {
+            authDetails.setUserId(userId);
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+
+    public AdminEventBuilder authIpAddress(String ipAddress) {
+        AuthDetails authDetails = adminEvent.getAuthDetails();
+        if(authDetails == null) {
+            authDetails =  new AuthDetails();
+            authDetails.setIpAddress(ipAddress);
+        } else {
+            authDetails.setIpAddress(ipAddress);
+        }
+        adminEvent.setAuthDetails(authDetails);
+        return this;
+    }
+    
+    public AdminEventBuilder resourcePath(String resourcePath) {
+        adminEvent.setResourcePath(resourcePath);
+        return this;
+    }
+    
+    public AdminEventBuilder resourcePath(String resourcePath, boolean segment) {
+        if(segment) {
+            int index = resourcePath.lastIndexOf('/');
+            int subIndex = resourcePath.lastIndexOf('/', index - 1);
+            adminEvent.setResourcePath(resourcePath.substring(subIndex));
+        } else {
+            adminEvent.setResourcePath(resourcePath.substring(resourcePath.lastIndexOf('/')));
+        }
+        return this;
+    }
+    
+    public AdminEventBuilder resourcePath(Object model) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getResourcePath(model));
+        adminEvent.setResourcePath(sb.toString());
+        return this;
+    }
+    
+    public AdminEventBuilder resourcePath(Object model, String resourcePath) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getResourcePath(model));
+        sb.append(resourcePath.substring(resourcePath.lastIndexOf('/')));
+        adminEvent.setResourcePath(sb.toString());
+        return this;
+    }
+    
+    public AdminEventBuilder resourcePath(Object model, String resourcePath, boolean segment) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getResourcePath(model));
+        int index = resourcePath.lastIndexOf('/');
+        int subIndex = resourcePath.lastIndexOf('/', index - 1);
+        sb.append(resourcePath.substring(subIndex));
+        adminEvent.setResourcePath(sb.toString());
+        return this;
+    }
+    
+    public AdminEventBuilder resourcePath(Object model, Object subModel, String resourcePath) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getResourcePath(model));
+        int index = resourcePath.lastIndexOf('/');
+        int subIndex = resourcePath.lastIndexOf('/', index - 1);
+        sb.append(resourcePath.substring(subIndex, index+1));
+        sb.append(getResourcePath(subModel));
+        adminEvent.setResourcePath(sb.toString());
+        return this;
+    }
+    
+
+    public void error(String error) {
+        adminEvent.setOperationType(OperationType.valueOf(adminEvent.getOperationType().name() + "_ERROR"));
+        adminEvent.setError(error);
+        send();
+    }
+    
+    public AdminEventBuilder representation(Object value) {
+        if (value == null || value.equals("")) {
+            return this;
+        }
+        try {
+            adminEvent.setRepresentation(JsonSerialization.writeValueAsString(value));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return this;
+    }
+    
+    public AdminEvent getEvent() {
+        return adminEvent;
+    }
+
+    public void success() {
+        send();
+    }
+
+    private void send() {
+        boolean includeRepresentation = false;
+        if(realm.isAdminEventsDetailsEnabled()) {
+            includeRepresentation = true;
+        }
+        adminEvent.setTime(Time.toMillis(Time.currentTime()));
+
+        if (store != null) {
+            try {
+                store.onEvent(adminEvent, includeRepresentation);
+            } catch (Throwable t) {
+                log.error("Failed to save event", t);
+            }
+        }
+        
+        if (listeners != null) {
+            for (EventListenerProvider l : listeners) {
+                try {
+                    l.onEvent(adminEvent, includeRepresentation);
+                } catch (Throwable t) {
+                    log.error("Failed to send type to " + l, t);
+                }
+            }
+        }
+    }
+    
+    private String getResourcePath(Object model) {
+
+        StringBuilder sb = new StringBuilder();
+
+        if (model instanceof RealmModel) {
+            RealmModel realm = (RealmModel) model;
+            sb.append("realms/" + realm.getId());
+        } else if (model instanceof ClientModel) {
+            ClientModel client = (ClientModel) model;
+            sb.append("clients/" + client.getId());
+        } else if (model instanceof UserModel) {
+            UserModel user = (UserModel) model;
+            sb.append("users/" + user.getId());
+
+        } else if (model instanceof IdentityProviderModel) {
+            IdentityProviderModel provider = (IdentityProviderModel) model;
+            sb.append("identity-Providers/" + provider.getProviderId());
+        } else if (model instanceof IdentityProviderRepresentation) {
+            IdentityProviderRepresentation provider = (IdentityProviderRepresentation) model;
+            sb.append("identity-Providers/" + provider.getProviderId());
+        } else if (model instanceof IdentityProviderMapperModel) {
+            IdentityProviderMapperModel provider = (IdentityProviderMapperModel) model;
+            sb.append("identity-Provider-Mappers/" + provider.getId());
+        } else if (model instanceof IdentityProviderFactory) {
+            IdentityProviderFactory provider = (IdentityProviderFactory) model;
+            sb.append("identity-Provider-Factory/" + provider.getId());
+
+        } else if (model instanceof ProtocolMapperModel) {
+            ProtocolMapperModel mapper = (ProtocolMapperModel) model;
+            sb.append("protocol-Mappers/" + mapper.getId());
+
+        } else if (model instanceof UserFederationProviderModel) {
+            UserFederationProviderModel provider = (UserFederationProviderModel) model;
+            sb.append("user-Federation-Providers/" + provider.getId());
+        
+        } else if (model instanceof RoleModel) {
+            RoleModel role = (RoleModel) model;
+            sb.append("roles/" + role.getId());
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index 34e8272..55861d0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -29,6 +29,7 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
+
 import java.io.IOException;
 
 /**
@@ -185,7 +186,7 @@ public class AdminRoot {
         }
 
         Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
-
+        
         RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager);
         ResteasyProviderFactory.getInstance().injectProperties(adminResource);
         return adminResource;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
index 16a0fbe..3b91e3e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java
@@ -6,6 +6,7 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
 import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.NotAcceptableException;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -21,6 +22,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriInfo;
+
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -47,11 +49,12 @@ public class ClientAttributeCertificateResource {
     private RealmAuth auth;
     protected ClientModel client;
     protected KeycloakSession session;
+    protected AdminEventBuilder adminEvent;
     protected String attributePrefix;
     protected String privateAttribute;
     protected String certificateAttribute;
 
-    public ClientAttributeCertificateResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, String attributePrefix) {
+    public ClientAttributeCertificateResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, String attributePrefix, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.client = client;
@@ -59,6 +62,7 @@ public class ClientAttributeCertificateResource {
         this.attributePrefix = attributePrefix;
         this.privateAttribute = attributePrefix + "." + PRIVATE_KEY;
         this.certificateAttribute = attributePrefix + "." + X509CERTIFICATE;
+        this.adminEvent = adminEvent;
     }
 
     public static class ClientKeyPairInfo {
@@ -129,11 +133,14 @@ public class ClientAttributeCertificateResource {
         client.setAttribute(privateAttribute, privateKeyPem);
         client.setAttribute(certificateAttribute, certPem);
 
-
         KeycloakModelUtils.generateClientKeyPairCertificate(client);
         ClientKeyPairInfo info = new ClientKeyPairInfo();
         info.setCertificate(client.getAttribute(certificateAttribute));
         info.setPrivateKey(client.getAttribute(privateAttribute));
+        
+        adminEvent.operation(OperationType.ACTION)
+        .resourcePath(client, session.getContext().getUri().getPath()).representation(info).success();
+        
         return info;
     }
 
@@ -190,7 +197,8 @@ public class ClientAttributeCertificateResource {
             client.setAttribute(certificateAttribute, certPem);
             info.setCertificate(certPem);
         }
-
+        
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).representation(info).success();
         return info;
     }
 
@@ -316,6 +324,10 @@ public class ClientAttributeCertificateResource {
             stream.flush();
             stream.close();
             byte[] rtn = stream.toByteArray();
+            
+            adminEvent.operation(OperationType.ACTION)
+            .resourcePath(client, session.getContext().getUri().getPath()).success();
+            
             return rtn;
         } catch (Exception e) {
             throw new RuntimeException(e);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
index f769101..d9ab8dc 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
@@ -5,6 +5,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
@@ -40,6 +41,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -57,6 +59,7 @@ public class ClientResource {
     protected static final Logger logger = Logger.getLogger(ClientResource.class);
     protected RealmModel realm;
     private RealmAuth auth;
+    private AdminEventBuilder adminEvent;
     protected ClientModel client;
     protected KeycloakSession session;
     
@@ -70,18 +73,19 @@ public class ClientResource {
         return keycloak;
     }
 
-    public ClientResource(RealmModel realm, RealmAuth auth, ClientModel clientModel, KeycloakSession session) {
+    public ClientResource(RealmModel realm, RealmAuth auth, ClientModel clientModel, KeycloakSession session, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.client = clientModel;
         this.session = session;
+        this.adminEvent = adminEvent;
 
         auth.init(RealmAuth.Resource.CLIENT);
     }
 
     @Path("protocol-mappers")
     public ProtocolMappersResource getProtocolMappers() {
-        ProtocolMappersResource mappers = new ProtocolMappersResource(client, auth);
+        ProtocolMappersResource mappers = new ProtocolMappersResource(client, auth, adminEvent);
         ResteasyProviderFactory.getInstance().injectProperties(mappers);
         return mappers;
     }
@@ -98,6 +102,7 @@ public class ClientResource {
 
         try {
             RepresentationToModel.updateClient(rep, client);
+            adminEvent.operation(OperationType.UPDATE).resourcePath(client).representation(rep).success();
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
@@ -115,7 +120,6 @@ public class ClientResource {
     @Produces(MediaType.APPLICATION_JSON)
     public ClientRepresentation getClient() {
         auth.requireView();
-
         return ModelToRepresentation.toRepresentation(client);
     }
 
@@ -126,7 +130,7 @@ public class ClientResource {
      */
     @Path("certificates/{attr}")
     public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix) {
-        return new ClientAttributeCertificateResource(realm, auth, client, session, attributePrefix);
+        return new ClientAttributeCertificateResource(realm, auth, client, session, attributePrefix, adminEvent);
     }
 
 
@@ -145,6 +149,8 @@ public class ClientResource {
 
         ClientManager clientManager = new ClientManager(new RealmManager(session));
         Object rep = clientManager.toInstallationRepresentation(realm, client, getKeycloakApplication().getBaseUri(uriInfo));
+        
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath(), true).success();
 
         // TODO Temporary solution to pretty-print
         return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep);
@@ -164,6 +170,9 @@ public class ClientResource {
         auth.requireView();
 
         ClientManager clientManager = new ClientManager(new RealmManager(session));
+
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath(), true).success();
+
         return clientManager.toJBossSubsystemConfig(realm, client, getKeycloakApplication().getBaseUri(uriInfo));
     }
 
@@ -176,6 +185,7 @@ public class ClientResource {
     public void deleteClient() {
         auth.requireManage();
         new ClientManager(new RealmManager(session)).removeClient(realm, client);
+        adminEvent.operation(OperationType.DELETE).resourcePath(client).success();
     }
 
 
@@ -194,6 +204,7 @@ public class ClientResource {
         logger.debug("regenerateSecret");
         UserCredentialModel cred = KeycloakModelUtils.generateSecret(client);
         CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred);
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).representation(rep).success();
         return rep;
     }
 
@@ -222,12 +233,12 @@ public class ClientResource {
      */
     @Path("scope-mappings")
     public ScopeMappedResource getScopeMappedResource() {
-        return new ScopeMappedResource(realm, auth, client, session);
+        return new ScopeMappedResource(realm, auth, client, session, adminEvent);
     }
 
     @Path("roles")
     public RoleContainerResource getRoleContainerResource() {
-        return new RoleContainerResource(realm, auth, client);
+        return new RoleContainerResource(realm, auth, client, adminEvent);
     }
 
     /**
@@ -243,7 +254,6 @@ public class ClientResource {
     public Set<String> getAllowedOrigins()
     {
         auth.requireView();
-
         return client.getWebOrigins();
     }
 
@@ -261,6 +271,7 @@ public class ClientResource {
         auth.requireManage();
 
         client.setWebOrigins(allowedOrigins);
+        adminEvent.operation(OperationType.UPDATE).resourcePath(client, uriInfo.getPath()).representation(client).success();
     }
 
     /**
@@ -279,6 +290,7 @@ public class ClientResource {
         for (String origin : allowedOrigins) {
             client.removeWebOrigin(origin);
         }
+        adminEvent.operation(OperationType.DELETE).resourcePath(client, uriInfo.getPath()).success();
     }
 
     /**
@@ -289,9 +301,11 @@ public class ClientResource {
     @POST
     public GlobalRequestResult pushRevocation() {
         auth.requireManage();
-        return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client);
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success();
+        return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client);
+    
     }
-
+    
     /**
      * Number of user sessions associated with this client
      *
@@ -341,7 +355,9 @@ public class ClientResource {
     @POST
     public GlobalRequestResult logoutAll() {
         auth.requireManage();
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success();
         return new ResourceAdminManager(session).logoutClient(uriInfo.getRequestUri(), realm, client);
+
     }
 
     /**
@@ -356,7 +372,9 @@ public class ClientResource {
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-        new ResourceAdminManager(session).logoutUserFromClient(uriInfo.getRequestUri(), realm, client, user);
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath(), true).success();
+        new ResourceAdminManager(session).logoutUserFromClient(uriInfo.getRequestUri(), realm, client, user);
+
     }
 
     /**
@@ -376,6 +394,7 @@ public class ClientResource {
         }
         if (logger.isDebugEnabled()) logger.debug("Register node: " + node);
         client.registerNode(node, Time.currentTime());
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success();
     }
 
     /**
@@ -394,8 +413,8 @@ public class ClientResource {
         if (time == null) {
             throw new NotFoundException("Client does not have a node " + node);
         }
-
         client.unregisterNode(node);
+        adminEvent.operation(OperationType.DELETE).resourcePath(client, uriInfo.getPath(), true).success();
     }
 
     /**
@@ -408,9 +427,10 @@ public class ClientResource {
     @NoCache
     public GlobalRequestResult testNodesAvailable() {
         auth.requireManage();
-        logger.debug("Test availability of cluster nodes");
-
+        logger.debug("Test availability of cluster nodes");
+        adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success();
         return new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client);
+
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java
index 46f2f87..3b273e0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java
@@ -8,8 +8,8 @@ import org.keycloak.models.RealmModel;
  * @version $Revision: 1 $
  */
 public class ClientsByIdResource extends ClientsResource {
-    public ClientsByIdResource(RealmModel realm, RealmAuth auth) {
-        super(realm, auth);
+    public ClientsByIdResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
+        super(realm, auth, adminEvent);
     }
 
     @Override
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
index f6df036..51c509f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
@@ -4,6 +4,7 @@ import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
@@ -23,6 +24,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,13 +38,15 @@ public class ClientsResource {
     protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
     protected RealmModel realm;
     private RealmAuth auth;
-
+    private AdminEventBuilder adminEvent;
+    
     @Context
     protected KeycloakSession session;
 
-    public ClientsResource(RealmModel realm, RealmAuth auth) {
+    public ClientsResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
+        this.adminEvent = adminEvent;
         
         auth.init(RealmAuth.Resource.CLIENT);
     }
@@ -72,7 +76,6 @@ public class ClientsResource {
                 rep.add(client);
             }
         }
-
         return rep;
     }
 
@@ -90,6 +93,9 @@ public class ClientsResource {
 
         try {
             ClientModel clientModel = RepresentationToModel.createClient(session, realm, rep, true);
+            
+            adminEvent.operation(OperationType.CREATE).resourcePath(clientModel).representation(rep).success();
+            
             return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(clientModel)).build()).build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
@@ -112,7 +118,7 @@ public class ClientsResource {
         if (clientModel == null) {
             throw new NotFoundException("Could not find client: " + name);
         }
-        ClientResource clientResource = new ClientResource(realm, auth, clientModel, session);
+        ClientResource clientResource = new ClientResource(realm, auth, clientModel, session, adminEvent);
         ResteasyProviderFactory.getInstance().injectProperties(clientResource);
         return clientResource;
     }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
index 539c410..9b058a5 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java
@@ -6,6 +6,7 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.broker.provider.IdentityProvider;
 import org.keycloak.broker.provider.IdentityProviderFactory;
 import org.keycloak.broker.provider.IdentityProviderMapper;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.FederatedIdentityModel;
 import org.keycloak.models.IdentityProviderMapperModel;
@@ -13,7 +14,6 @@ import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.ModelToRepresentation;
@@ -25,7 +25,6 @@ import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
 import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation;
 import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.ErrorResponse;
-import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.social.SocialIdentityProvider;
 
 import javax.ws.rs.Consumes;
@@ -41,6 +40,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -58,14 +58,16 @@ public class IdentityProviderResource {
     private final RealmModel realm;
     private final KeycloakSession session;
     private final IdentityProviderModel identityProviderModel;
-
+    private final AdminEventBuilder adminEvent;
+    
     @Context private UriInfo uriInfo;
 
-    public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel) {
+    public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.session = session;
         this.identityProviderModel = identityProviderModel;
         this.auth = auth;
+        this.adminEvent = adminEvent;
     }
 
     @GET
@@ -74,7 +76,6 @@ public class IdentityProviderResource {
     public IdentityProviderRepresentation getIdentityProvider() {
         this.auth.requireView();
         IdentityProviderRepresentation rep = ModelToRepresentation.toRepresentation(this.identityProviderModel);
-
         return rep;
     }
 
@@ -84,7 +85,9 @@ public class IdentityProviderResource {
         this.auth.requireManage();
 
         this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias());
-
+        
+        adminEvent.operation(OperationType.DELETE).resourcePath(identityProviderModel).success();
+        
         return Response.noContent().build();
     }
 
@@ -108,7 +111,9 @@ public class IdentityProviderResource {
 
                 updateUsersAfterProviderAliasChange(this.session.users().getUsers(this.realm), oldProviderId, newProviderId);
             }
-
+            
+            adminEvent.operation(OperationType.UPDATE).resourcePath(providerRep).representation(providerRep).success();
+            
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("Identity Provider " + providerRep.getAlias() + " already exists");
@@ -164,6 +169,7 @@ public class IdentityProviderResource {
         try {
             this.auth.requireView();
             IdentityProviderFactory factory = getIdentityProviderFactory();
+            adminEvent.operation(OperationType.ACTION).resourcePath(identityProviderModel, uriInfo.getPath()).success();
             return factory.create(identityProviderModel).export(uriInfo, realm, format);
         } catch (Exception e) {
             return ErrorResponse.error("Could not export public broker configuration for identity provider [" + identityProviderModel.getProviderId() + "].", Response.Status.NOT_FOUND);
@@ -225,6 +231,10 @@ public class IdentityProviderResource {
         auth.requireManage();
         IdentityProviderMapperModel model = RepresentationToModel.toModel(mapper);
         model = realm.addIdentityProviderMapper(model);
+        
+        adminEvent.operation(OperationType.CREATE).resourcePath(model, uriInfo.getPath())
+            .representation(mapper).success();
+        
         return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
 
     }
@@ -250,6 +260,8 @@ public class IdentityProviderResource {
         if (model == null) throw new NotFoundException("Model not found");
         model = RepresentationToModel.toModel(rep);
         realm.updateIdentityProviderMapper(model);
+        adminEvent.operation(OperationType.UPDATE).resourcePath(model).representation(rep).success();
+
     }
 
     @DELETE
@@ -260,6 +272,8 @@ public class IdentityProviderResource {
         IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id);
         if (model == null) throw new NotFoundException("Model not found");
         realm.removeIdentityProviderMapper(model);
+        adminEvent.operation(OperationType.DELETE).resourcePath(model).success();
+
     }
 
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
index ecedae7..3617631 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java
@@ -1,183 +1,191 @@
-package org.keycloak.services.resources.admin;
-
-import org.jboss.resteasy.annotations.cache.NoCache;
-import org.jboss.resteasy.plugins.providers.multipart.InputPart;
-import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
-import org.jboss.resteasy.spi.NotFoundException;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.keycloak.broker.provider.IdentityProvider;
-import org.keycloak.broker.provider.IdentityProviderFactory;
-import org.keycloak.connections.httpclient.HttpClientProvider;
-import org.keycloak.models.IdentityProviderModel;
-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.provider.ProviderFactory;
-import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.services.ErrorResponse;
-import org.keycloak.social.SocialIdentityProvider;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
-
-/**
- * @author Pedro Igor
- */
-public class IdentityProvidersResource {
-
-    private final RealmModel realm;
-    private final KeycloakSession session;
-    private RealmAuth auth;
-
-    public IdentityProvidersResource(RealmModel realm, KeycloakSession session, RealmAuth auth) {
-        this.realm = realm;
-        this.session = session;
-        this.auth = auth;
-        this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER);
-    }
-
-    @Path("/providers/{provider_id}")
-    @GET
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getIdentityProviders(@PathParam("provider_id") String providerId) {
-        this.auth.requireView();
-        IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
-
-        if (providerFactory != null) {
-            return Response.ok(providerFactory).build();
-        }
-
-        return Response.status(BAD_REQUEST).build();
-    }
-
-    @POST
-    @Path("import-config")
-    @Consumes(MediaType.MULTIPART_FORM_DATA)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Map<String, String> importFrom(@Context UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
-        this.auth.requireManage();
-        Map<String, List<InputPart>> formDataMap = input.getFormDataMap();
-        String providerId = formDataMap.get("providerId").get(0).getBodyAsString();
-        InputPart file = formDataMap.get("file").get(0);
-        InputStream inputStream = file.getBody(InputStream.class, null);
-        IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
-        Map<String, String> config = providerFactory.parseConfig(inputStream);
-        return config;
-    }
-
-    @POST
-    @Path("import-config")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Map<String, String> importFrom(@Context UriInfo uriInfo, Map<String, Object> data) throws IOException {
-        this.auth.requireManage();
-
-        String providerId = data.get("providerId").toString();
-        String from = data.get("fromUrl").toString();
-        InputStream inputStream = session.getProvider(HttpClientProvider.class).get(from);
-        try {
-            IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
-            Map<String, String> config;
-            config = providerFactory.parseConfig(inputStream);
-            return config;
-        } finally {
-            try {
-                inputStream.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    @GET
-    @Path("instances")
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    public List<IdentityProviderRepresentation> getIdentityProviders() {
-        this.auth.requireView();
-
-        List<IdentityProviderRepresentation> representations = new ArrayList<IdentityProviderRepresentation>();
-
-        for (IdentityProviderModel identityProviderModel : realm.getIdentityProviders()) {
-            representations.add(ModelToRepresentation.toRepresentation(identityProviderModel));
-        }
-
-        return representations;
-    }
-
-    @POST
-    @Path("instances")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response create(@Context UriInfo uriInfo, IdentityProviderRepresentation representation) {
-        this.auth.requireManage();
-
-        try {
-            IdentityProviderModel identityProvider = RepresentationToModel.toModel(representation);
-            this.realm.addIdentityProvider(identityProvider);
-
-            return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
-        } catch (ModelDuplicateException e) {
-            return ErrorResponse.exists("Identity Provider " + representation.getAlias() + " already exists");
-        }
-    }
-
-    @Path("instances/{alias}")
-    public IdentityProviderResource getIdentityProvider(@PathParam("alias") String alias) {
-        this.auth.requireView();
-        IdentityProviderModel identityProviderModel = null;
-
-        for (IdentityProviderModel storedIdentityProvider : this.realm.getIdentityProviders()) {
-            if (storedIdentityProvider.getAlias().equals(alias)
-                    || storedIdentityProvider.getInternalId().equals(alias)) {
-                identityProviderModel = storedIdentityProvider;
-            }
-        }
-
-        if (identityProviderModel == null) {
-            throw new NotFoundException("Could not find identity provider: " + alias);
-        }
-
-        IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel);
-        ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource);
-
-        return identityProviderResource;
-    }
-
-    private IdentityProviderFactory getProviderFactorytById(String providerId) {
-        List<ProviderFactory> allProviders = getProviderFactories();
-
-        for (ProviderFactory providerFactory : allProviders) {
-            if (providerFactory.getId().equals(providerId)) {
-                return (IdentityProviderFactory) providerFactory;
-            }
-        }
-
-        return null;
-    }
-
-    private List<ProviderFactory> getProviderFactories() {
-        List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
-
-        allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
-        allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
-
-        return allProviders;
-    }
+package org.keycloak.services.resources.admin;
+
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.plugins.providers.multipart.InputPart;
+import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.broker.provider.IdentityProvider;
+import org.keycloak.broker.provider.IdentityProviderFactory;
+import org.keycloak.connections.httpclient.HttpClientProvider;
+import org.keycloak.events.admin.OperationType;
+import org.keycloak.models.IdentityProviderModel;
+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.provider.ProviderFactory;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.services.ErrorResponse;
+import org.keycloak.social.SocialIdentityProvider;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+
+/**
+ * @author Pedro Igor
+ */
+public class IdentityProvidersResource {
+
+    private final RealmModel realm;
+    private final KeycloakSession session;
+    private RealmAuth auth;
+    private AdminEventBuilder adminEvent;
+
+    public IdentityProvidersResource(RealmModel realm, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
+        this.realm = realm;
+        this.session = session;
+        this.auth = auth;
+        this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER);
+        this.adminEvent = adminEvent;
+    }
+
+    @Path("/providers/{provider_id}")
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getIdentityProviders(@PathParam("provider_id") String providerId) {
+        this.auth.requireView();
+        IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
+        if (providerFactory != null) {
+            return Response.ok(providerFactory).build();
+        }
+        return Response.status(BAD_REQUEST).build();
+    }
+
+    @POST
+    @Path("import-config")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Map<String, String> importFrom(@Context UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
+        this.auth.requireManage();
+        Map<String, List<InputPart>> formDataMap = input.getFormDataMap();
+        String providerId = formDataMap.get("providerId").get(0).getBodyAsString();
+        InputPart file = formDataMap.get("file").get(0);
+        InputStream inputStream = file.getBody(InputStream.class, null);
+        IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
+        Map<String, String> config = providerFactory.parseConfig(inputStream);
+        
+        adminEvent.operation(OperationType.CREATE).resourcePath(providerFactory, uriInfo.getPath()).representation(config).success();
+
+        return config;
+    }
+
+    @POST
+    @Path("import-config")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Map<String, String> importFrom(@Context UriInfo uriInfo, Map<String, Object> data) throws IOException {
+        this.auth.requireManage();
+
+        String providerId = data.get("providerId").toString();
+        String from = data.get("fromUrl").toString();
+        InputStream inputStream = session.getProvider(HttpClientProvider.class).get(from);
+        try {
+            IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
+            Map<String, String> config;
+            config = providerFactory.parseConfig(inputStream);
+            adminEvent.operation(OperationType.CREATE).resourcePath(providerFactory, uriInfo.getPath()).representation(config).success();
+            return config;
+        } finally {
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    @GET
+    @Path("instances")
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<IdentityProviderRepresentation> getIdentityProviders() {
+        this.auth.requireView();
+
+        List<IdentityProviderRepresentation> representations = new ArrayList<IdentityProviderRepresentation>();
+
+        for (IdentityProviderModel identityProviderModel : realm.getIdentityProviders()) {
+            representations.add(ModelToRepresentation.toRepresentation(identityProviderModel));
+        }
+        return representations;
+    }
+
+    @POST
+    @Path("instances")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response create(@Context UriInfo uriInfo, IdentityProviderRepresentation representation) {
+        this.auth.requireManage();
+
+        try {
+            IdentityProviderModel identityProvider = RepresentationToModel.toModel(representation);
+            this.realm.addIdentityProvider(identityProvider);
+
+            adminEvent.operation(OperationType.CREATE).resourcePath(identityProvider)
+                    .representation(representation).success();
+            
+            return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
+        } catch (ModelDuplicateException e) {
+            return ErrorResponse.exists("Identity Provider " + representation.getAlias() + " already exists");
+        }
+    }
+
+    @Path("instances/{alias}")
+    public IdentityProviderResource getIdentityProvider(@PathParam("alias") String alias) {
+        this.auth.requireView();
+        IdentityProviderModel identityProviderModel = null;
+
+        for (IdentityProviderModel storedIdentityProvider : this.realm.getIdentityProviders()) {
+            if (storedIdentityProvider.getAlias().equals(alias)
+                    || storedIdentityProvider.getInternalId().equals(alias)) {
+                identityProviderModel = storedIdentityProvider;
+            }
+        }
+
+        if (identityProviderModel == null) {
+            throw new NotFoundException("Could not find identity provider: " + alias);
+        }
+
+        IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel, adminEvent);
+        ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource);
+        
+        return identityProviderResource;
+    }
+
+    private IdentityProviderFactory getProviderFactorytById(String providerId) {
+        List<ProviderFactory> allProviders = getProviderFactories();
+
+        for (ProviderFactory providerFactory : allProviders) {
+            if (providerFactory.getId().equals(providerId)) {
+                return (IdentityProviderFactory) providerFactory;
+            }
+        }
+
+        return null;
+    }
+
+    private List<ProviderFactory> getProviderFactories() {
+        List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
+
+        allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
+        allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
+
+        return allProviders;
+    }
 }
\ No newline at end of file
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
index 36428b8..1f59b68 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java
@@ -3,9 +3,11 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
@@ -22,6 +24,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -33,10 +36,12 @@ import java.util.List;
  */
 public class ProtocolMappersResource {
     protected static final Logger logger = Logger.getLogger(ProtocolMappersResource.class);
-
+    
     protected ClientModel client;
 
     protected  RealmAuth auth;
+    
+    protected AdminEventBuilder adminEvent;
 
     @Context
     protected UriInfo uriInfo;
@@ -44,9 +49,10 @@ public class ProtocolMappersResource {
     @Context
     protected KeycloakSession session;
 
-    public ProtocolMappersResource(ClientModel client, RealmAuth auth) {
+    public ProtocolMappersResource(ClientModel client, RealmAuth auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.client = client;
+        this.adminEvent = adminEvent;
 
         auth.init(RealmAuth.Resource.USER);
     }
@@ -83,6 +89,7 @@ public class ProtocolMappersResource {
         auth.requireManage();
         ProtocolMapperModel model = RepresentationToModel.toModel(rep);
         model = client.addProtocolMapper(model);
+        adminEvent.operation(OperationType.CREATE).resourcePath(model).representation(rep).success();
         return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
     }
     /**
@@ -95,10 +102,12 @@ public class ProtocolMappersResource {
     @Consumes(MediaType.APPLICATION_JSON)
     public void createMapper(List<ProtocolMapperRepresentation> reps) {
         auth.requireManage();
+        ProtocolMapperModel model = null;
         for (ProtocolMapperRepresentation rep : reps) {
-            ProtocolMapperModel model = RepresentationToModel.toModel(rep);
+            model = RepresentationToModel.toModel(rep);
             model = client.addProtocolMapper(model);
         }
+        adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getPath(), false).representation(reps).success();
     }
 
     @GET
@@ -135,6 +144,7 @@ public class ProtocolMappersResource {
         if (model == null) throw new NotFoundException("Model not found");
         model = RepresentationToModel.toModel(rep);
         client.updateProtocolMapper(model);
+        adminEvent.operation(OperationType.UPDATE).resourcePath(model).representation(rep).success();
     }
 
     @DELETE
@@ -145,6 +155,8 @@ public class ProtocolMappersResource {
         ProtocolMapperModel model = client.getProtocolMapperById(id);
         if (model == null) throw new NotFoundException("Model not found");
         client.removeProtocolMapper(model);
+        adminEvent.operation(OperationType.DELETE).resourcePath(model).success();
+
     }
 
 }
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 b0d171b..9f2a12f 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
@@ -1,451 +1,554 @@
-package org.keycloak.services.resources.admin;
-
-import org.jboss.logging.Logger;
-import org.jboss.resteasy.annotations.cache.NoCache;
-import org.jboss.resteasy.spi.NotFoundException;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.keycloak.ClientConnection;
-import org.keycloak.events.Event;
-import org.keycloak.events.EventQuery;
-import org.keycloak.events.EventStoreProvider;
-import org.keycloak.events.EventType;
-import org.keycloak.exportimport.ClientImporter;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelDuplicateException;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserFederationProviderModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.cache.CacheRealmProvider;
-import org.keycloak.models.cache.CacheUserProvider;
-import org.keycloak.models.utils.ModelToRepresentation;
-import org.keycloak.models.utils.RepresentationToModel;
-import org.keycloak.protocol.oidc.TokenManager;
-import org.keycloak.representations.adapters.action.GlobalRequestResult;
-import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.AuthenticationManager;
-import org.keycloak.services.managers.LDAPConnectionTestManager;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.managers.ResourceAdminManager;
-import org.keycloak.services.managers.UsersSyncManager;
-import org.keycloak.services.ErrorResponse;
-import org.keycloak.timer.TimerProvider;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * Base resource class for the admin REST api of one realm
- *
- * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
- * @version $Revision: 1 $
- */
-public class RealmAdminResource {
-    protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
-    protected RealmAuth auth;
-    protected RealmModel realm;
-    private TokenManager tokenManager;
-
-    @Context
-    protected KeycloakSession session;
-
-    @Context
-    protected UriInfo uriInfo;
-
-    @Context
-    protected ClientConnection connection;
-
-    @Context
-    protected HttpHeaders headers;
-
-    public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager) {
-        this.auth = auth;
-        this.realm = realm;
-        this.tokenManager = tokenManager;
-
-        auth.init(RealmAuth.Resource.REALM);
-    }
-
-    /**
-     * Base path for importing clients under this realm.
-     *
-     * @return
-     */
-    @Path("client-importers/{formatId}")
-    public Object getClientImporter(@PathParam("formatId") String formatId) {
-        ClientImporter importer = session.getProvider(ClientImporter.class, formatId);
-        return importer.createJaxrsService(realm, auth);
-    }
-
-    /**
-     * Base path for managing clients under this realm.
-     *
-     * @return
-     */
-    @Path("clients")
-    public ClientsResource getClients() {
-        ClientsResource clientsResource = new ClientsResource(realm, auth);
-        ResteasyProviderFactory.getInstance().injectProperties(clientsResource);
-        return clientsResource;
-    }
-
-    /**
-     * Base path for managing clients under this realm.
-     *
-     * @return
-     */
-    @Path("clients-by-id")
-    public ClientsByIdResource getClientsById() {
-        ClientsByIdResource clientsResource = new ClientsByIdResource(realm, auth);
-        ResteasyProviderFactory.getInstance().injectProperties(clientsResource);
-        return clientsResource;
-    }
-
-    /**
-     * base path for managing realm-level roles of this realm
-     *
-     * @return
-     */
-    @Path("roles")
-    public RoleContainerResource getRoleContainerResource() {
-        return new RoleContainerResource(realm, auth, realm);
-    }
-
-    /**
-     * Get the top-level representation of the realm.  It will not include nested information like User and Client representations.
-     *
-     * @return
-     */
-    @GET
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    public RealmRepresentation getRealm() {
-        if (auth.hasView()) {
-            RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false);
-            if (session.realms() instanceof CacheRealmProvider) {
-                CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
-                rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled());
-            }
-            if (session.userStorage() instanceof CacheUserProvider) {
-                CacheUserProvider cache = (CacheUserProvider)session.userStorage();
-                rep.setUserCacheEnabled(cache.isEnabled());
-            }
-            return rep;
-        } else {
-            auth.requireAny();
-
-            RealmRepresentation rep = new RealmRepresentation();
-            rep.setRealm(realm.getName());
-            return rep;
-        }
-    }
-
-    /**
-     * Update the top-level information of this realm.  Any user, roles or client information in the representation
-     * will be ignored.  This will only update top-level attributes of the realm.
-     *
-     * @param rep
-     * @return
-     */
-    @PUT
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response updateRealm(final RealmRepresentation rep) {
-        auth.requireManage();
-
-        logger.debug("updating realm: " + realm.getName());
-        try {
-            RepresentationToModel.updateRealm(rep, realm);
-            if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) {
-                CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
-                cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled());
-            }
-            if (rep.isUserCacheEnabled() != null && session.userStorage() instanceof CacheUserProvider) {
-                CacheUserProvider cache = (CacheUserProvider)session.userStorage();
-                cache.setEnabled(rep.isUserCacheEnabled());
-            }
-
-            // Refresh periodic sync tasks for configured federationProviders
-            List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
-            UsersSyncManager usersSyncManager = new UsersSyncManager();
-            for (final UserFederationProviderModel fedProvider : federationProviders) {
-                usersSyncManager.refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId());
-            }
-
-            return Response.noContent().build();
-        } catch (PatternSyntaxException e) {
-            return ErrorResponse.exists("Specified regex pattern(s) is invalid.");
-        } catch (ModelDuplicateException e) {
-            return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists.");
-        }  catch (Exception e) {
-            return ErrorResponse.exists("Failed to update " + rep.getRealm() + " Realm.");
-        }
-    }
-
-    /**
-     * Delete this realm.
-     *
-     */
-    @DELETE
-    public void deleteRealm() {
-        auth.requireManage();
-
-        if (!new RealmManager(session).removeRealm(realm)) {
-            throw new NotFoundException("Realm doesn't exist");
-        }
-    }
-
-    /**
-     * Base path for managing users in this realm.
-     *
-     * @return
-     */
-    @Path("users")
-    public UsersResource users() {
-        UsersResource users = new UsersResource(realm, auth, tokenManager);
-        ResteasyProviderFactory.getInstance().injectProperties(users);
-        //resourceContext.initResource(users);
-        return users;
-    }
-
-    @Path("user-federation")
-    public UserFederationResource userFederation() {
-        UserFederationResource fed = new UserFederationResource(realm, auth);
-        ResteasyProviderFactory.getInstance().injectProperties(fed);
-        //resourceContext.initResource(fed);
-        return fed;
-    }
-
-    /**
-     * Path for managing all realm-level or client-level roles defined in this realm by it's id.
-     *
-     * @return
-     */
-    @Path("roles-by-id")
-    public RoleByIdResource rolesById() {
-        RoleByIdResource resource = new RoleByIdResource(realm, auth);
-        ResteasyProviderFactory.getInstance().injectProperties(resource);
-        //resourceContext.initResource(resource);
-        return resource;
-    }
-
-    /**
-     * Push the realm's revocation policy to any client that has an admin url associated with it.
-     *
-     */
-    @Path("push-revocation")
-    @POST
-    public GlobalRequestResult pushRevocation() {
-        auth.requireManage();
-        return new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
-    }
-
-    /**
-     * Removes all user sessions.  Any client that has an admin url will also be told to invalidate any sessions
-     * they have.
-     *
-     */
-    @Path("logout-all")
-    @POST
-    public GlobalRequestResult logoutAll() {
-        session.sessions().removeUserSessions(realm);
-        return new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm);
-    }
-
-    /**
-     * Remove a specific user session. Any client that has an admin url will also be told to invalidate this
-     * particular session.
-     *
-     * @param sessionId
-     */
-    @Path("sessions/{session}")
-    @DELETE
-    public void deleteSession(@PathParam("session") String sessionId) {
-        UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
-        if (userSession == null) throw new NotFoundException("Sesssion not found");
-        AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true);
-    }
-
-    /**
-     * Returns a JSON map.  The key is the client name, the value is the number of sessions that currently are active
-     * with that client.  Only client's that actually have a session associated with them will be in this map.
-     *
-     * @return
-     */
-    @Path("client-session-stats")
-    @GET
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    @Deprecated
-    public Map<String, Integer> getClientSessionStats() {
-        auth.requireView();
-        Map<String, Integer> stats = new HashMap<String, Integer>();
-        for (ClientModel client : realm.getClients()) {
-            int size = session.sessions().getActiveUserSessions(client.getRealm(), client);
-            if (size == 0) continue;
-            stats.put(client.getClientId(), size);
-        }
-        return stats;
-    }
-
-    /**
-     * Returns a JSON map.  The key is the client id, the value is the number of sessions that currently are active
-     * with that client.  Only client's that actually have a session associated with them will be in this map.
-     *
-     * @return
-     */
-    @Path("client-by-id-session-stats")
-    @GET
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    public List<Map<String, String>> getClientByIdSessionStats() {
-        auth.requireView();
-        List<Map<String, String>> data = new LinkedList<Map<String, String>>();
-        for (ClientModel client : realm.getClients()) {
-            int size = session.sessions().getActiveUserSessions(client.getRealm(), client);
-            if (size == 0) continue;
-            Map<String, String> map = new HashMap<String, String>();
-            map.put("id", client.getId());
-            map.put("clientId", client.getClientId());
-            map.put("active", size + "");
-            data.add(map);
-        }
-        return data;
-    }
-
-    /**
-     * View the events provider and how it is configured.
-     *
-     * @return
-     */
-    @GET
-    @NoCache
-    @Path("events/config")
-    @Produces(MediaType.APPLICATION_JSON)
-    public RealmEventsConfigRepresentation getRealmEventsConfig() {
-        auth.init(RealmAuth.Resource.EVENTS).requireView();
-
-        return ModelToRepresentation.toEventsConfigReprensetation(realm);
-    }
-
-    /**
-     * Change the events provider and/or it's configuration
-     *
-     * @param rep
-     */
-    @PUT
-    @Path("events/config")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) {
-        auth.init(RealmAuth.Resource.EVENTS).requireManage();
-
-        logger.debug("updating realm events config: " + realm.getName());
-        new RealmManager(session).updateRealmEventsConfig(rep, realm);
-    }
-
-    /**
-     * Query events.  Returns all events, or will query based on URL query parameters listed here
-     *
-     * @param client app or oauth client name
-     * @param user user id
-     * @param ipAddress
-     * @param firstResult
-     * @param maxResults
-     * @return
-     */
-    @Path("events")
-    @GET
-    @NoCache
-    @Produces(MediaType.APPLICATION_JSON)
-    public List<Event> getEvents(@QueryParam("client") String client,
-            @QueryParam("user") String user, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo,
-            @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult,
-            @QueryParam("max") Integer maxResults) {
-        auth.init(RealmAuth.Resource.EVENTS).requireView();
-
-        EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
-
-        EventQuery query = eventStore.createQuery().realm(realm.getId());
-        if (client != null) {
-            query.client(client);
-        }
-
-        List<String> types = uriInfo.getQueryParameters().get("type");
-        if (types != null) {
-            EventType[] t = new EventType[types.size()];
-            for (int i = 0; i < t.length; i++) {
-                t[i] = EventType.valueOf(types.get(i));
-            }
-            query.type(t);
-        }
-
-        if (user != null) {
-            query.user(user);
-        }
-        
-        if(dateFrom != null) {
-            query.fromDate(dateFrom);
-        }
-        if(dateTo != null) {
-            query.toDate(dateTo);
-        }
-
-        if (ipAddress != null) {
-            query.ipAddress(ipAddress);
-        }
-        if (firstResult != null) {
-            query.firstResult(firstResult);
-        }
-        if (maxResults != null) {
-            query.maxResults(maxResults);
-        }
-
-        return query.getResultList();
-    }
-
-    /**
-     * Delete all events.
-     *
-     */
-    @Path("events")
-    @DELETE
-    public void clearEvents() {
-        auth.init(RealmAuth.Resource.EVENTS).requireManage();
-
-        EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
-        eventStore.clear(realm.getId());
-    }
-
-    @Path("testLDAPConnection")
-    @GET
-    @NoCache
-    public Response testLDAPConnection(@QueryParam("action") String action, @QueryParam("connectionUrl") String connectionUrl,
-                                       @QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential) {
-        auth.init(RealmAuth.Resource.REALM).requireManage();
-
-        boolean result = new LDAPConnectionTestManager().testLDAP(action, connectionUrl, bindDn, bindCredential);
-        return result ? Response.noContent().build() : ErrorResponse.error("LDAP test error", Response.Status.BAD_REQUEST);
-    }
-
-    @Path("identity-provider")
-    public IdentityProvidersResource getIdentityProviderResource() {
-        return new IdentityProvidersResource(realm, session, this.auth);
-    }
-}
+package org.keycloak.services.resources.admin;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.ClientConnection;
+import org.keycloak.events.Event;
+import org.keycloak.events.EventQuery;
+import org.keycloak.events.EventStoreProvider;
+import org.keycloak.events.EventType;
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AdminEventQuery;
+import org.keycloak.events.admin.OperationType;
+import org.keycloak.exportimport.ClientImporter;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.cache.CacheRealmProvider;
+import org.keycloak.models.cache.CacheUserProvider;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.protocol.oidc.TokenManager;
+import org.keycloak.representations.adapters.action.GlobalRequestResult;
+import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.services.managers.AuthenticationManager;
+import org.keycloak.services.managers.LDAPConnectionTestManager;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.managers.ResourceAdminManager;
+import org.keycloak.services.managers.UsersSyncManager;
+import org.keycloak.services.ErrorResponse;
+import org.keycloak.timer.TimerProvider;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Base resource class for the admin REST api of one realm
+ *
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class RealmAdminResource {
+    protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
+    protected RealmAuth auth;
+    protected RealmModel realm;
+    private TokenManager tokenManager;
+    private AdminEventBuilder adminEvent;
+
+    @Context
+    protected KeycloakSession session;
+
+    @Context
+    protected UriInfo uriInfo;
+
+    @Context
+    protected ClientConnection connection;
+
+    @Context
+    protected HttpHeaders headers;
+
+    public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager, AdminEventBuilder adminEvent) {
+        this.auth = auth;
+        this.realm = realm;
+        this.tokenManager = tokenManager;
+        this.adminEvent = adminEvent.realm(realm);
+
+        auth.init(RealmAuth.Resource.REALM);
+    }
+
+    /**
+     * Base path for importing clients under this realm.
+     *
+     * @return
+     */
+    @Path("client-importers/{formatId}")
+    public Object getClientImporter(@PathParam("formatId") String formatId) {
+        ClientImporter importer = session.getProvider(ClientImporter.class, formatId);
+        return importer.createJaxrsService(realm, auth);
+    }
+
+    /**
+     * Base path for managing clients under this realm.
+     *
+     * @return
+     */
+    @Path("clients")
+    public ClientsResource getClients() {
+        ClientsResource clientsResource = new ClientsResource(realm, auth, adminEvent);
+        ResteasyProviderFactory.getInstance().injectProperties(clientsResource);
+        return clientsResource;
+    }
+
+    /**
+     * Base path for managing clients under this realm.
+     *
+     * @return
+     */
+    @Path("clients-by-id")
+    public ClientsByIdResource getClientsById() {
+        ClientsByIdResource clientsResource = new ClientsByIdResource(realm, auth, adminEvent);
+        ResteasyProviderFactory.getInstance().injectProperties(clientsResource);
+        return clientsResource;
+    }
+
+    /**
+     * base path for managing realm-level roles of this realm
+     *
+     * @return
+     */
+    @Path("roles")
+    public RoleContainerResource getRoleContainerResource() {
+        return new RoleContainerResource(realm, auth, realm, adminEvent);
+    }
+
+    /**
+     * Get the top-level representation of the realm.  It will not include nested information like User and Client representations.
+     *
+     * @return
+     */
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public RealmRepresentation getRealm() {
+        if (auth.hasView()) {
+            RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false);
+            if (session.realms() instanceof CacheRealmProvider) {
+                CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
+                rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled());
+            }
+            if (session.userStorage() instanceof CacheUserProvider) {
+                CacheUserProvider cache = (CacheUserProvider)session.userStorage();
+                rep.setUserCacheEnabled(cache.isEnabled());
+            }
+            return rep;
+        } else {
+            auth.requireAny();
+
+            RealmRepresentation rep = new RealmRepresentation();
+            rep.setRealm(realm.getName());
+            return rep;
+        }
+    }
+
+    /**
+     * Update the top-level information of this realm.  Any user, roles or client information in the representation
+     * will be ignored.  This will only update top-level attributes of the realm.
+     *
+     * @param rep
+     * @return
+     */
+    @PUT
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateRealm(final RealmRepresentation rep) {
+        auth.requireManage();
+
+        logger.debug("updating realm: " + realm.getName());
+        try {
+            RepresentationToModel.updateRealm(rep, realm);
+            if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) {
+                CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
+                cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled());
+            }
+            if (rep.isUserCacheEnabled() != null && session.userStorage() instanceof CacheUserProvider) {
+                CacheUserProvider cache = (CacheUserProvider)session.userStorage();
+                cache.setEnabled(rep.isUserCacheEnabled());
+            }
+
+            // Refresh periodic sync tasks for configured federationProviders
+            List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
+            UsersSyncManager usersSyncManager = new UsersSyncManager();
+            for (final UserFederationProviderModel fedProvider : federationProviders) {
+                usersSyncManager.refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId());
+            }
+            
+            adminEvent.operation(OperationType.UPDATE).representation(rep).success();
+            return Response.noContent().build();
+        } catch (PatternSyntaxException e) {
+            return ErrorResponse.error("Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST);
+        } catch (ModelDuplicateException e) {
+            return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists.");
+        }  catch (Exception e) {
+            return ErrorResponse.error("Failed to update " + rep.getRealm() + " Realm.", Response.Status.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    /**
+     * Delete this realm.
+     *
+     */
+    @DELETE
+    public void deleteRealm() {
+        auth.requireManage();
+
+        if (!new RealmManager(session).removeRealm(realm)) {
+            throw new NotFoundException("Realm doesn't exist");
+        } else {
+            clearAdminEvents();
+        }
+    }
+
+    /**
+     * Base path for managing users in this realm.
+     *
+     * @return
+     */
+    @Path("users")
+    public UsersResource users() {
+        UsersResource users = new UsersResource(realm, auth, tokenManager, adminEvent);
+        ResteasyProviderFactory.getInstance().injectProperties(users);
+        //resourceContext.initResource(users);
+        return users;
+    }
+
+    @Path("user-federation")
+    public UserFederationResource userFederation() {
+        UserFederationResource fed = new UserFederationResource(realm, auth, adminEvent);
+        ResteasyProviderFactory.getInstance().injectProperties(fed);
+        //resourceContext.initResource(fed);
+        return fed;
+    }
+
+    /**
+     * Path for managing all realm-level or client-level roles defined in this realm by it's id.
+     *
+     * @return
+     */
+    @Path("roles-by-id")
+    public RoleByIdResource rolesById() {
+        RoleByIdResource resource = new RoleByIdResource(realm, auth, adminEvent);
+        ResteasyProviderFactory.getInstance().injectProperties(resource);
+        //resourceContext.initResource(resource);
+        return resource;
+    }
+
+    /**
+     * Push the realm's revocation policy to any client that has an admin url associated with it.
+     *
+     */
+    @Path("push-revocation")
+    @POST
+    public GlobalRequestResult pushRevocation() {
+        auth.requireManage();
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath(), false).success();
+        return new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
+    }
+
+    /**
+     * Removes all user sessions.  Any client that has an admin url will also be told to invalidate any sessions
+     * they have.
+     *
+     */
+    @Path("logout-all")
+    @POST
+    public GlobalRequestResult logoutAll() {
+        session.sessions().removeUserSessions(realm);
+        adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath(), false).success();
+        return new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm);
+    }
+
+    /**
+     * Remove a specific user session. Any client that has an admin url will also be told to invalidate this
+     * particular session.
+     *
+     * @param sessionId
+     */
+    @Path("sessions/{session}")
+    @DELETE
+    public void deleteSession(@PathParam("session") String sessionId) {
+        UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
+        if (userSession == null) throw new NotFoundException("Sesssion not found");
+        AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true);
+        adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath(), true).success();
+
+    }
+
+    /**
+     * Returns a JSON map.  The key is the client name, the value is the number of sessions that currently are active
+     * with that client.  Only client's that actually have a session associated with them will be in this map.
+     *
+     * @return
+     */
+    @Path("client-session-stats")
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    @Deprecated
+    public Map<String, Integer> getClientSessionStats() {
+        auth.requireView();
+        Map<String, Integer> stats = new HashMap<String, Integer>();
+        for (ClientModel client : realm.getClients()) {
+            int size = session.sessions().getActiveUserSessions(client.getRealm(), client);
+            if (size == 0) continue;
+            stats.put(client.getClientId(), size);
+        }
+        return stats;
+    }
+
+    /**
+     * Returns a JSON map.  The key is the client id, the value is the number of sessions that currently are active
+     * with that client.  Only client's that actually have a session associated with them will be in this map.
+     *
+     * @return
+     */
+    @Path("client-by-id-session-stats")
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<Map<String, String>> getClientByIdSessionStats() {
+        auth.requireView();
+        List<Map<String, String>> data = new LinkedList<Map<String, String>>();
+        for (ClientModel client : realm.getClients()) {
+            int size = session.sessions().getActiveUserSessions(client.getRealm(), client);
+            if (size == 0) continue;
+            Map<String, String> map = new HashMap<String, String>();
+            map.put("id", client.getId());
+            map.put("clientId", client.getClientId());
+            map.put("active", size + "");
+            data.add(map);
+        }
+        return data;
+    }
+
+    /**
+     * View the events provider and how it is configured.
+     *
+     * @return
+     */
+    @GET
+    @NoCache
+    @Path("events/config")
+    @Produces(MediaType.APPLICATION_JSON)
+    public RealmEventsConfigRepresentation getRealmEventsConfig() {
+        auth.init(RealmAuth.Resource.EVENTS).requireView();
+
+        return ModelToRepresentation.toEventsConfigReprensetation(realm);
+    }
+
+    /**
+     * Change the events provider and/or it's configuration
+     *
+     * @param rep
+     */
+    @PUT
+    @Path("events/config")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) {
+        auth.init(RealmAuth.Resource.EVENTS).requireManage();
+
+        logger.debug("updating realm events config: " + realm.getName());
+        new RealmManager(session).updateRealmEventsConfig(rep, realm);
+    }
+
+    /**
+     * Query events.  Returns all events, or will query based on URL query parameters listed here
+     *
+     * @param client app or oauth client name
+     * @param user user id
+     * @param ipAddress
+     * @param dateTo
+     * @param dateFrom
+     * @param firstResult
+     * @param maxResults
+     * @return
+     */
+    @Path("events")
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<Event> getEvents(@QueryParam("client") String client,
+            @QueryParam("user") String user, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo,
+            @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult,
+            @QueryParam("max") Integer maxResults) {
+        auth.init(RealmAuth.Resource.EVENTS).requireView();
+
+        EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
+
+        EventQuery query = eventStore.createQuery().realm(realm.getId());
+        if (client != null) {
+            query.client(client);
+        }
+
+        List<String> types = uriInfo.getQueryParameters().get("type");
+        if (types != null) {
+            EventType[] t = new EventType[types.size()];
+            for (int i = 0; i < t.length; i++) {
+                t[i] = EventType.valueOf(types.get(i));
+            }
+            query.type(t);
+        }
+
+        if (user != null) {
+            query.user(user);
+        }
+        
+        if(dateFrom != null) {
+            query.fromDate(dateFrom);
+        }
+        if(dateTo != null) {
+            query.toDate(dateTo);
+        }
+
+        if (ipAddress != null) {
+            query.ipAddress(ipAddress);
+        }
+        if (firstResult != null) {
+            query.firstResult(firstResult);
+        }
+        if (maxResults != null) {
+            query.maxResults(maxResults);
+        }
+
+        return query.getResultList();
+    }
+    
+    /**
+     * Query admin events.  Returns all admin events, or will query based on URL query parameters listed here
+     *
+     * @param client app or oauth client name
+     * @param operationTypes operation type
+     * @param authUser user id
+     * @param authIpAddress
+     * @param resourcePath
+     * @param dateTo
+     * @param dateFrom
+     * @param resourcePath
+     * @param firstResult
+     * @param maxResults
+     * @return
+     */
+    @Path("admin-events")
+    @GET
+    @NoCache
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<AdminEvent> getEvents(@QueryParam("authRealm") String authRealm, @QueryParam("authClient") String authClient,
+            @QueryParam("authUser") String authUser, @QueryParam("authIpAddress") String authIpAddress,
+            @QueryParam("resourcePath") String resourcePath, @QueryParam("dateFrom") String dateFrom,
+            @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult,
+            @QueryParam("max") Integer maxResults) {
+        auth.init(RealmAuth.Resource.EVENTS).requireView();
+
+        EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
+        AdminEventQuery query = eventStore.createAdminQuery().realm(realm.getId());;
+
+        if (authRealm != null) {
+            query.authRealm(authRealm);
+        }
+
+        if (authClient != null) {
+            query.authClient(authClient);
+        }
+        
+        if (authUser != null) {
+            query.authUser(authUser);
+        }
+        
+        if (authIpAddress != null) {
+            query.authIpAddress(authIpAddress);
+        }
+        
+        if (resourcePath != null) {
+            query.resourcePath(resourcePath);
+        }
+
+        List<String> operationTypes = uriInfo.getQueryParameters().get("operationTypes");
+        if (operationTypes != null) {
+            OperationType[] t = new OperationType[operationTypes.size()];
+            for (int i = 0; i < t.length; i++) {
+                t[i] = OperationType.valueOf(operationTypes.get(i));
+            }
+            query.operation(t);
+        }
+        
+        if(dateFrom != null) {
+            query.fromTime(dateFrom);
+        }
+        if(dateTo != null) {
+            query.toTime(dateTo);
+        }
+
+        if (firstResult != null) {
+            query.firstResult(firstResult);
+        }
+        if (maxResults != null) {
+            query.maxResults(maxResults);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Delete all events.
+     *
+     */
+    @Path("events")
+    @DELETE
+    public void clearEvents() {
+        auth.init(RealmAuth.Resource.EVENTS).requireManage();
+
+        EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
+        eventStore.clear(realm.getId());
+    }
+    
+    /**
+     * Delete all admin events.
+     *
+     */
+    @Path("admin-events")
+    @DELETE
+    public void clearAdminEvents() {
+        auth.init(RealmAuth.Resource.EVENTS).requireManage();
+
+        EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class);
+        eventStore.clearAdmin(realm.getId());
+    }
+
+    @Path("testLDAPConnection")
+    @GET
+    @NoCache
+    public Response testLDAPConnection(@QueryParam("action") String action, @QueryParam("connectionUrl") String connectionUrl,
+                                       @QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential) {
+        auth.init(RealmAuth.Resource.REALM).requireManage();
+
+        boolean result = new LDAPConnectionTestManager().testLDAP(action, connectionUrl, bindDn, bindCredential);
+        return result ? Response.noContent().build() : ErrorResponse.error("LDAP test error", Response.Status.BAD_REQUEST);
+    }
+
+    @Path("identity-provider")
+    public IdentityProvidersResource getIdentityProviderResource() {
+        return new IdentityProvidersResource(realm, session, this.auth, adminEvent);
+    }
+}
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 c9fea3d..fbe401c 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
@@ -6,6 +6,7 @@ import org.jboss.resteasy.plugins.providers.multipart.InputPart;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.ClientConnection;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
@@ -33,6 +34,7 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.io.IOException;
 import java.net.URI;
 import java.util.ArrayList;
@@ -52,9 +54,12 @@ public class RealmsAdminResource {
 
     @Context
     protected KeycloakSession session;
-
+    
     @Context
     protected KeycloakApplication keycloak;
+    
+    @Context
+    protected ClientConnection clientConnection;
 
     public RealmsAdminResource(AdminAuth auth, TokenManager tokenManager) {
         this.auth = auth;
@@ -128,7 +133,7 @@ public class RealmsAdminResource {
 
             URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
             logger.debugv("imported realm success, sending back: {0}", location.toString());
-
+            
             return Response.created(location).build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists");
@@ -158,10 +163,11 @@ public class RealmsAdminResource {
 
         Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
         List<InputPart> inputParts = uploadForm.get("file");
-
+        RealmRepresentation rep = null;
+        
         for (InputPart inputPart : inputParts) {
             // inputPart.getBody doesn't work as content-type is wrong, and inputPart.setMediaType is not supported on AS7 (RestEasy 2.3.2.Final)
-            RealmRepresentation rep = JsonSerialization.readValue(inputPart.getBodyAsString(), RealmRepresentation.class);
+            rep = JsonSerialization.readValue(inputPart.getBodyAsString(), RealmRepresentation.class);
             RealmModel realm;
             try {
                 realm = realmManager.importRealm(rep);
@@ -170,13 +176,14 @@ public class RealmsAdminResource {
             }
 
             grantPermissionsToRealmCreator(realm);
-
+            
+            URI location = null;
             if (inputParts.size() == 1) {
-                URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
+                location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
                 return Response.created(location).build();
             }
         }
-
+        
         return Response.noContent().build();
     }
 
@@ -218,8 +225,10 @@ public class RealmsAdminResource {
         } else {
             realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())));
         }
-
-        RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager);
+        
+        AdminEventBuilder adminEvent = new AdminEventBuilder(realm, auth, session, clientConnection);
+        
+        RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager, adminEvent);
         ResteasyProviderFactory.getInstance().injectProperties(adminResource);
         //resourceContext.initResource(adminResource);
         return adminResource;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
index 67d8c12..4ca1667 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java
@@ -3,6 +3,7 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -20,6 +21,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
 import java.util.List;
 import java.util.Set;
 
@@ -33,15 +36,17 @@ public class RoleByIdResource extends RoleResource {
     protected static final Logger logger = Logger.getLogger(RoleByIdResource.class);
     private final RealmModel realm;
     private final RealmAuth auth;
+    private AdminEventBuilder adminEvent;
 
     @Context
     protected KeycloakSession session;
 
-    public RoleByIdResource(RealmModel realm, RealmAuth auth) {
+    public RoleByIdResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
         super(realm);
 
         this.realm = realm;
         this.auth = auth;
+        this.adminEvent = adminEvent;
     }
 
     /**
@@ -57,7 +62,6 @@ public class RoleByIdResource extends RoleResource {
     public RoleRepresentation getRole(final @PathParam("role-id") String id) {
         RoleModel roleModel = getRoleModel(id);
         auth.requireView();
-
         return getRole(roleModel);
     }
 
@@ -76,7 +80,6 @@ public class RoleByIdResource extends RoleResource {
             r = RealmAuth.Resource.USER;
         }
         auth.init(r);
-
         return roleModel;
     }
 
@@ -92,6 +95,7 @@ public class RoleByIdResource extends RoleResource {
         RoleModel role = getRoleModel(id);
         auth.requireManage();
         deleteRole(role);
+        adminEvent.operation(OperationType.DELETE).resourcePath(role).success();
     }
 
     /**
@@ -107,6 +111,7 @@ public class RoleByIdResource extends RoleResource {
         RoleModel role = getRoleModel(id);
         auth.requireManage();
         updateRole(rep, role);
+        adminEvent.operation(OperationType.UPDATE).resourcePath(role).representation(rep).success();
     }
 
     /**
@@ -122,6 +127,10 @@ public class RoleByIdResource extends RoleResource {
         RoleModel role = getRoleModel(id);
         auth.requireManage();
         addComposites(roles, role);
+        
+        adminEvent.operation(OperationType.ACTION)
+            .resourcePath(role, session.getContext().getUri().getPath()).representation(roles).success();
+        
     }
 
     /**
@@ -217,6 +226,9 @@ public class RoleByIdResource extends RoleResource {
         RoleModel role = getRoleModel(id);
         auth.requireManage();
         deleteComposites(roles, role);
+        
+        adminEvent.operation(OperationType.DELETE)
+            .resourcePath(role, session.getContext().getUri().getPath()).representation(roles).success();
     }
 
 }
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 fa0064f..de2e3b4 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,7 +2,9 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 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;
@@ -23,6 +25,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -35,12 +38,14 @@ public class RoleContainerResource extends RoleResource {
     private final RealmModel realm;
     private final RealmAuth auth;
     protected RoleContainerModel roleContainer;
+    private AdminEventBuilder adminEvent;
 
-    public RoleContainerResource(RealmModel realm, RealmAuth auth, RoleContainerModel roleContainer) {
+    public RoleContainerResource(RealmModel realm, RealmAuth auth, RoleContainerModel roleContainer, AdminEventBuilder adminEvent) {
         super(realm);
         this.realm = realm;
         this.auth = auth;
         this.roleContainer = roleContainer;
+        this.adminEvent = adminEvent;
     }
 
     /**
@@ -51,7 +56,7 @@ public class RoleContainerResource extends RoleResource {
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public List<RoleRepresentation> getRoles() {
+    public List<RoleRepresentation> getRoles(@Context final UriInfo uriInfo) {
         auth.requireAny();
 
         Set<RoleModel> roleModels = roleContainer.getRoles();
@@ -77,6 +82,9 @@ public class RoleContainerResource extends RoleResource {
         try {
             RoleModel role = roleContainer.addRole(rep.getName());
             role.setDescription(rep.getDescription());
+
+            adminEvent.operation(OperationType.CREATE).resourcePath(role).representation(rep).success();
+
             return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("Role with name " + rep.getName() + " already exists");
@@ -93,7 +101,7 @@ public class RoleContainerResource extends RoleResource {
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public RoleRepresentation getRole(final @PathParam("role-name") String roleName) {
+    public RoleRepresentation getRole(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName) {
         auth.requireView();
 
         RoleModel roleModel = roleContainer.getRole(roleName);
@@ -112,15 +120,18 @@ public class RoleContainerResource extends RoleResource {
     @Path("{role-name}")
     @DELETE
     @NoCache
-    public void deleteRole(final @PathParam("role-name") String roleName) {
+    public void deleteRole(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName) {
         auth.requireManage();
 
-        RoleRepresentation rep = getRole(roleName);
+        RoleRepresentation rep = getRole(uriInfo, roleName);
         RoleModel role = roleContainer.getRole(roleName);
         if (role == null) {
             throw new NotFoundException("Could not find role: " + roleName);
         }
         deleteRole(role);
+
+        adminEvent.operation(OperationType.DELETE).resourcePath(role).success();
+
     }
 
     /**
@@ -133,7 +144,7 @@ public class RoleContainerResource extends RoleResource {
     @Path("{role-name}")
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response updateRole(final @PathParam("role-name") String roleName, final RoleRepresentation rep) {
+    public Response updateRole(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName, final RoleRepresentation rep) {
         auth.requireManage();
 
         RoleModel role = roleContainer.getRole(roleName);
@@ -142,6 +153,9 @@ public class RoleContainerResource extends RoleResource {
         }
         try {
             updateRole(rep, role);
+
+            adminEvent.operation(OperationType.UPDATE).resourcePath(role).representation(rep).success();
+
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("Role with name " + rep.getName() + " already exists");
@@ -157,7 +171,7 @@ public class RoleContainerResource extends RoleResource {
     @Path("{role-name}/composites")
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
-    public void addComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
+    public void addComposites(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
         auth.requireManage();
 
         RoleModel role = roleContainer.getRole(roleName);
@@ -165,6 +179,8 @@ public class RoleContainerResource extends RoleResource {
             throw new NotFoundException("Could not find role: " + roleName);
         }
         addComposites(roles, role);
+        adminEvent.operation(OperationType.ACTION).resourcePath(role, uriInfo.getPath()).representation(roles).success();
+
     }
 
     /**
@@ -177,7 +193,7 @@ public class RoleContainerResource extends RoleResource {
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-name") String roleName) {
+    public Set<RoleRepresentation> getRoleComposites(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName) {
         auth.requireManage();
 
         RoleModel role = roleContainer.getRole(roleName);
@@ -197,7 +213,7 @@ public class RoleContainerResource extends RoleResource {
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-name") String roleName) {
+    public Set<RoleRepresentation> getRealmRoleComposites(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName) {
         auth.requireManage();
 
         RoleModel role = roleContainer.getRole(roleName);
@@ -218,7 +234,8 @@ public class RoleContainerResource extends RoleResource {
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-name") String roleName,
+    public Set<RoleRepresentation> getClientRoleComposites(@Context final UriInfo uriInfo, 
+                                                           final @PathParam("role-name") String roleName,
                                                            final @PathParam("clientId") String clientId) {
         auth.requireManage();
 
@@ -246,7 +263,8 @@ public class RoleContainerResource extends RoleResource {
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public Set<RoleRepresentation> getClientByIdRoleComposites(final @PathParam("role-name") String roleName,
+    public Set<RoleRepresentation> getClientByIdRoleComposites(@Context final UriInfo uriInfo,
+                                                                final @PathParam("role-name") String roleName,
                                                                 final @PathParam("id") String id) {
         auth.requireManage();
 
@@ -272,7 +290,9 @@ public class RoleContainerResource extends RoleResource {
     @Path("{role-name}/composites")
     @DELETE
     @Consumes(MediaType.APPLICATION_JSON)
-    public void deleteComposites(final @PathParam("role-name") String roleName, List<RoleRepresentation> roles) {
+    public void deleteComposites(@Context final UriInfo uriInfo, 
+                                   final @PathParam("role-name") String roleName,
+                                   List<RoleRepresentation> roles) {
         auth.requireManage();
 
         RoleModel role = roleContainer.getRole(roleName);
@@ -280,7 +300,7 @@ public class RoleContainerResource extends RoleResource {
             throw new NotFoundException("Could not find role: " + roleName);
         }
         deleteComposites(roles, role);
+        adminEvent.operation(OperationType.DELETE).resourcePath(role, uriInfo.getPath()).success();
     }
 
-
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
index 01fe1d6..7f195c5 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java
@@ -2,6 +2,7 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -16,6 +17,7 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -30,13 +32,15 @@ public class ScopeMappedClientResource {
     protected ClientModel client;
     protected KeycloakSession session;
     protected ClientModel scopedClient;
-
-    public ScopeMappedClientResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, ClientModel scopedClient) {
+    protected AdminEventBuilder adminEvent;
+    
+    public ScopeMappedClientResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, ClientModel scopedClient, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.client = client;
         this.session = session;
         this.scopedClient = scopedClient;
+        this.adminEvent = adminEvent;
     }
 
     /**
@@ -106,8 +110,8 @@ public class ScopeMappedClientResource {
                 throw new NotFoundException("Role not found");
             }
             client.addScopeMapping(roleModel);
+            adminEvent.operation(OperationType.CREATE).resourcePath(client, "/roles").representation(roles).success();
         }
-
     }
 
     /**
@@ -135,5 +139,6 @@ public class ScopeMappedClientResource {
                 client.deleteScopeMapping(roleModel);
             }
         }
+        adminEvent.operation(OperationType.DELETE).resourcePath(client, "/roles").representation(roles).success();
     }
 }
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 8d4e005..97b5e3b 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
@@ -2,6 +2,7 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -18,7 +19,10 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -36,12 +40,14 @@ public class ScopeMappedResource {
     private RealmAuth auth;
     protected ClientModel client;
     protected KeycloakSession session;
+    protected AdminEventBuilder adminEvent;
 
-    public ScopeMappedResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session) {
+    public ScopeMappedResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.client = client;
         this.session = session;
+        this.adminEvent = adminEvent;
     }
 
     /**
@@ -176,7 +182,7 @@ public class ScopeMappedResource {
             }
             client.addScopeMapping(roleModel);
         }
-
+        adminEvent.operation(OperationType.CREATE).resourcePath(client, "/roles").representation(roles).success();
 
     }
 
@@ -206,6 +212,8 @@ public class ScopeMappedResource {
                 client.deleteScopeMapping(roleModel);
             }
         }
+        adminEvent.operation(OperationType.DELETE).resourcePath(client, "/roles").representation(roles).success();
+
     }
 
     @Path("clients/{clientId}")
@@ -215,8 +223,7 @@ public class ScopeMappedResource {
         if (app == null) {
             throw new NotFoundException("Role not found");
         }
-
-        return new ScopeMappedClientResource(realm, auth, client, session, app);
+        return new ScopeMappedClientResource(realm, auth, client, session, app, adminEvent);
     }
 
     @Path("clients-by-id/{id}")
@@ -226,7 +233,6 @@ public class ScopeMappedResource {
         if (app == null) {
             throw new NotFoundException("Client not found");
         }
-
-        return new ScopeMappedClientResource(realm, auth, client, session, app);
+        return new ScopeMappedClientResource(realm, auth, client, session, app, adminEvent);
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
index f535b19..4e0d8f9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java
@@ -5,6 +5,7 @@ import org.keycloak.broker.provider.IdentityProvider;
 import org.keycloak.broker.provider.IdentityProviderFactory;
 import org.keycloak.events.EventListenerProvider;
 import org.keycloak.events.EventType;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.exportimport.ClientImporter;
 import org.keycloak.exportimport.ClientImporterFactory;
 import org.keycloak.freemarker.Theme;
@@ -39,6 +40,8 @@ import java.util.Set;
  */
 public class ServerInfoAdminResource {
 
+    private static final Map<String, List<String>> ENUMS = createEnumsMap(EventType.class, OperationType.class);
+
     @Context
     private KeycloakSession session;
 
@@ -61,7 +64,7 @@ public class ServerInfoAdminResource {
         setProviders(info);
         setProtocolMapperTypes(info);
         setBuiltinProtocolMappers(info);
-        setEventTypes(info);
+        info.setEnums(ENUMS);
         return info;
     }
 
@@ -181,15 +184,6 @@ public class ServerInfoAdminResource {
         }
     }
 
-    private void setEventTypes(ServerInfoRepresentation info) {
-        List<String> eventTypes = new LinkedList<>();
-        for (EventType t : EventType.values()) {
-            eventTypes.add(t.name());
-        }
-        Collections.sort(eventTypes);
-        info.setEventTypes(eventTypes);
-    }
-
     public static class ServerInfoRepresentation {
 
         private String version;
@@ -209,7 +203,7 @@ public class ServerInfoAdminResource {
         private Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes;
         private Map<String, List<ProtocolMapperRepresentation>> builtinProtocolMappers;
 
-        private List<String> eventTypes;
+        private Map<String, List<String>> enums;
 
         public ServerInfoRepresentation() {
         }
@@ -262,13 +256,30 @@ public class ServerInfoAdminResource {
             this.builtinProtocolMappers = builtinProtocolMappers;
         }
 
-        public List<String> getEventTypes() {
-            return eventTypes;
+        public Map<String, List<String>> getEnums() {
+            return enums;
+        }
+
+        public void setEnums(Map<String, List<String>> enums) {
+            this.enums = enums;
         }
+    }
+
+    private static Map<String, List<String>> createEnumsMap(Class... enums) {
+        Map<String, List<String>> m = new HashMap<>();
+        for (Class e : enums) {
+            String n = e.getSimpleName();
+            n = Character.toLowerCase(n.charAt(0)) + n.substring(1);
+
+            List<String> l = new LinkedList<>();
+            for (Object c :  e.getEnumConstants()) {
+                l.add(c.toString());
+            }
+            Collections.sort(l);
 
-        public void setEventTypes(List<String> eventTypes) {
-            this.eventTypes = eventTypes;
+            m.put(n, l);
         }
+        return m;
     }
 
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java
index e838333..9bd8160 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java
@@ -3,7 +3,9 @@ package org.keycloak.services.resources.admin;
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
+import org.keycloak.events.admin.OperationType;
 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;
@@ -16,7 +18,10 @@ import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -33,12 +38,18 @@ public class UserClientRoleMappingsResource {
     protected RealmAuth auth;
     protected UserModel user;
     protected ClientModel client;
+    protected AdminEventBuilder adminEvent;
+    
+    @Context
+    protected KeycloakSession session;
+    
 
-    public UserClientRoleMappingsResource(RealmModel realm, RealmAuth auth, UserModel user, ClientModel client) {
+    public UserClientRoleMappingsResource(RealmModel realm, RealmAuth auth, UserModel user, ClientModel client, AdminEventBuilder adminEvent) {
         this.realm = realm;
         this.auth = auth;
         this.user = user;
         this.client = client;
+        this.adminEvent = adminEvent;
     }
 
     /**
@@ -127,6 +138,7 @@ public class UserClientRoleMappingsResource {
             }
             user.grantRole(roleModel);
         }
+        adminEvent.operation(OperationType.CREATE).resourcePath(client, user, "/roles/").representation(roles).success();
 
     }
 
@@ -159,5 +171,6 @@ public class UserClientRoleMappingsResource {
                 user.deleteRoleMapping(roleModel);
             }
         }
+        adminEvent.operation(OperationType.DELETE).resourcePath(client, user, "/roles/").representation(roles).success();
     }
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java
index 188cb30..7bc54a9 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java
@@ -4,6 +4,7 @@ import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.constants.KerberosConstants;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
@@ -31,6 +32,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -46,6 +48,8 @@ public class UserFederationResource {
     protected RealmModel realm;
 
     protected  RealmAuth auth;
+    
+    protected AdminEventBuilder adminEvent;
 
     @Context
     protected UriInfo uriInfo;
@@ -53,10 +57,11 @@ public class UserFederationResource {
     @Context
     protected KeycloakSession session;
 
-    public UserFederationResource(RealmModel realm, RealmAuth auth) {
+    public UserFederationResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
-
+        this.adminEvent = adminEvent;
+        
         auth.init(RealmAuth.Resource.USER);
     }
 
@@ -99,6 +104,8 @@ public class UserFederationResource {
             UserFederationProviderFactoryRepresentation rep = new UserFederationProviderFactoryRepresentation();
             rep.setId(factory.getId());
             rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions());
+
+
             return rep;
         }
         throw new NotFoundException("Could not find provider");
@@ -123,6 +130,9 @@ public class UserFederationResource {
                 rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
         new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
         checkKerberosCredential(model);
+        
+        adminEvent.operation(OperationType.CREATE).resourcePath(model).representation(rep).success();
+
         return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
     }
 
@@ -146,6 +156,9 @@ public class UserFederationResource {
         realm.updateUserFederationProvider(model);
         new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
         checkKerberosCredential(model);
+        
+        adminEvent.operation(OperationType.UPDATE).resourcePath(model).representation(rep).success();
+
     }
 
     /**
@@ -164,7 +177,6 @@ public class UserFederationResource {
                 return ModelToRepresentation.toRepresentation(model);
             }
         }
-        
         throw new NotFoundException("could not find provider");
     }
 
@@ -182,6 +194,9 @@ public class UserFederationResource {
         UserFederationProviderModel model = new UserFederationProviderModel(id, null, null, -1, null, -1, -1, 0);
         realm.removeUserFederationProvider(model);
         new UsersSyncManager().removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), model);
+        
+        adminEvent.operation(OperationType.DELETE).resourcePath(model).success();
+
     }
 
 
@@ -224,6 +239,7 @@ public class UserFederationResource {
                 } else if ("triggerChangedUsersSync".equals(action)) {
                     syncManager.syncChangedUsers(session.getKeycloakSessionFactory(), realm.getId(), model);
                 }
+                adminEvent.operation(OperationType.ACTION).resourcePath(model, "/sync").success();
                 return Response.noContent().build();
             }
         }
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 ee9dc90..c84b635 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
@@ -7,6 +7,7 @@ import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.ClientConnection;
 import org.keycloak.email.EmailException;
 import org.keycloak.email.EmailProvider;
+import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.Constants;
@@ -56,6 +57,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -78,6 +80,8 @@ public class UsersResource {
 
     private RealmAuth auth;
     
+    private AdminEventBuilder adminEvent;
+    
     @Context
     protected ClientConnection clientConnection;
 
@@ -90,9 +94,10 @@ public class UsersResource {
     @Context
     protected HttpHeaders headers;
 
-    public UsersResource(RealmModel realm, RealmAuth auth, TokenManager tokenManager) {
+    public UsersResource(RealmModel realm, RealmAuth auth, TokenManager tokenManager, AdminEventBuilder adminEvent) {
         this.auth = auth;
         this.realm = realm;
+        this.adminEvent = adminEvent;
 
         auth.init(RealmAuth.Resource.USER);
     }
@@ -116,11 +121,11 @@ public class UsersResource {
                 throw new NotFoundException("User not found");
             }
             updateUserFromRep(user, rep);
+            adminEvent.operation(OperationType.UPDATE).resourcePath(user).representation(rep).success();
 
             if (session.getTransaction().isActive()) {
                 session.getTransaction().commit();
             }
-
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return ErrorResponse.exists("User exists with same username or email");
@@ -152,11 +157,13 @@ public class UsersResource {
         try {
             UserModel user = session.users().addUser(realm, rep.getUsername());
             updateUserFromRep(user, rep);
-
+            
+            adminEvent.operation(OperationType.CREATE).resourcePath(user).representation(rep).success();
+            
             if (session.getTransaction().isActive()) {
                 session.getTransaction().commit();
             }
-
+            
             return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getUsername()).build()).build();
         } catch (ModelDuplicateException e) {
             if (session.getTransaction().isActive()) {
@@ -217,7 +224,7 @@ public class UsersResource {
         if (user == null) {
             throw new NotFoundException("User not found");
         }
-
+        
         UserRepresentation rep = ModelToRepresentation.toRepresentation(user);
 
         if (realm.isIdentityFederationEnabled()) {
@@ -305,7 +312,7 @@ public class UsersResource {
 
         FederatedIdentityModel socialLink = new FederatedIdentityModel(provider, rep.getUserId(), rep.getUserName());
         session.users().addFederatedIdentity(realm, user, socialLink);
-
+        adminEvent.operation(OperationType.CREATE).resourcePath(user, uriInfo.getPath(), true).representation(rep).success();
         return Response.noContent().build();
     }
 
@@ -321,6 +328,7 @@ public class UsersResource {
         if (!session.users().removeFederatedIdentity(realm, user, provider)) {
             throw new NotFoundException("Link not found");
         }
+        adminEvent.operation(OperationType.DELETE).resourcePath(user, uriInfo.getPath(), true).success();
     }
 
     /**
@@ -374,6 +382,7 @@ public class UsersResource {
         } else {
             throw new NotFoundException("Consent not found for user " + username + " and client " + clientId);
         }
+        adminEvent.operation(OperationType.ACTION).resourcePath(user, client, uriInfo.getPath()).success();
     }
 
     /**
@@ -395,6 +404,7 @@ public class UsersResource {
         for (UserSessionModel userSession : userSessions) {
             AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers, true);
         }
+        adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success();
     }
 
     /**
@@ -416,6 +426,7 @@ public class UsersResource {
 
         boolean removed = new UserManager(session).removeUser(realm, user);
         if (removed) {
+            adminEvent.operation(OperationType.DELETE).resourcePath(user).success();
             return Response.noContent().build();
         } else {
             return ErrorResponse.error("User couldn't be deleted", Response.Status.BAD_REQUEST);
@@ -628,7 +639,8 @@ public class UsersResource {
             }
             user.grantRole(roleModel);
         }
-
+        
+        adminEvent.operation(OperationType.CREATE).resourcePath(user, realm, uriInfo.getPath()).representation(roles).success();
 
     }
 
@@ -665,6 +677,8 @@ public class UsersResource {
                 user.deleteRoleMapping(roleModel);
             }
         }
+        
+        adminEvent.operation(OperationType.DELETE).resourcePath(user, realm, uriInfo.getPath()).representation(roles).success();
     }
 
     @Path("{username}/role-mappings/clients/{clientId}")
@@ -679,8 +693,7 @@ public class UsersResource {
         if (client == null) {
             throw new NotFoundException("Client not found");
         }
-
-        return new UserClientRoleMappingsResource(realm, auth, user, client);
+        return new UserClientRoleMappingsResource(realm, auth, user, client, adminEvent);
 
     }
     @Path("{username}/role-mappings/clients-by-id/{id}")
@@ -695,8 +708,8 @@ public class UsersResource {
         if (client == null) {
             throw new NotFoundException("Client not found");
         }
-
-        return new UserClientRoleMappingsResource(realm, auth, user, client);
+        
+        return new UserClientRoleMappingsResource(realm, auth, user, client, adminEvent);
 
     }
     /**
@@ -729,6 +742,8 @@ public class UsersResource {
             throw new BadRequestException("Can't reset password as account is read only");
         }
         if (pass.isTemporary()) user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
+        
+        adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success();
     }
 
     /**
@@ -748,6 +763,7 @@ public class UsersResource {
         }
 
         user.setTotp(false);
+        adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success();
     }
 
     /**
@@ -823,6 +839,9 @@ public class UsersResource {
             this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendPasswordReset(link, expiration);
 
             //audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success();
+
+            adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success();
+
             return Response.ok().build();
         } catch (EmailException e) {
             logger.error("Failed to send password reset email", e);
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 d3586bc..b0f02ad 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -25,6 +25,7 @@ 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.SystemEnvProperties;
 
 import javax.servlet.ServletContext;
 import javax.ws.rs.core.Application;
@@ -139,14 +140,8 @@ public class KeycloakApplication extends Application {
             }
 
             if (node != null) {
-                Properties properties = new Properties();
-                properties.putAll(System.getProperties());
-                for(Map.Entry<String, String> e : System.getenv().entrySet()) {
-                    properties.put("env." + e.getKey(), e.getValue());
-                }
-
+                Properties properties = new SystemEnvProperties();
                 Config.init(new JsonConfigProvider(node, properties));
-
                 return;
             } else {
                 log.warn("Config 'keycloak-server.json' not found");
diff --git a/services/src/main/java/org/keycloak/wellknown/WellKnownSpi.java b/services/src/main/java/org/keycloak/wellknown/WellKnownSpi.java
index 7cb962d..7734f48 100755
--- a/services/src/main/java/org/keycloak/wellknown/WellKnownSpi.java
+++ b/services/src/main/java/org/keycloak/wellknown/WellKnownSpi.java
@@ -10,6 +10,11 @@ import org.keycloak.provider.Spi;
 public class WellKnownSpi implements Spi {
 
     @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
+    @Override
     public String getName() {
         return "well-known";
     }
diff --git a/social/core/src/main/java/org/keycloak/social/SocialProviderSpi.java b/social/core/src/main/java/org/keycloak/social/SocialProviderSpi.java
index 949fea7..fd500a8 100644
--- a/social/core/src/main/java/org/keycloak/social/SocialProviderSpi.java
+++ b/social/core/src/main/java/org/keycloak/social/SocialProviderSpi.java
@@ -29,6 +29,11 @@ public class SocialProviderSpi implements Spi {
     public static final String SOCIAL_SPI_NAME = "social";
 
     @Override
+    public boolean isPrivate() {
+        return false;
+    }
+
+    @Override
     public String getName() {
         return SOCIAL_SPI_NAME;
     }
diff --git a/testsuite/docker-cluster/shared-files/keycloak-base-prepare.sh b/testsuite/docker-cluster/shared-files/keycloak-base-prepare.sh
index 965da9b..c303009 100644
--- a/testsuite/docker-cluster/shared-files/keycloak-base-prepare.sh
+++ b/testsuite/docker-cluster/shared-files/keycloak-base-prepare.sh
@@ -12,8 +12,8 @@ mkdir -p mysql/main && mv /mysql-connector-java-5.1.32.jar mysql/main/
 cp /keycloak-docker-cluster/shared-files/mysql-module.xml mysql/main/module.xml
 mv mysql $JBOSS_MODULES_HOME/com/
 
-sed -i -e "s/<extensions>/&\n <extension module=\"org.keycloak.keycloak-subsystem\"\/>/" $JBOSS_HOME/standalone/configuration/standalone-ha.xml
-sed -i -e 's/<profile>/&\n <subsystem xmlns="urn:jboss:domain:keycloak:1.0">\n  <auth-server name="main-auth-server">\n   <enabled>true<\/enabled>\n   <web-context>auth<\/web-context>\n  <\/auth-server> \n <\/subsystem>/' $JBOSS_HOME/standalone/configuration/standalone-ha.xml && \
+sed -i -e "s/<extensions>/&\n <extension module=\"org.keycloak.keycloak-server-subsystem\"\/>/" $JBOSS_HOME/standalone/configuration/standalone-ha.xml
+sed -i -e 's/<profile>/&\n <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">\n  <auth-server name="main-auth-server">\n   <enabled>true<\/enabled>\n   <web-context>auth<\/web-context>\n  <\/auth-server> \n <\/subsystem>/' $JBOSS_HOME/standalone/configuration/standalone-ha.xml && \
 sed -i -e 's/<security-domains>/&\n <security-domain name="keycloak">\n  <authentication>\n   <login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule" flag="required"\/>\n  <\/authentication>\n <\/security-domain>/' $JBOSS_HOME/standalone/configuration/standalone-ha.xml && \
 sed -i -e 's/<drivers>/&\n <driver name="mysql" module="com.mysql">\n  <xa-datasource-class>com.mysql.jdbc.Driver<\/xa-datasource-class>\n  <driver-class>com.mysql.jdbc.Driver<\/driver-class>\n <\/driver>/' $JBOSS_HOME/standalone/configuration/standalone-ha.xml && \
 sed -i -e 's/<\/periodic-rotating-file-handler>/&\n <logger category=\"org.keycloak\">\n  <level name=\"DEBUG\" \/> \n <\/logger>\n <logger category=\"org.jboss.resteasy.core.ResourceLocator\">\n  <level name=\"ERROR\" \/> \n <\/logger>/' $JBOSS_HOME/standalone/configuration/standalone-ha.xml
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
index 13c181b..ce80527 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
@@ -8,6 +8,7 @@ import org.junit.Assert;
 import org.junit.rules.TestRule;
 import org.junit.runners.model.Statement;
 import org.keycloak.Config;
+import org.keycloak.events.admin.AdminEvent;
 import org.keycloak.events.Details;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventListenerProvider;
@@ -195,6 +196,12 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
             @Override
             public void close() {
             }
+
+            @Override
+            public void onEvent(AdminEvent event, boolean includeRepresentation) {
+                // TODO Auto-generated method stub
+                
+            }
         };
     }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java
new file mode 100644
index 0000000..58c5698
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java
@@ -0,0 +1,226 @@
+package org.keycloak.testsuite.events;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.keycloak.events.EventStoreProvider;
+import org.keycloak.events.admin.AdminEvent;
+import org.keycloak.events.admin.AuthDetails;
+import org.keycloak.events.admin.OperationType;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.testsuite.rule.KeycloakRule;
+
+/**
+ * @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
+ */
+public class AdminEventStoreProviderTest {
+
+    @ClassRule
+    public static KeycloakRule kc = new KeycloakRule();
+
+    private KeycloakSession session;
+
+    private EventStoreProvider eventStore;
+
+    @Before
+    public void before() {
+        session = kc.startSession();
+        eventStore = session.getProvider(EventStoreProvider.class);
+    }
+
+    @After
+    public void after() {
+        eventStore.clearAdmin();
+        kc.stopSession(session, true);
+    }
+
+    @Test
+    public void save() {
+        eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+    }
+
+    @Test
+    public void query() {
+        long oldest = System.currentTimeMillis() - 30000;
+        long newest = System.currentTimeMillis() + 30000;
+
+        eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create("realmId2", OperationType.CREATE, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(oldest, "realmId", OperationType.CREATE, "realmId", "clientId2", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+
+        resetSession();
+
+        Assert.assertEquals(5, eventStore.createAdminQuery().authClient("clientId").getResultList().size());
+        Assert.assertEquals(5, eventStore.createAdminQuery().authRealm("realmId").getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().operation(OperationType.CREATE).getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().operation(OperationType.CREATE, OperationType.ACTION).getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().authUser("userId").getResultList().size());
+
+        Assert.assertEquals(1, eventStore.createAdminQuery().authUser("userId").operation(OperationType.ACTION).getResultList().size());
+
+        Assert.assertEquals(2, eventStore.createAdminQuery().maxResults(2).getResultList().size());
+        Assert.assertEquals(1, eventStore.createAdminQuery().firstResult(5).getResultList().size());
+
+        Assert.assertEquals(newest, eventStore.createAdminQuery().maxResults(1).getResultList().get(0).getTime());
+        Assert.assertEquals(oldest, eventStore.createAdminQuery().firstResult(5).maxResults(1).getResultList().get(0).getTime());
+        
+        eventStore.clearAdmin("realmId");
+        eventStore.clearAdmin("realmId2");
+        
+        Assert.assertEquals(0, eventStore.createAdminQuery().getResultList().size());
+        
+        String d1 = new String("2015-03-04");
+        String d2 = new String("2015-03-05");
+        String d3 = new String("2015-03-06");
+        String d4 = new String("2015-03-07");
+        
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+        Date date1 = null, date2 = null, date3 = null, date4 = null;
+        
+        try {
+            date1 = formatter.parse(d1);
+            date2 = formatter.parse(d2);
+            date3 = formatter.parse(d3);
+            date4 = formatter.parse(d4);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        
+        eventStore.onEvent(create(date1, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date1, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date2, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date2, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date3, "realmId", OperationType.UPDATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date3, "realmId", OperationType.DELETE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date4, "realmId2", OperationType.CREATE, "realmId2", "clientId2", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(date4, "realmId2", OperationType.CREATE, "realmId2", "clientId2", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+        
+        resetSession();
+        
+        Assert.assertEquals(6, eventStore.createAdminQuery().authClient("clientId").getResultList().size());
+        Assert.assertEquals(2, eventStore.createAdminQuery().authClient("clientId2").getResultList().size());
+        
+        Assert.assertEquals(6, eventStore.createAdminQuery().authRealm("realmId").getResultList().size());
+        Assert.assertEquals(2, eventStore.createAdminQuery().authRealm("realmId2").getResultList().size());
+        
+        Assert.assertEquals(4, eventStore.createAdminQuery().authUser("userId").getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().authUser("userId2").getResultList().size());
+        
+        Assert.assertEquals(2, eventStore.createAdminQuery().operation(OperationType.ACTION).getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().operation(OperationType.CREATE, OperationType.ACTION).getResultList().size());
+        Assert.assertEquals(1, eventStore.createAdminQuery().operation(OperationType.UPDATE).getResultList().size());
+        Assert.assertEquals(1, eventStore.createAdminQuery().operation(OperationType.DELETE).getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().operation(OperationType.CREATE).getResultList().size());
+        
+        Assert.assertEquals(8, eventStore.createAdminQuery().fromTime("2015-03-04").getResultList().size());
+        Assert.assertEquals(8, eventStore.createAdminQuery().toTime("2015-03-07").getResultList().size());
+        
+        Assert.assertEquals(4, eventStore.createAdminQuery().fromTime("2015-03-06").getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().toTime("2015-03-05").getResultList().size());
+        
+        Assert.assertEquals(0, eventStore.createAdminQuery().fromTime("2015-03-08").getResultList().size());
+        Assert.assertEquals(0, eventStore.createAdminQuery().toTime("2015-03-03").getResultList().size());
+        
+        Assert.assertEquals(8, eventStore.createAdminQuery().fromTime("2015-03-04").toTime("2015-03-07").getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().fromTime("2015-03-05").toTime("2015-03-07").getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().fromTime("2015-03-04").toTime("2015-03-05").getResultList().size());
+        Assert.assertEquals(4, eventStore.createAdminQuery().fromTime("2015-03-06").toTime("2015-03-07").getResultList().size());
+        
+        Assert.assertEquals(0, eventStore.createAdminQuery().fromTime("2015-03-01").toTime("2015-03-03").getResultList().size());
+        Assert.assertEquals(0, eventStore.createAdminQuery().fromTime("2015-03-08").toTime("2015-03-10").getResultList().size());
+        
+    }
+    
+    @Test
+    public void queryResourcePath() {
+        long oldest = System.currentTimeMillis() - 30000;
+        long newest = System.currentTimeMillis() + 30000;
+
+        eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create("realmId2", OperationType.CREATE, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(oldest, "realmId", OperationType.CREATE, "realmId", "clientId2", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false);
+
+        resetSession();
+
+        Assert.assertEquals(6, eventStore.createAdminQuery().resourcePath("/admin").getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().resourcePath("/realms").getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().resourcePath("/master").getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().resourcePath("/admin/realms").getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().resourcePath("/realms/master").getResultList().size());
+        Assert.assertEquals(6, eventStore.createAdminQuery().resourcePath("/admin/realms/master").getResultList().size());
+    }
+    
+    @Test
+    public void clear() {
+        eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis() - 20000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId2", OperationType.CREATE, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+
+        resetSession();
+
+        eventStore.clearAdmin("realmId");
+
+        Assert.assertEquals(1, eventStore.createAdminQuery().getResultList().size());
+    }
+
+    @Test
+    public void clearOld() {
+        eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis() - 20000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+        eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false);
+
+        resetSession();
+
+        eventStore.clearAdmin("realmId", System.currentTimeMillis() - 10000);
+
+        Assert.assertEquals(2, eventStore.createAdminQuery().getResultList().size());
+    }
+
+    private AdminEvent create(String realmId, OperationType operation, String authRealmId, String authClientId, String authUserId, String authIpAddress, String resourcePath, String error) {
+        return create(System.currentTimeMillis(), realmId, operation, authRealmId, authClientId, authUserId, authIpAddress, resourcePath, error);
+    }
+    
+    private AdminEvent create(Date date, String realmId, OperationType operation, String authRealmId, String authClientId, String authUserId, String authIpAddress, String resourcePath, String error) {
+        return create(date.getTime(), realmId, operation, authRealmId, authClientId, authUserId, authIpAddress, resourcePath, error);
+    }
+
+    private AdminEvent create(long time, String realmId, OperationType operation, String authRealmId, String authClientId, String authUserId, String authIpAddress, String resourcePath, String error) {
+        AdminEvent e = new AdminEvent();
+        e.setTime(time);
+        e.setRealmId(realmId);
+        e.setOperationType(operation);
+        AuthDetails authDetails = new AuthDetails();
+        authDetails.setRealmId(authRealmId);
+        authDetails.setClientId(authClientId);
+        authDetails.setUserId(authUserId);
+        authDetails.setIpAddress(authIpAddress);
+        e.setAuthDetails(authDetails);
+        e.setResourcePath(resourcePath);
+        e.setError(error);
+
+        return e;
+    }
+
+    private void resetSession() {
+        kc.stopSession(session, true);
+        session = kc.startSession();
+        eventStore = session.getProvider(EventStoreProvider.class);
+    }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/ListSpi.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/ListSpi.java
new file mode 100644
index 0000000..82695bc
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/utils/ListSpi.java
@@ -0,0 +1,34 @@
+package org.keycloak.testsuite.utils;
+
+import org.keycloak.provider.Spi;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class ListSpi {
+
+    public static void main(String[] args) {
+        List<String> l = new LinkedList<>();
+        for (Spi s : ServiceLoader.load(Spi.class)) {
+            l.add(fixedLength(s.getName()) + s.isPrivate());
+        }
+        Collections.sort(l);
+        System.out.println(fixedLength("SPI") + "Private");
+        System.out.println("-------------------------------------");
+        for (String s : l) {
+            System.out.println(s);
+        }
+    }
+
+    public static String fixedLength(String s) {
+        while (s.length() < 30) {
+            s = s + " ";
+        }
+        return s;
+    }
+}
diff --git a/testsuite/integration/src/test/resources/log4j.properties b/testsuite/integration/src/test/resources/log4j.properties
index d94d2f9..a776341 100755
--- a/testsuite/integration/src/test/resources/log4j.properties
+++ b/testsuite/integration/src/test/resources/log4j.properties
@@ -18,6 +18,7 @@ log4j.logger.org.keycloak=info
 # log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider=debug
 # log4j.logger.org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider=debug
 # log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug
+# log4j.logger.org.keycloak.migration.MigrationModelManager=debug
 
 # Enable to view kerberos/spnego logging
 # log4j.logger.org.keycloak.broker.kerberos=trace
diff --git a/testsuite/integration/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration/src/test/resources/META-INF/keycloak-server.json
index 15269f2..277a708 100755
--- a/testsuite/integration/src/test/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/test/resources/META-INF/keycloak-server.json
@@ -48,8 +48,7 @@
         "cacheThemes": "${keycloak.theme.cacheThemes:true}",
         "folder": {
             "dir": "${keycloak.theme.dir}"
-        } ,
-        "welcomeTheme": "logo-example"
+        }
     },
 
     "login": {
diff --git a/testsuite/wildfly/pom.xml b/testsuite/wildfly/pom.xml
new file mode 100644
index 0000000..4fbbe04
--- /dev/null
+++ b/testsuite/wildfly/pom.xml
@@ -0,0 +1,504 @@
+<?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-testsuite-pom</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.3.0.Beta1-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-testsuite-wildfly</artifactId>
+    <name>Keycloak WildFly 9.x Integration TestSuite</name>
+    <description />
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-dependencies-server-all</artifactId>
+            <type>pom</type>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-admin-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.6.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.6.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.spec.javax.servlet</groupId>
+            <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>jaxrs-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jaxrs</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-simple</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-multipart-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-jackson-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.resteasy</groupId>
+            <artifactId>resteasy-undertow</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>javase</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-ldap-federation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-kerberos-federation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-undertow-adapter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-wildfly-adapter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.undertow</groupId>
+            <artifactId>undertow-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.undertow</groupId>
+            <artifactId>undertow-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-xc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate.javax.persistence</groupId>
+            <artifactId>hibernate-jpa-2.0-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-entitymanager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.icegreen</groupId>
+            <artifactId>greenmail</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.infinispan</groupId>
+            <artifactId>infinispan-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>xml-apis</groupId>
+            <artifactId>xml-apis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-chrome-driver</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wildfly</groupId>
+            <artifactId>wildfly-undertow</artifactId>
+            <version>${wildfly.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-testsuite-integration</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-testsuite-integration</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jaas</artifactId>
+            <version>${jetty9.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty9.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+            <version>${jetty9.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-security</artifactId>
+            <version>${jetty9.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <version>${jetty9.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.2</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <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>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <configuration>
+                    <workingDirectory>${project.basedir}</workingDirectory>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>keycloak-server</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <configuration>
+                            <mainClass>org.keycloak.testsuite.KeycloakServer</mainClass>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>mail-server</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <configuration>
+                            <mainClass>org.keycloak.testsuite.MailServer</mainClass>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>totp</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <configuration>
+                            <mainClass>org.keycloak.testsuite.TotpGenerator</mainClass>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>jpa</id>
+
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <systemPropertyVariables>
+                                <keycloak.realm.provider>jpa</keycloak.realm.provider>
+                                <keycloak.user.provider>jpa</keycloak.user.provider>
+                                <keycloak.eventStore.provider>jpa</keycloak.eventStore.provider>
+                                <keycloak.userSessions.provider>jpa</keycloak.userSessions.provider>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>mongo</id>
+
+            <properties>
+                <keycloak.connectionsMongo.host>localhost</keycloak.connectionsMongo.host>
+                <keycloak.connectionsMongo.port>27018</keycloak.connectionsMongo.port>
+                <keycloak.connectionsMongo.db>keycloak</keycloak.connectionsMongo.db>
+                <keycloak.connectionsMongo.clearOnStartup>true</keycloak.connectionsMongo.clearOnStartup>
+                <keycloak.connectionsMongo.bindIp>127.0.0.1</keycloak.connectionsMongo.bindIp>
+            </properties>
+
+            <build>
+                <plugins>
+
+                    <!-- Postpone tests to "integration-test" phase, so that we can bootstrap embedded mongo on 27018 before running tests -->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>test</id>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>test</goal>
+                                </goals>
+                                <configuration>
+                                    <systemPropertyVariables>
+                                        <keycloak.realm.provider>mongo</keycloak.realm.provider>
+                                        <keycloak.user.provider>mongo</keycloak.user.provider>
+                                        <keycloak.audit.provider>mongo</keycloak.audit.provider>
+                                        <keycloak.userSessions.provider>mongo</keycloak.userSessions.provider>
+                                        <keycloak.connectionsMongo.host>${keycloak.connectionsMongo.host}</keycloak.connectionsMongo.host>
+                                        <keycloak.connectionsMongo.port>${keycloak.connectionsMongo.port}</keycloak.connectionsMongo.port>
+                                        <keycloak.connectionsMongo.db>${keycloak.connectionsMongo.db}</keycloak.connectionsMongo.db>
+                                        <keycloak.connectionsMongo.clearOnStartup>${keycloak.connectionsMongo.clearOnStartup}</keycloak.connectionsMongo.clearOnStartup>
+                                        <keycloak.connectionsMongo.bindIp>${keycloak.connectionsMongo.bindIp}</keycloak.connectionsMongo.bindIp>
+                                    </systemPropertyVariables>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>default-test</id>
+                                <configuration>
+                                    <skip>true</skip>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+
+                    <!-- Embedded mongo -->
+                    <plugin>
+                        <groupId>com.github.joelittlejohn.embedmongo</groupId>
+                        <artifactId>embedmongo-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>start-mongodb</id>
+                                <phase>pre-integration-test</phase>
+                                <goals>
+                                    <goal>start</goal>
+                                </goals>
+                                <configuration>
+                                    <port>${keycloak.connectionsMongo.port}</port>
+                                    <logging>file</logging>
+                                    <logFile>${project.build.directory}/mongodb.log</logFile>
+                                    <bindIp>${keycloak.connectionsMongo.bindIp}</bindIp>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>stop-mongodb</id>
+                                <phase>post-integration-test</phase>
+                                <goals>
+                                    <goal>stop</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+
+        </profile>
+
+        <profile>
+            <id>infinispan</id>
+
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <systemPropertyVariables>
+                                <keycloak.realm.cache.provider>infinispan</keycloak.realm.cache.provider>
+                                <keycloak.user.cache.provider>infinispan</keycloak.user.cache.provider>
+                                <keycloak.userSessions.provider>infinispan</keycloak.userSessions.provider>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <!-- MySQL -->
+        <profile>
+            <activation>
+                <property>
+                    <name>keycloak.connectionsJpa.driver</name>
+                    <value>com.mysql.jdbc.Driver</value>
+                </property>
+            </activation>
+            <id>mysql</id>
+            <dependencies>
+                <dependency>
+                    <groupId>mysql</groupId>
+                    <artifactId>mysql-connector-java</artifactId>
+                    <version>${mysql.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <!-- PostgreSQL -->
+        <profile>
+            <activation>
+                <property>
+                    <name>keycloak.connectionsJpa.driver</name>
+                    <value>org.postgresql.Driver</value>
+                </property>
+            </activation>
+            <id>postgresql</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.postgresql</groupId>
+                    <artifactId>postgresql</artifactId>
+                    <version>${postgresql.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
+            <id>clean-jpa</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.liquibase</groupId>
+                        <artifactId>liquibase-maven-plugin</artifactId>
+                        <configuration>
+                            <changeLogFile>META-INF/jpa-changelog-master.xml</changeLogFile>
+
+                            <url>${keycloak.connectionsJpa.url}</url>
+                            <driver>${keycloak.connectionsJpa.driver}</driver>
+                            <username>${keycloak.connectionsJpa.user}</username>
+                            <password>${keycloak.connectionsJpa.password}</password>
+
+                            <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>clean-jpa</id>
+                                <phase>clean</phase>
+                                <goals>
+                                    <goal>dropAll</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/testsuite/wildfly/src/test/config/arq/arquillian.xml b/testsuite/wildfly/src/test/config/arq/arquillian.xml
new file mode 100644
index 0000000..7fcf61c
--- /dev/null
+++ b/testsuite/wildfly/src/test/config/arq/arquillian.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+    <defaultProtocol type="jmx-as7" />
+
+    <container qualifier="jboss" default="true">
+        <configuration>
+            <property name="jbossHome">${basedir}/target/jbossas</property>
+            <property name="javaVmArguments">${server.jvm.args} -Djboss.inst=${basedir}/target/jbossas -Dtest.bind.address=${node0}</property>
+            <property name="serverConfig">${jboss.server.config.file.name:standalone.xml}</property>
+            <property name="jbossArguments">${jboss.args}</property>
+            <!-- -Djboss.inst is not necessarily needed, only in case the test case neeeds path to the instance it runs in.
+                 In the future, Arquillian should capable of injecting it into @ArquillianResource File or such. -->
+            <property name="allowConnectingToRunningServer">true</property>
+            <property name="managementAddress">${node0:127.0.0.1}</property>
+            <property name="managementPort">${as.managementPort:9990}</property>
+
+            <!-- AS7-4070 -->
+            <property name="waitForPorts">${as.debug.port:8787} ${as.managementPort:9990}</property>
+            <property name="waitForPortsTimeoutInSeconds">8</property>
+        </configuration>
+    </container>
+
+</arquillian>
diff --git a/timer/api/src/main/java/org/keycloak/timer/TimerSpi.java b/timer/api/src/main/java/org/keycloak/timer/TimerSpi.java
index d0e57f9..ac92339 100644
--- a/timer/api/src/main/java/org/keycloak/timer/TimerSpi.java
+++ b/timer/api/src/main/java/org/keycloak/timer/TimerSpi.java
@@ -8,6 +8,12 @@ import org.keycloak.provider.Spi;
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
  */
 public class TimerSpi implements Spi {
+
+    @Override
+    public boolean isPrivate() {
+        return true;
+    }
+
     @Override
     public String getName() {
         return "timer";