You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/08/02 07:45:15 UTC

[01/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Repository: syncope
Updated Branches:
  refs/heads/SYNCOPE-652 eec12cd84 -> 34a1c2147


http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index f6d2e57..9f277fa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -126,7 +126,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         task = taskService.read(actual.getKey());
         assertNotNull(task);
         assertEquals(actual.getKey(), task.getKey());
-        assertEquals(actual.getJobClassName(), task.getJobClassName());
+        assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName());
         assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
         assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
     }
@@ -231,14 +231,11 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertNotNull(userTO);
             assertEquals("active", userTO.getStatus());
 
-            // SYNCOPE-317
-            execProvisioningTask(SYNC_TASK_ID, 50, false);
-
-            final Set<Long> pushTaskIds = new HashSet<>();
-            pushTaskIds.add(25L);
-            pushTaskIds.add(26L);
+            Set<Long> otherSyncTaskKeys = new HashSet<>();
+            otherSyncTaskKeys.add(25L);
+            otherSyncTaskKeys.add(26L);
+            execProvisioningTasks(otherSyncTaskKeys, 50, false);
 
-            execProvisioningTasks(pushTaskIds, 50, false);
             // Matching --> UNLINK
             assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
             assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
@@ -290,7 +287,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                 build());
         if (matchingGroups.getSize() > 0) {
             for (GroupTO group : matchingGroups.getResult()) {
-                groupService.bulkDeassociation(group.getKey(),
+                groupService.deassociate(group.getKey(),
                         ResourceDeassociationActionType.UNLINK,
                         CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
                 groupService.delete(group.getKey());
@@ -302,7 +299,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                 build());
         if (matchingUsers.getSize() > 0) {
             for (UserTO user : matchingUsers.getResult()) {
-                userService.bulkDeassociation(user.getKey(),
+                userService.deassociate(user.getKey(),
                         ResourceDeassociationActionType.UNLINK,
                         CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
                 userService.delete(user.getKey());
@@ -352,6 +349,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
         assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
         assertNull(groupTO.getGroupOwner());
+
+        // SYNCOPE-317
+        execProvisioningTask(11L, 50, false);
     }
 
     @Test
@@ -376,7 +376,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                         is("location").equalTo("sync*").query()).build());
         assertTrue(matchingPrinters.getSize() > 0);
         for (AnyObjectTO printer : matchingPrinters.getResult()) {
-            anyObjectService.bulkDeassociation(printer.getKey(),
+            anyObjectService.deassociate(printer.getKey(),
                     ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(RESOURCE_NAME_DBSCRIPTED, ResourceKey.class));
             anyObjectService.delete(printer.getKey());
@@ -678,7 +678,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         syncTask = taskService.read(actual.getKey());
         assertNotNull(syncTask);
         assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
 
         TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
         final String status = execution.getStatus();
@@ -755,7 +755,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         syncTask = taskService.read(actual.getKey());
         assertNotNull(syncTask);
         assertEquals(actual.getKey(), syncTask.getKey());
-        assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+        assertEquals(actual.getJobDelegateClassName(), syncTask.getJobDelegateClassName());
 
         TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
         String status = execution.getStatus();

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 10b07bf..4cecdf7 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -47,7 +47,6 @@ import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
@@ -70,7 +69,7 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
@@ -436,7 +435,7 @@ public class UserITCase extends AbstractITCase {
             createUser(userTO);
             fail();
         } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.DataIntegrityViolation, e.getType());
+            assertEquals(ClientExceptionType.GenericPersistence, e.getType());
         }
     }
 
@@ -923,8 +922,9 @@ public class UserITCase extends AbstractITCase {
         assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
     }
 
+    @Test
     public void updateMultivalueAttribute() {
-        UserTO userTO = getSampleTO("multivalue@syncope.apache.org");
+        UserTO userTO = getUniqueSampleTO("multivalue@syncope.apache.org");
         userTO.getResources().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
@@ -938,11 +938,8 @@ public class UserITCase extends AbstractITCase {
 
         UserMod userMod = new UserMod();
 
-        AttrMod loginDateMod = new AttrMod();
-        loginDateMod.getValuesToBeAdded().add("2000-01-01");
-
         userMod.setKey(userTO.getKey());
-        userMod.getPlainAttrsToUpdate().add(loginDateMod);
+        userMod.getPlainAttrsToUpdate().add(attrMod("loginDate", "2000-01-01"));
 
         userTO = updateUser(userMod);
         assertNotNull(userTO);
@@ -1519,18 +1516,15 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void issueSYNCOPE265() {
-        for (long i = 1; i <= 5; i++) {
+        for (long key = 1; key <= 5; key++) {
             UserMod userMod = new UserMod();
-            userMod.setKey(i);
-
-            AttrMod attributeMod = new AttrMod();
-            attributeMod.setSchema("type");
-            attributeMod.getValuesToBeAdded().add("a type");
+            userMod.setKey(key);
 
             userMod.getPlainAttrsToRemove().add("type");
-            userMod.getPlainAttrsToUpdate().add(attributeMod);
+            userMod.getPlainAttrsToUpdate().add(attrMod("type", "a type"));
 
             UserTO userTO = updateUser(userMod);
+
             assertEquals("a type", userTO.getPlainAttrMap().get("type").getValues().get(0));
         }
     }
@@ -1549,21 +1543,21 @@ public class UserITCase extends AbstractITCase {
 
         assertEquals(11, bulkAction.getTargets().size());
 
-        bulkAction.setOperation(BulkAction.Type.SUSPEND);
+        bulkAction.setType(BulkAction.Type.SUSPEND);
         BulkActionResult res = userService.bulk(bulkAction);
         assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
         assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
         assertEquals("suspended", userService.read(
                 Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
 
-        bulkAction.setOperation(BulkAction.Type.REACTIVATE);
+        bulkAction.setType(BulkAction.Type.REACTIVATE);
         res = userService.bulk(bulkAction);
         assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
         assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
         assertEquals("active", userService.read(
                 Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
 
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
         res = userService.bulk(bulkAction);
         assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
         assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
@@ -1765,7 +1759,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -1801,8 +1795,7 @@ public class UserITCase extends AbstractITCase {
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
 
-        assertNotNull(userService.bulkAssociation(
-                actual.getKey(), ResourceAssociationActionType.LINK, associationMod).readEntity(BulkActionResult.class));
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
@@ -1831,7 +1824,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -1869,12 +1862,12 @@ public class UserITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
-        final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
-        assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.ASSIGN, associationMod)
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.ASSIGN, associationMod)
                 .readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
@@ -1898,7 +1891,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(actual);
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -1936,14 +1929,13 @@ public class UserITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
-        final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
-        assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.PROVISION,
-                associationMod)
-                .readEntity(BulkActionResult.class));
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.PROVISION, associationMod).
+                readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
         assertNotNull(actual);
@@ -1977,7 +1969,7 @@ public class UserITCase extends AbstractITCase {
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
-        assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.PROVISION,
+        assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.PROVISION,
                 associationMod)
                 .readEntity(BulkActionResult.class));
 
@@ -1986,7 +1978,7 @@ public class UserITCase extends AbstractITCase {
         assertTrue(actual.getResources().isEmpty());
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
 
-        assertNotNull(userService.bulkDeassociation(actual.getKey(),
+        assertNotNull(userService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));


[13/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
index c8274a4..86e6583 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEnforcer.java
@@ -23,5 +23,13 @@ import org.apache.syncope.common.lib.types.PolicyType;
 
 public interface PolicyEnforcer<T extends PolicySpec, E> {
 
-    void enforce(final T policy, final PolicyType type, final E object);
+    /**
+     * Check the given entity to see if it conforms with the indicated policy.
+     *
+     * @param policy
+     * @param type
+     * @param entity
+     * @return whether user is to be suspended
+     */
+    boolean enforce(final T policy, final PolicyType type, final E entity);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
index 52fa0d8..fd6abd2 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyEvaluator.java
@@ -34,9 +34,6 @@ import org.springframework.stereotype.Component;
 @Component
 public class PolicyEvaluator {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(PolicyEvaluator.class);
 
     @SuppressWarnings("unchecked")
@@ -54,7 +51,7 @@ public class PolicyEvaluator {
                 BeanUtils.copyProperties(ppSpec, evaluatedPPSpec, new String[] { "schemasNotPermitted" });
 
                 for (String schema : ppSpec.getSchemasNotPermitted()) {
-                    PlainAttr attr = any.getPlainAttr(schema);
+                    PlainAttr<?> attr = any.getPlainAttr(schema);
                     if (attr != null) {
                         List<String> values = attr.getValuesAsStrings();
                         if (values != null && !values.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
index 932627d..38240d9 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
@@ -18,12 +18,18 @@
  */
 package org.apache.syncope.core.misc.security;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
@@ -79,6 +85,27 @@ public final class AuthContextUtils {
         return domainKey;
     }
 
+    public static void setFakeAuth(final String domain) {
+        List<GrantedAuthority> authorities = CollectionUtils.collect(Entitlement.values(),
+                new Transformer<String, GrantedAuthority>() {
+
+                    @Override
+                    public GrantedAuthority transform(final String entitlement) {
+                        return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+                    }
+                }, new ArrayList<GrantedAuthority>());
+
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new User(ApplicationContextProvider.getBeanFactory().getBean("adminUser", String.class),
+                        "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails(domain));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+
+    public static void clearFakeAuth() {
+        SecurityContextHolder.clearContext();
+    }
+
     /**
      * Private default constructor, for static-only classes.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
index eab59bb..44635be 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
@@ -215,7 +215,7 @@ public class PasswordGenerator {
         String[] generatedPassword = new String[policySpec.getMinLength()];
 
         for (int i = 0; i < generatedPassword.length; i++) {
-            generatedPassword[i] = "";
+            generatedPassword[i] = StringUtils.EMPTY;
         }
 
         checkStartChar(generatedPassword, policySpec);
@@ -224,7 +224,6 @@ public class PasswordGenerator {
 
         checkRequired(generatedPassword, policySpec);
 
-        //filled empty chars
         for (int firstEmptyChar = firstEmptyChar(generatedPassword);
                 firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
 
@@ -252,6 +251,10 @@ public class PasswordGenerator {
         if (policySpec.isMustntStartWithNonAlpha()) {
             generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
         }
+
+        if (StringUtils.EMPTY.equals(generatedPassword[0])) {
+            generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+        }
     }
 
     private void checkEndChar(final String[] generatedPassword, final PasswordPolicySpec policySpec) {
@@ -271,6 +274,10 @@ public class PasswordGenerator {
         if (policySpec.isMustntEndWithNonAlpha()) {
             generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
         }
+
+        if (StringUtils.EMPTY.equals(generatedPassword[policySpec.getMinLength() - 1])) {
+            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+        }
     }
 
     private int firstEmptyChar(final String[] generatedPStrings) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
index 01abb93..f452128 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
@@ -191,23 +191,23 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
 
             auditManager.audit(
                     AuditElements.EventCategoryType.REST,
-                    "AuthenticationController",
+                    AuditElements.AUTHENTICATION_CATEGORY,
                     null,
-                    "login",
+                    AuditElements.LOGIN_EVENT,
                     Result.SUCCESS,
                     null,
                     authenticated,
                     authentication,
-                    "Successfully authenticated, with groups: " + token.getAuthorities());
+                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
 
             LOG.debug("User {} successfully authenticated, with groups {}",
                     authentication.getPrincipal(), token.getAuthorities());
         } else {
             auditManager.audit(
                     AuditElements.EventCategoryType.REST,
-                    "AuthenticationController",
+                    AuditElements.AUTHENTICATION_CATEGORY,
                     null,
-                    "login",
+                    AuditElements.LOGIN_EVENT,
                     Result.FAILURE,
                     null,
                     authenticated,

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
index f8f974b..100de17 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
@@ -27,6 +27,8 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.SetUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.core.misc.RealmUtils;
 import org.springframework.security.core.GrantedAuthority;
 
@@ -80,4 +82,9 @@ public class SyncopeGrantedAuthority implements GrantedAuthority {
         return HashCodeBuilder.reflectionHashCode(this);
     }
 
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
index 1aa4367..e67dcd6 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
@@ -27,12 +27,22 @@ public class ApplicationContextProvider implements ApplicationContextAware {
 
     private static ConfigurableApplicationContext CTX;
 
+    private static DefaultListableBeanFactory BEAN_FACTORY;
+
     public static ConfigurableApplicationContext getApplicationContext() {
         return CTX;
     }
 
     public static DefaultListableBeanFactory getBeanFactory() {
-        return (DefaultListableBeanFactory) CTX.getBeanFactory();
+        return BEAN_FACTORY == null
+                ? CTX == null
+                        ? null
+                        : (DefaultListableBeanFactory) CTX.getBeanFactory()
+                : BEAN_FACTORY;
+    }
+
+    public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
+        BEAN_FACTORY = beanFactory;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java
new file mode 100644
index 0000000..1d8e27c
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/DomainsHolder.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.persistence.api;
+
+import java.util.Map;
+import javax.sql.DataSource;
+
+public interface DomainsHolder {
+
+    Map<String, DataSource> getDomains();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
index 67508f7..5ed50df 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java
@@ -24,6 +24,6 @@ import org.xml.sax.SAXException;
 
 public interface ContentExporter {
 
-    void export(OutputStream output, String uwfPrefix, String rwfPrefix) 
+    void export(String domain, OutputStream output, String uwfPrefix, String rwfPrefix) 
             throws SAXException, TransformerConfigurationException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
index eb00a0d..4452890 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DAO.java
@@ -22,8 +22,6 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
 
 public interface DAO<E extends Entity<KEY>, KEY> {
 
-    String getDomain(E entity);
-
     void refresh(E entity);
 
     void detach(E entity);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
index 734194b..0913ee1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SchedTask.java
@@ -24,7 +24,7 @@ public interface SchedTask extends Task {
 
     String getDescription();
 
-    String getJobClassName();
+    String getJobDelegateClassName();
 
     String getName();
 
@@ -32,7 +32,7 @@ public interface SchedTask extends Task {
 
     void setDescription(String description);
 
-    void setJobClassName(String jobClassName);
+    void setJobDelegateClassName(String jobDelegateClassName);
 
     void setName(String name);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index f60f3da..7f1ff38 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -80,6 +80,11 @@ under the License.
     </dependency>
       
     <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>aspectjweaver</artifactId>
+    </dependency>
+    
+    <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
index 3bec6b1..9e44efe 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/AbstractContentDealer.java
@@ -18,17 +18,10 @@
  */
 package org.apache.syncope.core.persistence.jpa.content;
 
-import java.io.IOException;
-import java.util.Properties;
-import javax.annotation.Resource;
-import javax.sql.DataSource;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.support.PropertiesLoaderUtils;
-import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
 
 public abstract class AbstractContentDealer {
 
@@ -36,53 +29,7 @@ public abstract class AbstractContentDealer {
 
     protected static final String ROOT_ELEMENT = "dataset";
 
-    @Resource(name = "database.schema")
-    protected String dbSchema;
-
-    @Resource(name = "indexesXML")
-    private ResourceWithFallbackLoader indexesXML;
-
-    @Resource(name = "viewsXML")
-    private ResourceWithFallbackLoader viewsXML;
-
     @Autowired
-    protected DataSource dataSource;
-
-    protected void createIndexes() throws IOException {
-        LOG.debug("Creating indexes");
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
-        Properties indexes = PropertiesLoaderUtils.loadProperties(indexesXML.getResource());
-        for (String idx : indexes.stringPropertyNames()) {
-            LOG.debug("Creating index {}", indexes.get(idx).toString());
-
-            try {
-                jdbcTemplate.execute(indexes.get(idx).toString());
-            } catch (DataAccessException e) {
-                LOG.error("Could not create index ", e);
-            }
-        }
-
-        LOG.debug("Indexes created");
-    }
-
-    protected void createViews() throws IOException {
-        LOG.debug("Creating views");
-
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
-        Properties views = PropertiesLoaderUtils.loadProperties(viewsXML.getResource());
-        for (String idx : views.stringPropertyNames()) {
-            LOG.debug("Creating view {}", views.get(idx).toString());
-
-            try {
-                jdbcTemplate.execute(views.get(idx).toString().replaceAll("\\n", " "));
-            } catch (DataAccessException e) {
-                LOG.error("Could not create view ", e);
-            }
-        }
+    protected DomainsHolder domainsHolder;
 
-        LOG.debug("Views created");
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index ea13072..17f4bce 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -40,6 +40,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import javax.sql.DataSource;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
@@ -50,6 +51,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr;
@@ -91,30 +93,13 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
                 JPAARelationship.TABLE, JPAAMembership.TABLE, JPAURelationship.TABLE, JPAUMembership.TABLE
             }));
 
-    protected static final Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED =
-            new HashSet<>(Arrays.asList(new String[] { "TEMPLATE" }));
-
     protected static final Map<String, String> TABLES_TO_BE_FILTERED =
             Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
 
     protected static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
             Collections.singletonMap("SYNCOPEGROUP", Collections.singleton("USEROWNER_ID"));
 
-    private boolean isTableAllowed(final String tableName) {
-        boolean allowed = true;
-        for (String prefix : TABLE_PREFIXES_TO_BE_EXCLUDED) {
-            if (tableName.toUpperCase().startsWith(prefix)) {
-                for (String suffix : TABLE_SUFFIXES_TO_BE_INCLUDED) {
-                    if (!tableName.toUpperCase().endsWith(suffix)) {
-                        allowed = false;
-                    }
-                }
-            }
-        }
-        return allowed;
-    }
-
-    private List<String> sortByForeignKeys(final Connection conn, final Set<String> tableNames)
+    private List<String> sortByForeignKeys(final String dbSchema, final Connection conn, final Set<String> tableNames)
             throws SQLException {
 
         Set<MultiParentNode<String>> roots = new HashSet<>();
@@ -325,7 +310,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
     }
 
     @Override
-    public void export(final OutputStream os, final String uwfPrefix, final String rwfPrefix)
+    public void export(final String domain, final OutputStream os, final String uwfPrefix, final String rwfPrefix)
             throws SAXException, TransformerConfigurationException {
 
         if (StringUtils.isNotBlank(uwfPrefix)) {
@@ -346,6 +331,13 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
         handler.startDocument();
         handler.startElement("", "", ROOT_ELEMENT, new AttributesImpl());
 
+        DataSource dataSource = domainsHolder.getDomains().get(domain);
+        if (dataSource == null) {
+            throw new IllegalArgumentException("Could not find DataSource for domain " + domain);
+        }
+
+        String dbSchema = ApplicationContextProvider.getBeanFactory().getBean(domain + "DatabaseSchema", String.class);
+
         Connection conn = null;
         ResultSet rs = null;
         try {
@@ -359,15 +351,13 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
             while (rs.next()) {
                 String tableName = rs.getString("TABLE_NAME");
                 LOG.debug("Found table {}", tableName);
-                if (isTableAllowed(tableName)) {
-                    tableNames.add(tableName);
-                }
+                tableNames.add(tableName);
             }
 
             LOG.debug("Tables to be exported {}", tableNames);
 
             // then sort tables based on foreign keys and dump
-            for (String tableName : sortByForeignKeys(conn, tableNames)) {
+            for (String tableName : sortByForeignKeys(dbSchema, conn, tableNames)) {
                 try {
                     doExportTable(handler, conn, tableName, TABLES_TO_BE_FILTERED.get(tableName.toUpperCase()));
                 } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
index 086adfd..5d8cfc5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
@@ -20,17 +20,22 @@ package org.apache.syncope.core.persistence.jpa.content;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
 import javax.annotation.Resource;
+import javax.sql.DataSource;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import org.apache.commons.io.IOUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.springframework.core.io.support.PropertiesLoaderUtils;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Initialize Database with default content if no data is present already.
@@ -38,47 +43,59 @@ import org.springframework.transaction.annotation.Transactional;
 @Component
 public class XMLContentLoader extends AbstractContentDealer implements ContentLoader {
 
-    @Resource(name = "contentXML")
-    private ResourceWithFallbackLoader contentXML;
+    @Resource(name = "indexesXML")
+    private ResourceWithFallbackLoader indexesXML;
+
+    @Resource(name = "viewsXML")
+    private ResourceWithFallbackLoader viewsXML;
 
     @Override
     public Integer getPriority() {
         return 0;
     }
 
-    @Transactional
     @Override
     public void load() {
-        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
-        boolean existingData;
-        try {
-            existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0;
-        } catch (DataAccessException e) {
-            LOG.error("Could not access to table " + JPAConf.TABLE, e);
-            existingData = true;
-        }
-
-        if (existingData) {
-            LOG.info("Data found in the database, leaving untouched");
-        } else {
-            LOG.info("Empty database found, loading default content");
+        for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+            // create EntityManager so OpenJPA will build the SQL schema
+            EntityManagerFactoryUtils.findEntityManagerFactory(
+                    ApplicationContextProvider.getBeanFactory(), entry.getKey()).createEntityManager();
 
+            JdbcTemplate jdbcTemplate = new JdbcTemplate(entry.getValue());
+            boolean existingData;
             try {
-                loadDefaultContent();
-            } catch (Exception e) {
-                LOG.error("While loading default content", e);
+                existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + JPAConf.TABLE, Integer.class) > 0;
+            } catch (DataAccessException e) {
+                LOG.error("[{}] Could not access to table " + JPAConf.TABLE, entry.getKey(), e);
+                existingData = true;
             }
-            try {
-                createIndexes();
-                createViews();
-            } catch (IOException e) {
-                LOG.error("While creating indexes and views", e);
+
+            if (existingData) {
+                LOG.info("[{}] Data found in the database, leaving untouched", entry.getKey());
+            } else {
+                LOG.info("[{}] Empty database found, loading default content", entry.getKey());
+
+                try {
+                    ResourceWithFallbackLoader contentXML = ApplicationContextProvider.getBeanFactory().
+                            getBean(entry.getKey() + "ContentXML", ResourceWithFallbackLoader.class);
+                    loadDefaultContent(entry.getKey(), contentXML, entry.getValue());
+                } catch (Exception e) {
+                    LOG.error("[{}] While loading default content", entry.getKey(), e);
+                }
+                try {
+                    createIndexes(entry.getKey(), entry.getValue());
+                    createViews(entry.getKey(), entry.getValue());
+                } catch (IOException e) {
+                    LOG.error("[{}] While creating indexes and views", entry.getKey(), e);
+                }
             }
         }
     }
 
-    private void loadDefaultContent() throws Exception {
+    private void loadDefaultContent(
+            final String domain, final ResourceWithFallbackLoader contentXML, final DataSource dataSource)
+            throws Exception {
+
         SAXParserFactory factory = SAXParserFactory.newInstance();
         InputStream in = null;
         try {
@@ -86,9 +103,47 @@ public class XMLContentLoader extends AbstractContentDealer implements ContentLo
 
             SAXParser parser = factory.newSAXParser();
             parser.parse(in, new ContentLoaderHandler(dataSource, ROOT_ELEMENT));
-            LOG.debug("Default content successfully loaded");
+            LOG.debug("[{}] Default content successfully loaded", domain);
         } finally {
             IOUtils.closeQuietly(in);
         }
     }
+
+    private void createIndexes(final String domain, final DataSource dataSource) throws IOException {
+        LOG.debug("[{}] Creating indexes", domain);
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+
+        Properties indexes = PropertiesLoaderUtils.loadProperties(indexesXML.getResource());
+        for (String idx : indexes.stringPropertyNames()) {
+            LOG.debug("[{}] Creating index {}", domain, indexes.get(idx).toString());
+
+            try {
+                jdbcTemplate.execute(indexes.get(idx).toString());
+            } catch (DataAccessException e) {
+                LOG.error("[{}] Could not create index", domain, e);
+            }
+        }
+
+        LOG.debug("Indexes created");
+    }
+
+    private void createViews(final String domain, final DataSource dataSource) throws IOException {
+        LOG.debug("[{}] Creating views", domain);
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+
+        Properties views = PropertiesLoaderUtils.loadProperties(viewsXML.getResource());
+        for (String idx : views.stringPropertyNames()) {
+            LOG.debug("[{}] Creating view {}", domain, views.get(idx).toString());
+
+            try {
+                jdbcTemplate.execute(views.get(idx).toString().replaceAll("\\n", " "));
+            } catch (DataAccessException e) {
+                LOG.error("[{}] Could not create view", domain, e);
+            }
+        }
+
+        LOG.debug("Views created");
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index ef2161e..95f5b4e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import static org.apache.syncope.core.persistence.jpa.dao.AbstractDAO.LOG;
-
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -54,6 +52,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO<A, Long> implements AnyDAO<A> {
 
@@ -81,6 +80,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
 
     protected abstract void securityChecks(A any);
 
+    @Transactional(readOnly = true)
     @Override
     public A authFind(final Long key) {
         if (key == null) {
@@ -98,16 +98,17 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
         return any;
     }
 
+    @Transactional(readOnly = true)
     @Override
     @SuppressWarnings("unchecked")
     public A find(final Long key) {
-        return (A) entityManager.find(getAnyUtils().anyClass(), key);
+        return (A) entityManager().find(getAnyUtils().anyClass(), key);
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public A findByWorkflowId(final String workflowId) {
-        Query query = entityManager.createQuery("SELECT e FROM " + getAnyUtils().anyClass().getSimpleName()
+        Query query = entityManager().createQuery("SELECT e FROM " + getAnyUtils().anyClass().getSimpleName()
                 + " e WHERE e.workflowId = :workflowId", User.class);
         query.setParameter("workflowId", workflowId);
 
@@ -122,7 +123,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
     }
 
     private Query findByAttrValueQuery(final String entityName) {
-        return entityManager.createQuery("SELECT e FROM " + entityName + " e"
+        return entityManager().createQuery("SELECT e FROM " + entityName + " e"
                 + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL"
                 + " AND e.stringValue = :stringValue)"
                 + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)"
@@ -362,7 +363,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
             }
         }
 
-        Query query = entityManager.createNativeQuery(querystring.toString());
+        Query query = entityManager().createNativeQuery(querystring.toString());
 
         List<A> result = new ArrayList<>();
         for (Object anyKey : query.getResultList()) {
@@ -378,7 +379,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
     @SuppressWarnings("unchecked")
     @Override
     public List<A> findByResource(final ExternalResource resource) {
-        Query query = entityManager.createQuery(
+        Query query = entityManager().createQuery(
                 "SELECT e FROM " + getAnyUtils().anyClass().getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources");
         query.setParameter("resource", resource);
@@ -414,7 +415,7 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
 
     @Override
     public A save(final A any) {
-        A merged = entityManager.merge(any);
+        A merged = entityManager().merge(any);
         for (VirAttr<?> virAttr : merged.getVirAttrs()) {
             virAttr.getValues().clear();
             virAttr.getValues().addAll(any.getVirAttr(virAttr.getSchema().getKey()).getValues());

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index f4916c7..e5c1d66 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -20,17 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.DAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.util.ReflectionUtils;
 
 @Configurable
@@ -38,9 +37,16 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
 
     protected static final Logger LOG = LoggerFactory.getLogger(DAO.class);
 
-    @Value("#{entityManager}")
-    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
-    protected EntityManager entityManager;
+    protected EntityManager entityManager() {
+        EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(
+                EntityManagerFactoryUtils.findEntityManagerFactory(
+                        ApplicationContextProvider.getBeanFactory(), AuthContextUtils.getDomain()));
+        if (entityManager == null) {
+            throw new IllegalStateException("Could not find EntityManager for domain " + AuthContextUtils.getDomain());
+        }
+
+        return entityManager;
+    }
 
     protected String toOrderByStatement(final Class<? extends Entity<KEY>> beanClass, final String prefix,
             final List<OrderByClause> orderByClauses) {
@@ -64,27 +70,22 @@ public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E,
     }
 
     @Override
-    public String getDomain(final E entity) {
-        return SyncopeConstants.MASTER_DOMAIN;
-    }
-
-    @Override
     public void refresh(final E entity) {
-        entityManager.refresh(entity);
+        entityManager().refresh(entity);
     }
 
     @Override
     public void detach(final E entity) {
-        entityManager.detach(entity);
+        entityManager().detach(entity);
     }
 
     @Override
     public void flush() {
-        entityManager.flush();
+        entityManager().flush();
     }
 
     @Override
     public void clear() {
-        entityManager.clear();
+        entityManager().clear();
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 968f990..75b903d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -99,7 +99,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
 
     @Override
     public List<ARelationship> findARelationships(final AnyObject anyObject) {
-        TypedQuery<ARelationship> query = entityManager.createQuery(
+        TypedQuery<ARelationship> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAARelationship.class.getSimpleName()
                 + " e WHERE e.rightEnd=:anyObject", ARelationship.class);
         query.setParameter("anyObject", anyObject);
@@ -109,7 +109,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
 
     @Override
     public List<URelationship> findURelationships(final AnyObject anyObject) {
-        TypedQuery<URelationship> query = entityManager.createQuery(
+        TypedQuery<URelationship> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAURelationship.class.getSimpleName()
                 + " e WHERE e.rightEnd=:anyObject", URelationship.class);
         query.setParameter("anyObject", anyObject);
@@ -132,13 +132,13 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
             group.getADynMembership().remove(any);
         }
 
-        entityManager.remove(any);
+        entityManager().remove(any);
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Group> findDynGroupMemberships(final AnyObject anyObject) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
                 + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
         query.setParameter("anyObject", anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index e0eae6a..2b422eb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -143,7 +143,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         queryString.insert(0, "SELECT COUNT(any_id) FROM (");
         queryString.append(") count_any_id");
 
-        Query countQuery = entityManager.createNativeQuery(queryString.toString());
+        Query countQuery = entityManager().createNativeQuery(queryString.toString());
         fillWithParameters(countQuery, parameters);
 
         return ((Number) countQuery.getSingleResult()).intValue();
@@ -208,7 +208,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
             queryString.append(") u WHERE any_id=?").append(setParameter(parameters, any.getKey()));
 
             // 3. prepare the search query
-            Query query = entityManager.createNativeQuery(queryString.toString());
+            Query query = entityManager().createNativeQuery(queryString.toString());
 
             // 4. populate the search query with parameter values
             fillWithParameters(query, parameters);
@@ -371,7 +371,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
                 append(buildOrderBy(orderBySupport));
 
         // 3. prepare the search query
-        Query query = entityManager.createNativeQuery(queryString.toString());
+        Query query = entityManager().createNativeQuery(queryString.toString());
 
         // 4. page starts from 1, while setFirtResult() starts from 0
         query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index 58b547d..9a01442 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -51,19 +51,19 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
 
     @Override
     public AnyTypeClass find(final String key) {
-        return entityManager.find(JPAAnyTypeClass.class, key);
+        return entityManager().find(JPAAnyTypeClass.class, key);
     }
 
     @Override
     public List<AnyTypeClass> findAll() {
-        TypedQuery<AnyTypeClass> query = entityManager.createQuery(
+        TypedQuery<AnyTypeClass> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAnyTypeClass.class.getSimpleName() + " e ", AnyTypeClass.class);
         return query.getResultList();
     }
 
     @Override
     public AnyTypeClass save(final AnyTypeClass anyTypeClass) {
-        AnyTypeClass merge = entityManager.merge(anyTypeClass);
+        AnyTypeClass merge = entityManager().merge(anyTypeClass);
 
         for (PlainSchema schema : merge.getPlainSchemas()) {
             schema.setAnyTypeClass(merge);
@@ -99,7 +99,7 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
             type.remove(anyTypeClass);
         }
 
-        entityManager.remove(anyTypeClass);
+        entityManager().remove(anyTypeClass);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
index 4342811..cf87a3b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
@@ -32,7 +32,7 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
 
     @Override
     public AnyType find(final String key) {
-        return entityManager.find(JPAAnyType.class, key);
+        return entityManager().find(JPAAnyType.class, key);
     }
 
     @Override
@@ -50,7 +50,7 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
                 append(JPAAnyType.class.getSimpleName()).
                 append(" e WHERE :anyTypeClass MEMBER OF e.classes");
 
-        TypedQuery<AnyType> query = entityManager.createQuery(queryString.toString(), AnyType.class);
+        TypedQuery<AnyType> query = entityManager().createQuery(queryString.toString(), AnyType.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -58,14 +58,14 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
 
     @Override
     public List<AnyType> findAll() {
-        TypedQuery<AnyType> query = entityManager.createQuery(
+        TypedQuery<AnyType> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAnyType.class.getSimpleName() + " e ", AnyType.class);
         return query.getResultList();
     }
 
     @Override
     public AnyType save(final AnyType anyType) {
-        return entityManager.merge(anyType);
+        return entityManager().merge(anyType);
     }
 
     @Override
@@ -79,7 +79,7 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
             throw new IllegalArgumentException(key + " cannot be deleted");
         }
 
-        entityManager.remove(anyType);
+        entityManager().remove(anyType);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
index 7045a1a..4afe78e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
@@ -42,12 +42,12 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
 
     @Override
     public Conf get() {
-        Conf instance = entityManager.find(JPAConf.class, 1L);
+        Conf instance = entityManager().find(JPAConf.class, 1L);
         if (instance == null) {
             instance = new JPAConf();
             instance.setKey(1L);
 
-            instance = entityManager.merge(instance);
+            instance = entityManager().merge(instance);
         }
 
         return instance;
@@ -97,7 +97,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         instance.add(attr);
         attr.setOwner(instance);
 
-        return entityManager.merge(instance);
+        return entityManager().merge(instance);
     }
 
     @Override
@@ -106,7 +106,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
         CPlainAttr attr = instance.getPlainAttr(key);
         if (attr != null) {
             instance.remove(attr);
-            instance = entityManager.merge(instance);
+            instance = entityManager().merge(instance);
         }
 
         return instance;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index 453c363..eb027e9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -44,19 +44,19 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance, Long> implemen
 
     @Override
     public ConnInstance find(final Long key) {
-        return entityManager.find(JPAConnInstance.class, key);
+        return entityManager().find(JPAConnInstance.class, key);
     }
 
     @Override
     public List<ConnInstance> findAll() {
-        TypedQuery<ConnInstance> query = entityManager.createQuery(
+        TypedQuery<ConnInstance> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAConnInstance.class.getSimpleName() + " e", ConnInstance.class);
         return query.getResultList();
     }
 
     @Override
     public ConnInstance save(final ConnInstance connector) {
-        final ConnInstance merged = entityManager.merge(connector);
+        final ConnInstance merged = entityManager().merge(connector);
 
         for (ExternalResource resource : merged.getResources()) {
             try {
@@ -86,7 +86,7 @@ public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance, Long> implemen
 
                 });
 
-        entityManager.remove(connInstance);
+        entityManager().remove(connInstance);
 
         connRegistry.unregisterConnector(key.toString());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
index 2162898..8dff203 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
@@ -49,19 +49,19 @@ public class JPADerAttrDAO extends AbstractDAO<DerAttr<?>, Long> implements DerA
 
     @Override
     public <T extends DerAttr<?>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
     public <T extends DerAttr<?>> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
+        TypedQuery<T> query = entityManager().createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
     public <T extends DerAttr<?>> T save(final T derAttr) {
-        return entityManager.merge(derAttr);
+        return entityManager().merge(derAttr);
     }
 
     @Override
@@ -81,6 +81,6 @@ public class JPADerAttrDAO extends AbstractDAO<DerAttr<?>, Long> implements DerA
             ((Any<?, T, ?>) derAttr.getOwner()).remove(derAttr);
         }
 
-        entityManager.remove(derAttr);
+        entityManager().remove(derAttr);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index 18b6636..4ed17ca 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public DerSchema find(final String key) {
-        return entityManager.find(JPADerSchema.class, key);
+        return entityManager().find(JPADerSchema.class, key);
     }
 
     @Override
@@ -54,7 +54,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
                 append(JPADerSchema.class.getSimpleName()).
                 append(" e WHERE e.anyTypeClass=:anyTypeClass");
 
-        TypedQuery<DerSchema> query = entityManager.createQuery(queryString.toString(), DerSchema.class);
+        TypedQuery<DerSchema> query = entityManager().createQuery(queryString.toString(), DerSchema.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -62,7 +62,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public List<DerSchema> findAll() {
-        TypedQuery<DerSchema> query = entityManager.createQuery(
+        TypedQuery<DerSchema> query = entityManager().createQuery(
                 "SELECT e FROM " + JPADerSchema.class.getSimpleName() + " e", DerSchema.class);
         return query.getResultList();
     }
@@ -73,7 +73,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
                 append(((JPADerAttrDAO) derAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
-        TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -81,7 +81,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public DerSchema save(final DerSchema derSchema) {
-        return entityManager.merge(derSchema);
+        return entityManager().merge(derSchema);
     }
 
     @Override
@@ -106,6 +106,6 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
             schema.getAnyTypeClass().remove(schema);
         }
 
-        entityManager.remove(schema);
+        entityManager().remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
index 37a4cd2..b3bb188 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADomainDAO.java
@@ -30,19 +30,19 @@ public class JPADomainDAO extends AbstractDAO<Domain, String> implements DomainD
 
     @Override
     public Domain find(final String key) {
-        return entityManager.find(JPADomain.class, key);
+        return entityManager().find(JPADomain.class, key);
     }
 
     @Override
     public List<Domain> findAll() {
-        TypedQuery<Domain> query = entityManager.createQuery(
+        TypedQuery<Domain> query = entityManager().createQuery(
                 "SELECT e FROM " + JPADomain.class.getSimpleName() + " e ", Domain.class);
         return query.getResultList();
     }
 
     @Override
     public Domain save(final Domain anyTypeClass) {
-        return entityManager.merge(anyTypeClass);
+        return entityManager().merge(anyTypeClass);
     }
 
     @Override
@@ -52,6 +52,6 @@ public class JPADomainDAO extends AbstractDAO<Domain, String> implements DomainD
             return;
         }
 
-        entityManager.remove(domain);
+        entityManager().remove(domain);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 17553a2..4a8a759 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -71,7 +71,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     public ExternalResource find(final String name) {
-        return entityManager.find(JPAExternalResource.class, name);
+        return entityManager().find(JPAExternalResource.class, name);
     }
 
     private StringBuilder getByPolicyQuery(final PolicyType type) {
@@ -99,7 +99,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     public List<ExternalResource> findByPolicy(final Policy policy) {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 getByPolicyQuery(policy.getType()).append(" = :policy").toString(), ExternalResource.class);
         query.setParameter("policy", policy);
         return query.getResultList();
@@ -107,21 +107,21 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
 
     @Override
     public List<ExternalResource> findWithoutPolicy(final PolicyType type) {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 getByPolicyQuery(type).append(" IS NULL").toString(), ExternalResource.class);
         return query.getResultList();
     }
 
     @Override
     public List<ExternalResource> findAll() {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
         return query.getResultList();
     }
 
     @Override
     public List<ExternalResource> findAllByPriority() {
-        TypedQuery<ExternalResource> query = entityManager.createQuery(
+        TypedQuery<ExternalResource> query = entityManager().createQuery(
                 "SELECT e FROM  " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
                 ExternalResource.class);
         return query.getResultList();
@@ -138,7 +138,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
     @Override
     @Transactional(rollbackFor = { Throwable.class })
     public ExternalResource save(final ExternalResource resource) {
-        ExternalResource merged = entityManager.merge(resource);
+        ExternalResource merged = entityManager().merge(resource);
         try {
             connRegistry.registerConnector(merged);
         } catch (NotFoundException e) {
@@ -154,7 +154,7 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             return;
         }
 
-        TypedQuery<MappingItem> query = entityManager.createQuery(
+        TypedQuery<MappingItem> query = entityManager().createQuery(
                 "SELECT m FROM " + JPAMappingItem.class.getSimpleName()
                 + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", MappingItem.class);
         query.setParameter("intAttrName", intAttrName);
@@ -165,18 +165,18 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             itemKeys.add(item.getKey());
         }
         for (Long itemKey : itemKeys) {
-            MappingItem item = entityManager.find(JPAMappingItem.class, itemKey);
+            MappingItem item = entityManager().find(JPAMappingItem.class, itemKey);
             if (item != null) {
                 item.getMapping().remove(item);
                 item.setMapping(null);
 
-                entityManager.remove(item);
+                entityManager().remove(item);
             }
         }
 
         // Make empty query cache for *MappingItem and related *Mapping
-        entityManager.getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
-        entityManager.getEntityManagerFactory().getCache().evict(JPAMapping.class);
+        entityManager().getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
+        entityManager().getEntityManagerFactory().getCache().evict(JPAMapping.class);
     }
 
     @Override
@@ -219,6 +219,6 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
             provision.setResource(null);
         }
 
-        entityManager.remove(resource);
+        entityManager().remove(resource);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index 22ce79e..368ea07 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -88,7 +88,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Override
     public Group find(final String name) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAGroup.class.getSimpleName() + " e WHERE e.name = :name", Group.class);
         query.setParameter("name", name);
 
@@ -116,7 +116,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
             queryString.append("OR e.groupOwner.id=").append(groupKey).append(' ');
         }
 
-        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        TypedQuery<Group> query = entityManager().createQuery(queryString.toString(), Group.class);
         query.setParameter("owner", owner);
 
         return query.getResultList();
@@ -133,7 +133,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
         StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPAGroup.class.getSimpleName()).
                 append(" e WHERE e.groupOwner=:owner ");
 
-        TypedQuery<Group> query = entityManager.createQuery(queryString.toString(), Group.class);
+        TypedQuery<Group> query = entityManager().createQuery(queryString.toString(), Group.class);
         query.setParameter("owner", owner);
 
         return query.getResultList();
@@ -141,7 +141,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Override
     public List<AMembership> findAMemberships(final Group group) {
-        TypedQuery<AMembership> query = entityManager.createQuery(
+        TypedQuery<AMembership> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAMembership.class.getSimpleName()
                 + " e WHERE e.rightEnd=:group", AMembership.class);
         query.setParameter("group", group);
@@ -151,7 +151,7 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
 
     @Override
     public List<UMembership> findUMemberships(final Group group) {
-        TypedQuery<UMembership> query = entityManager.createQuery(
+        TypedQuery<UMembership> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAUMembership.class.getSimpleName()
                 + " e WHERE e.rightEnd=:group", UMembership.class);
         query.setParameter("group", group);
@@ -190,16 +190,16 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO {
             membership.getLeftEnd().remove(membership);
             anyObjectDAO.save(membership.getLeftEnd());
 
-            entityManager.remove(membership);
+            entityManager().remove(membership);
         }
         for (UMembership membership : findUMemberships(group)) {
             membership.getLeftEnd().remove(membership);
             userDAO.save(membership.getLeftEnd());
 
-            entityManager.remove(membership);
+            entityManager().remove(membership);
         }
 
-        entityManager.remove(group);
+        entityManager().remove(group);
     }
 
     private void populateTransitiveResources(

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
index 327149f..9189e2a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
@@ -32,12 +32,12 @@ public class JPALoggerDAO extends AbstractDAO<Logger, String> implements LoggerD
 
     @Override
     public Logger find(final String key) {
-        return entityManager.find(JPALogger.class, key);
+        return entityManager().find(JPALogger.class, key);
     }
 
     @Override
     public List<Logger> findAll(final LoggerType type) {
-        TypedQuery<Logger> query = entityManager.createQuery(
+        TypedQuery<Logger> query = entityManager().createQuery(
                 "SELECT e FROM " + JPALogger.class.getSimpleName() + " e WHERE e.type=:type", Logger.class);
         query.setParameter("type", type);
         return query.getResultList();
@@ -49,12 +49,12 @@ public class JPALoggerDAO extends AbstractDAO<Logger, String> implements LoggerD
         if (LoggerType.AUDIT == logger.getType() && LoggerLevel.OFF != logger.getLevel()) {
             logger.setLevel(LoggerLevel.DEBUG);
         }
-        return entityManager.merge(logger);
+        return entityManager().merge(logger);
     }
 
     @Override
     public void delete(final Logger logger) {
-        entityManager.remove(logger);
+        entityManager().remove(logger);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
index b3b4b01..a43cf22 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
@@ -30,23 +30,23 @@ public class JPANotificationDAO extends AbstractDAO<Notification, Long> implemen
 
     @Override
     public Notification find(final Long key) {
-        return entityManager.find(JPANotification.class, key);
+        return entityManager().find(JPANotification.class, key);
     }
 
     @Override
     public List<Notification> findAll() {
-        TypedQuery<Notification> query = entityManager.createQuery(
+        TypedQuery<Notification> query = entityManager().createQuery(
                 "SELECT e FROM " + JPANotification.class.getSimpleName() + " e", Notification.class);
         return query.getResultList();
     }
 
     @Override
     public Notification save(final Notification notification) {
-        return entityManager.merge(notification);
+        return entityManager().merge(notification);
     }
 
     @Override
     public void delete(final Long key) {
-        entityManager.remove(find(key));
+        entityManager().remove(find(key));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
index 5e232fd..d21d1f3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
@@ -51,7 +51,7 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements
 
     @Override
     public <T extends PlainAttr<?>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
@@ -71,6 +71,6 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements
             ((Any<T, ?, ?>) plainAttr.getOwner()).remove(plainAttr);
         }
 
-        entityManager.remove(plainAttr);
+        entityManager().remove(plainAttr);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
index 655decd..be2965c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -68,19 +68,19 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
 
     @Override
     public <T extends PlainAttrValue> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
     public <T extends PlainAttrValue> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
+        TypedQuery<T> query = entityManager().createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
     public <T extends PlainAttrValue> T save(final T attributeValue) {
-        return entityManager.merge(attributeValue);
+        return entityManager().merge(attributeValue);
     }
 
     @Override
@@ -99,6 +99,6 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl
             attrValue.getAttr().remove(attrValue);
         }
 
-        entityManager.remove(attrValue);
+        entityManager().remove(attrValue);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
index c3c94ce..47e8fe3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public PlainSchema find(final String key) {
-        return entityManager.find(JPAPlainSchema.class, key);
+        return entityManager().find(JPAPlainSchema.class, key);
     }
 
     @Override
@@ -54,7 +54,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
                 append(JPAPlainSchema.class.getSimpleName()).
                 append(" e WHERE e.anyTypeClass=:anyTypeClass");
 
-        TypedQuery<PlainSchema> query = entityManager.createQuery(queryString.toString(), PlainSchema.class);
+        TypedQuery<PlainSchema> query = entityManager().createQuery(queryString.toString(), PlainSchema.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -62,7 +62,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public List<PlainSchema> findAll() {
-        TypedQuery<PlainSchema> query = entityManager.createQuery(
+        TypedQuery<PlainSchema> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPlainSchema.class.getSimpleName() + " e", PlainSchema.class);
         return query.getResultList();
     }
@@ -73,7 +73,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
                 append(((JPAPlainAttrDAO) plainAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
-        TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -81,7 +81,7 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
 
     @Override
     public PlainSchema save(final PlainSchema schema) {
-        return entityManager.merge(schema);
+        return entityManager().merge(schema);
     }
 
     @Override
@@ -106,6 +106,6 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
             schema.getAnyTypeClass().remove(schema);
         }
 
-        entityManager.remove(schema);
+        entityManager().remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
index 176cfbd..ab0a8c5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java
@@ -43,7 +43,7 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
     @Override
     @SuppressWarnings("unchecked")
     public <T extends Policy> T find(final Long key) {
-        final Query query = entityManager.createQuery(
+        final Query query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e WHERE e.id=:id");
         query.setParameter("id", key);
 
@@ -56,7 +56,7 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
     @Override
     @SuppressWarnings("unchecked")
     public <T extends Policy> List<T> find(final PolicyType type) {
-        final Query query = entityManager.createQuery(
+        final Query query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e WHERE e.type=:type");
         query.setParameter("type", type);
 
@@ -65,7 +65,7 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
 
     @Override
     public List<AccountPolicy> findByResource(final ExternalResource resource) {
-        TypedQuery<AccountPolicy> query = entityManager.createQuery(
+        TypedQuery<AccountPolicy> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAAccountPolicy.class.getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources", AccountPolicy.class);
         query.setParameter("resource", resource);
@@ -75,14 +75,14 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
 
     @Override
     public List<Policy> findAll() {
-        TypedQuery<Policy> query = entityManager.createQuery(
+        TypedQuery<Policy> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e", Policy.class);
         return query.getResultList();
     }
 
     @Override
     public <T extends Policy> T save(final T policy) {
-        return entityManager.merge(policy);
+        return entityManager().merge(policy);
     }
 
     @Override
@@ -95,6 +95,6 @@ public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO
             }
         }
 
-        entityManager.remove(policy);
+        entityManager().remove(policy);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index f5625ee..36ce550 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -50,7 +50,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public Realm getRoot() {
-        TypedQuery<Realm> query = entityManager.createQuery(
+        TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e WHERE e.parent IS NULL", Realm.class);
 
         Realm result = null;
@@ -65,7 +65,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public Realm find(final Long key) {
-        return entityManager.find(JPARealm.class, key);
+        return entityManager().find(JPARealm.class, key);
     }
 
     @Override
@@ -126,7 +126,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
                 append(JPARealm.class.getSimpleName()).append(" e WHERE e.").
                 append(policy instanceof AccountPolicy ? "accountPolicy" : "passwordPolicy").append("=:policy");
 
-        TypedQuery<Realm> query = entityManager.createQuery(queryString.toString(), Realm.class);
+        TypedQuery<Realm> query = entityManager().createQuery(queryString.toString(), Realm.class);
         query.setParameter("policy", policy);
 
         List<Realm> result = new ArrayList<>();
@@ -154,7 +154,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public List<Realm> findChildren(final Realm realm) {
-        TypedQuery<Realm> query = entityManager.createQuery(
+        TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e WHERE e.parent=:realm", Realm.class);
         query.setParameter("realm", realm);
 
@@ -180,14 +180,14 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
     @Override
     public List<Realm> findAll() {
-        TypedQuery<Realm> query = entityManager.createQuery(
+        TypedQuery<Realm> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARealm.class.getSimpleName() + " e ", Realm.class);
         return query.getResultList();
     }
 
     @Override
     public Realm save(final Realm realm) {
-        return entityManager.merge(realm);
+        return entityManager().merge(realm);
     }
 
     @Override
@@ -199,7 +199,7 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
 
             toBeDeleted.setParent(null);
 
-            entityManager.remove(toBeDeleted);
+            entityManager().remove(toBeDeleted);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
index 37ce107..5eb3951 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
@@ -39,27 +39,27 @@ public class JPARelationshipTypeDAO extends AbstractDAO<RelationshipType, String
 
     @Override
     public RelationshipType find(final String key) {
-        return entityManager.find(JPARelationshipType.class, key);
+        return entityManager().find(JPARelationshipType.class, key);
     }
 
     @Override
     public List<RelationshipType> findAll() {
-        TypedQuery<RelationshipType> query = entityManager.createQuery(
+        TypedQuery<RelationshipType> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARelationshipType.class.getSimpleName() + " e ", RelationshipType.class);
         return query.getResultList();
     }
 
     @Override
     public RelationshipType save(final RelationshipType anyType) {
-        return entityManager.merge(anyType);
+        return entityManager().merge(anyType);
     }
 
     private Collection<? extends Relationship<?, ?>> findRelationshipsByType(final RelationshipType type) {
-        TypedQuery<ARelationship> aquery = entityManager.createQuery(
+        TypedQuery<ARelationship> aquery = entityManager().createQuery(
                 "SELECT e FROM " + JPAARelationship.class.getSimpleName() + " e WHERE e.type=:type",
                 ARelationship.class);
         aquery.setParameter("type", type);
-        TypedQuery<URelationship> uquery = entityManager.createQuery(
+        TypedQuery<URelationship> uquery = entityManager().createQuery(
                 "SELECT e FROM " + JPAURelationship.class.getSimpleName() + " e WHERE e.type=:type",
                 URelationship.class);
         uquery.setParameter("type", type);
@@ -86,10 +86,10 @@ public class JPARelationshipTypeDAO extends AbstractDAO<RelationshipType, String
             }
 
             relationship.setLeftEnd(null);
-            entityManager.remove(relationship);
+            entityManager().remove(relationship);
         }
 
-        entityManager.remove(type);
+        entityManager().remove(type);
     }
 
 }


[04/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
new file mode 100644
index 0000000..245a74a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.sync.SyncActions;
+import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    protected SyncUtils syncUtils;
+
+    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
+        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
+            Group group = groupDAO.find(entry.getKey());
+            if (group == null) {
+                throw new NotFoundException("Group " + entry.getKey());
+            }
+
+            if (StringUtils.isBlank(entry.getValue())) {
+                group.setGroupOwner(null);
+                group.setUserOwner(null);
+            } else {
+                Long userKey = syncUtils.findMatchingAnyKey(
+                        anyTypeDAO.findUser(),
+                        entry.getValue(),
+                        ghandler.getProfile().getTask().getResource(),
+                        ghandler.getProfile().getConnector());
+
+                if (userKey == null) {
+                    Long groupKey = syncUtils.findMatchingAnyKey(
+                            anyTypeDAO.findGroup(),
+                            entry.getValue(),
+                            ghandler.getProfile().getTask().getResource(),
+                            ghandler.getProfile().getConnector());
+
+                    if (groupKey != null) {
+                        group.setGroupOwner(groupDAO.find(groupKey));
+                    }
+                } else {
+                    group.setUserOwner(userDAO.find(userKey));
+                }
+            }
+
+            groupDAO.save(group);
+        }
+    }
+
+    @Override
+    protected String doExecuteProvisioning(
+            final SyncTask syncTask,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException {
+
+        LOG.debug("Executing sync on {}", syncTask.getResource());
+
+        List<SyncActions> actions = new ArrayList<>();
+        for (String className : syncTask.getActionsClassNames()) {
+            try {
+                Class<?> actionsClass = Class.forName(className);
+                SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
+                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+
+                actions.add(syncActions);
+            } catch (Exception e) {
+                LOG.info("Class '{}' not found", className, e);
+            }
+        }
+
+        ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
+        profile.getActions().addAll(actions);
+        profile.setDryRun(dryRun);
+        profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
+
+        // Prepare handler for SyncDelta objects (any objects)
+        AnyObjectSyncResultHandler ahandler =
+                (AnyObjectSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
+        // Prepare handler for SyncDelta objects (users)
+        UserSyncResultHandler uhandler =
+                (UserSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        uhandler.setProfile(profile);
+
+        // Prepare handler for SyncDelta objects (groups)
+        GroupSyncResultHandler ghandler =
+                (GroupSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ghandler.setProfile(profile);
+
+        if (!profile.isDryRun()) {
+            for (SyncActions action : actions) {
+                action.beforeAll(profile);
+            }
+        }
+
+        for (Provision provision : syncTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                SyncResultsHandler handler;
+                switch (provision.getAnyType().getKind()) {
+                    case USER:
+                        handler = uhandler;
+                        break;
+
+                    case GROUP:
+                        handler = ghandler;
+                        break;
+
+                    case ANY_OBJECT:
+                    default:
+                        handler = ahandler;
+                }
+
+                try {
+                    SyncToken latestSyncToken = null;
+                    if (!syncTask.isFullReconciliation()) {
+                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+                    }
+
+                    if (syncTask.isFullReconciliation()) {
+                        connector.getAllObjects(provision.getObjectClass(), handler,
+                                connector.getOperationOptions(provision.getMapping().getItems()));
+                    } else {
+                        connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
+                                connector.getOperationOptions(provision.getMapping().getItems()));
+                    }
+
+                    if (!dryRun && !syncTask.isFullReconciliation()) {
+                        try {
+                            provision.setSyncToken(latestSyncToken);
+                            resourceDAO.save(provision.getResource());
+                        } catch (Exception e) {
+                            throw new JobExecutionException("While updating SyncToken", e);
+                        }
+                    }
+                } catch (Throwable t) {
+                    throw new JobExecutionException("While syncing on connector", t);
+                }
+            }
+        }
+
+        try {
+            setGroupOwners(ghandler);
+        } catch (Exception e) {
+            LOG.error("While setting group owners", e);
+        }
+
+        if (!profile.isDryRun()) {
+            for (SyncActions action : actions) {
+                action.afterAll(profile);
+            }
+        }
+
+        String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
+
+        LOG.debug("Sync result: {}", result);
+
+        return result;
+    }
+
+    private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
+        SyncPolicySpec syncPolicySpec;
+
+        if (task instanceof SyncTask) {
+            syncPolicySpec = task.getResource().getSyncPolicy() == null
+                    ? null
+                    : task.getResource().getSyncPolicy().getSpecification(SyncPolicySpec.class);
+        } else {
+            syncPolicySpec = null;
+        }
+
+        // step required because the call <policy>.getSpecification() could return a null value
+        return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
deleted file mode 100644
index c52c3cf..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobImpl.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.java.sync;
-
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.mod.ReferenceMod;
-import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.types.SyncPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
-import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.identityconnectors.framework.common.objects.SyncToken;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-
-/**
- * Job for executing synchronization (from external resource) tasks.
- *
- * @see AbstractProvisioningJob
- * @see SyncTask
- */
-public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions> implements SyncJob {
-
-    /**
-     * Group workflow adapter.
-     */
-    @Autowired
-    private GroupWorkflowAdapter gwfAdapter;
-
-    @Autowired
-    protected SyncUtils syncUtils;
-
-    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
-        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
-            GroupMod groupMod = new GroupMod();
-            groupMod.setKey(entry.getKey());
-
-            if (StringUtils.isBlank(entry.getValue())) {
-                groupMod.setGroupOwner(null);
-                groupMod.setUserOwner(null);
-            } else {
-                Long userKey = syncUtils.findMatchingAnyKey(
-                        anyTypeDAO.findUser(),
-                        entry.getValue(),
-                        ghandler.getProfile().getTask().getResource(),
-                        ghandler.getProfile().getConnector());
-
-                if (userKey == null) {
-                    Long groupKey = syncUtils.findMatchingAnyKey(
-                            anyTypeDAO.findGroup(),
-                            entry.getValue(),
-                            ghandler.getProfile().getTask().getResource(),
-                            ghandler.getProfile().getConnector());
-
-                    if (groupKey != null) {
-                        groupMod.setGroupOwner(new ReferenceMod(groupKey));
-                    }
-                } else {
-                    groupMod.setUserOwner(new ReferenceMod(userKey));
-                }
-            }
-
-            gwfAdapter.update(groupMod);
-        }
-    }
-
-    @Override
-    protected String executeWithSecurityContext(
-            final SyncTask syncTask,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException {
-
-        LOG.debug("Executing sync on {}", syncTask.getResource());
-
-        ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
-        if (actions != null) {
-            profile.getActions().addAll(actions);
-        }
-        profile.setDryRun(dryRun);
-        profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
-
-        // Prepare handler for SyncDelta objects (any objects)
-        AnyObjectSyncResultHandler ahandler =
-                (AnyObjectSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ahandler.setProfile(profile);
-
-        // Prepare handler for SyncDelta objects (users)
-        UserSyncResultHandler uhandler =
-                (UserSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        uhandler.setProfile(profile);
-
-        // Prepare handler for SyncDelta objects (groups)
-        GroupSyncResultHandler ghandler =
-                (GroupSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ghandler.setProfile(profile);
-
-        if (actions != null && !profile.isDryRun()) {
-            for (SyncActions action : actions) {
-                action.beforeAll(profile);
-            }
-        }
-
-        for (Provision provision : syncTask.getResource().getProvisions()) {
-            if (provision.getMapping() != null) {
-                SyncResultsHandler handler;
-                switch (provision.getAnyType().getKind()) {
-                    case USER:
-                        handler = uhandler;
-                        break;
-
-                    case GROUP:
-                        handler = ghandler;
-                        break;
-
-                    case ANY_OBJECT:
-                    default:
-                        handler = ahandler;
-                }
-
-                try {
-                    SyncToken latestSyncToken = null;
-                    if (!syncTask.isFullReconciliation()) {
-                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
-                    }
-
-                    if (syncTask.isFullReconciliation()) {
-                        connector.getAllObjects(provision.getObjectClass(), handler,
-                                connector.getOperationOptions(provision.getMapping().getItems()));
-                    } else {
-                        connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
-                                connector.getOperationOptions(provision.getMapping().getItems()));
-                    }
-
-                    if (!dryRun && !syncTask.isFullReconciliation()) {
-                        try {
-                            provision.setSyncToken(latestSyncToken);
-                            resourceDAO.save(provision.getResource());
-                        } catch (Exception e) {
-                            throw new JobExecutionException("While updating SyncToken", e);
-                        }
-                    }
-                } catch (Throwable t) {
-                    throw new JobExecutionException("While syncing on connector", t);
-                }
-            }
-        }
-
-        try {
-            setGroupOwners(ghandler);
-        } catch (Exception e) {
-            LOG.error("While setting group owners", e);
-        }
-
-        if (actions != null && !profile.isDryRun()) {
-            for (SyncActions action : actions) {
-                action.afterAll(profile);
-            }
-        }
-
-        String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
-
-        LOG.debug("Sync result: {}", result);
-
-        return result;
-    }
-
-    private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
-        SyncPolicySpec syncPolicySpec;
-
-        if (task instanceof SyncTask) {
-            syncPolicySpec = task.getResource().getSyncPolicy() == null
-                    ? null
-                    : task.getResource().getSyncPolicy().getSpecification(SyncPolicySpec.class);
-        } else {
-            syncPolicySpec = null;
-        }
-
-        // step required because the call <policy>.getSpecification() could return a null value
-        return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
index c3d11a9..dc5cdf0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
@@ -64,7 +64,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional(readOnly = true)
 @Component
 public class SyncUtils {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
index d5c41db..20a3673 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
@@ -107,12 +107,11 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
             final Long key,
             final boolean unlink) {
 
-        taskExecutor.execute(
-                propagationManager.getUserDeleteTasks(
-                        key, Collections.singleton(profile.getTask().getResource().getKey())));
+        taskExecutor.execute(propagationManager.getUserDeleteTasks(
+                key, Collections.singleton(profile.getTask().getResource().getKey())));
 
         if (unlink) {
-            final UserMod userMod = new UserMod();
+            UserMod userMod = new UserMod();
             userMod.setKey(key);
             userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioning.properties b/core/provisioning-java/src/main/resources/provisioning.properties
index af1dd4b..59e5916 100644
--- a/core/provisioning-java/src/main/resources/provisioning.properties
+++ b/core/provisioning-java/src/main/resources/provisioning.properties
@@ -18,3 +18,6 @@ userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserPro
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+
+quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
+quartz.sql=tables_postgres.sql

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/provisioningContext.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioningContext.xml b/core/provisioning-java/src/main/resources/provisioningContext.xml
index 32120f4..2f0f617 100644
--- a/core/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/core/provisioning-java/src/main/resources/provisioningContext.xml
@@ -35,14 +35,33 @@ under the License.
   <bean class="${groupProvisioningManager}"/>
   <bean class="${anyObjectProvisioningManager}"/>
 
+  <bean id="quartzDataSourceInit" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/quartz/${quartz.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+
   <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
-        lazy-init="false" depends-on="nonJPAdbInitializer">
+        lazy-init="false" depends-on="quartzDataSourceInit">
     <property name="autoStartup" value="true"/>
     <property name="applicationContextSchedulerContextKey" value="applicationContext"/>
     <property name="waitForJobsToCompleteOnShutdown" value="true"/>
     <property name="overwriteExistingJobs" value="true"/>
-    <property name="dataSource" ref="dataSource"/>
-    <property name="transactionManager" ref="transactionManager"/>
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="transactionManager" ref="MasterTransactionManager"/>
     <property name="jobFactory">
       <bean class="org.apache.syncope.core.provisioning.java.job.SpringBeanJobFactory"/>
     </property>
@@ -104,7 +123,7 @@ under the License.
     <constructor-arg index="1" value="true"/>
   </bean>
 
-  <bean id="connIdBundleManager" class="org.apache.syncope.core.provisioning.java.ConnIdBundleManagerImpl" scope="singleton">
+  <bean id="connIdBundleManager" class="org.apache.syncope.core.provisioning.java.ConnIdBundleManagerImpl">
     <property name="stringLocations" value="${connid.locations}"/>
   </bean>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_h2.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_h2.sql b/core/provisioning-java/src/main/resources/quartz/tables_h2.sql
new file mode 100644
index 0000000..e798223
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_h2.sql
@@ -0,0 +1,266 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+-- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database, 
+-- and verifying that it works with Quartz's StdJDBCDelegate
+--
+-- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE 
+-- setting on your H2 database, or you will experience dead-locks
+--
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+
+CREATE TABLE QRTZ_CALENDARS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR (200)  NOT NULL ,
+  CALENDAR IMAGE NOT NULL
+);
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  CRON_EXPRESSION VARCHAR (120)  NOT NULL ,
+  TIME_ZONE_ID VARCHAR (80) 
+);
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  ENTRY_ID VARCHAR (95)  NOT NULL ,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
+  FIRED_TIME BIGINT NOT NULL ,
+  SCHED_TIME BIGINT NOT NULL ,
+  PRIORITY INTEGER NOT NULL ,
+  STATE VARCHAR (16)  NOT NULL,
+  JOB_NAME VARCHAR (200)  NULL ,
+  JOB_GROUP VARCHAR (200)  NULL ,
+  IS_NONCONCURRENT BOOLEAN  NULL ,
+  REQUESTS_RECOVERY BOOLEAN  NULL 
+);
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL 
+);
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
+  LAST_CHECKIN_TIME BIGINT NOT NULL ,
+  CHECKIN_INTERVAL BIGINT NOT NULL
+);
+
+CREATE TABLE QRTZ_LOCKS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME VARCHAR (40)  NOT NULL 
+);
+
+CREATE TABLE QRTZ_JOB_DETAILS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  JOB_NAME VARCHAR (200)  NOT NULL ,
+  JOB_GROUP VARCHAR (200)  NOT NULL ,
+  DESCRIPTION VARCHAR (250) NULL ,
+  JOB_CLASS_NAME VARCHAR (250)  NOT NULL ,
+  IS_DURABLE BOOLEAN  NOT NULL ,
+  IS_NONCONCURRENT BOOLEAN  NOT NULL ,
+  IS_UPDATE_DATA BOOLEAN  NOT NULL ,
+  REQUESTS_RECOVERY BOOLEAN  NOT NULL ,
+  JOB_DATA IMAGE NULL
+);
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  REPEAT_COUNT BIGINT NOT NULL ,
+  REPEAT_INTERVAL BIGINT NOT NULL ,
+  TIMES_TRIGGERED BIGINT NOT NULL
+);
+
+CREATE TABLE qrtz_simprop_triggers
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INTEGER NULL,
+    INT_PROP_2 INTEGER NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 BOOLEAN NULL,
+    BOOL_PROP_2 BOOLEAN NULL,
+);
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  BLOB_DATA IMAGE NULL
+);
+
+CREATE TABLE QRTZ_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
+  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
+  JOB_NAME VARCHAR (200)  NOT NULL ,
+  JOB_GROUP VARCHAR (200)  NOT NULL ,
+  DESCRIPTION VARCHAR (250) NULL ,
+  NEXT_FIRE_TIME BIGINT NULL ,
+  PREV_FIRE_TIME BIGINT NULL ,
+  PRIORITY INTEGER NULL ,
+  TRIGGER_STATE VARCHAR (16)  NOT NULL ,
+  TRIGGER_TYPE VARCHAR (8)  NOT NULL ,
+  START_TIME BIGINT NOT NULL ,
+  END_TIME BIGINT NULL ,
+  CALENDAR_NAME VARCHAR (200)  NULL ,
+  MISFIRE_INSTR SMALLINT NULL ,
+  JOB_DATA IMAGE NULL
+);
+
+ALTER TABLE QRTZ_CALENDARS  ADD
+  CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    CALENDAR_NAME
+  );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_FIRED_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    ENTRY_ID
+  );
+
+ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS  ADD
+  CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_SCHEDULER_STATE  ADD
+  CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY  
+  (
+    SCHED_NAME,
+    INSTANCE_NAME
+  );
+
+ALTER TABLE QRTZ_LOCKS  ADD
+  CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    LOCK_NAME
+  );
+
+ALTER TABLE QRTZ_JOB_DETAILS  ADD
+  CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  );
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_TRIGGERS  ADD
+  CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY  
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+  (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_TRIGGERS ADD
+  CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
+  (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  ) REFERENCES QRTZ_JOB_DETAILS (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  );
+  
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql b/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql
new file mode 100644
index 0000000..ebb8e59
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql
@@ -0,0 +1,206 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+--
+-- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
+--
+-- PLEASE consider using mysql with innodb tables to avoid locking issues
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+--
+
+BEGIN;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+COMMIT;
+
+
+BEGIN;
+CREATE TABLE QRTZ_JOB_DETAILS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
+    IS_DURABLE VARCHAR(1) NOT NULL,
+    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT(13) NULL,
+    PREV_FIRE_TIME BIGINT(13) NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT(13) NOT NULL,
+    END_TIME BIGINT(13) NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT(2) NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT(7) NOT NULL,
+    REPEAT_INTERVAL BIGINT(12) NOT NULL,
+    TIMES_TRIGGERED BIGINT(10) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CRON_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(200) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_BLOB_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CALENDARS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL,
+    CALENDAR BLOB NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_FIRED_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT(13) NOT NULL,
+    SCHED_TIME BIGINT(13) NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT VARCHAR(1) NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SCHEDULER_STATE
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_LOCKS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql b/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql
new file mode 100644
index 0000000..ebb8e59
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql
@@ -0,0 +1,206 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+--
+-- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
+--
+-- PLEASE consider using mysql with innodb tables to avoid locking issues
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+--
+
+BEGIN;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+COMMIT;
+
+
+BEGIN;
+CREATE TABLE QRTZ_JOB_DETAILS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
+    IS_DURABLE VARCHAR(1) NOT NULL,
+    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT(13) NULL,
+    PREV_FIRE_TIME BIGINT(13) NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT(13) NOT NULL,
+    END_TIME BIGINT(13) NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT(2) NULL,
+    JOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT(7) NOT NULL,
+    REPEAT_INTERVAL BIGINT(12) NOT NULL,
+    TIMES_TRIGGERED BIGINT(10) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CRON_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(200) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_BLOB_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BLOB NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CALENDARS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL,
+    CALENDAR BLOB NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_FIRED_TRIGGERS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT(13) NOT NULL,
+    SCHED_TIME BIGINT(13) NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT VARCHAR(1) NULL,
+    REQUESTS_RECOVERY VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SCHEDULER_STATE
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_LOCKS
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql b/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql
new file mode 100644
index 0000000..c54493e
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql
@@ -0,0 +1,221 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+--
+--
+-- By: Ron Cordell - roncordell
+-- I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
+--
+
+BEGIN;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_JOB_DETAILS(
+SCHED_NAME VARCHAR(120) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+IS_DURABLE VARCHAR(1) NOT NULL,
+IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+NEXT_FIRE_TIME BIGINT(13) NULL,
+PREV_FIRE_TIME BIGINT(13) NULL,
+PRIORITY INTEGER NULL,
+TRIGGER_STATE VARCHAR(16) NOT NULL,
+TRIGGER_TYPE VARCHAR(8) NOT NULL,
+START_TIME BIGINT(13) NOT NULL,
+END_TIME BIGINT(13) NULL,
+CALENDAR_NAME VARCHAR(200) NULL,
+MISFIRE_INSTR SMALLINT(2) NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+REPEAT_COUNT BIGINT(7) NOT NULL,
+REPEAT_INTERVAL BIGINT(12) NOT NULL,
+TIMES_TRIGGERED BIGINT(10) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+CRON_EXPRESSION VARCHAR(120) NOT NULL,
+TIME_ZONE_ID VARCHAR(80),
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR(1) NULL,
+    BOOL_PROP_2 VARCHAR(1) NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+BLOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_CALENDARS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+CALENDAR_NAME VARCHAR(200) NOT NULL,
+CALENDAR BLOB NOT NULL,
+PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+ENTRY_ID VARCHAR(95) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+FIRED_TIME BIGINT(13) NOT NULL,
+SCHED_TIME BIGINT(13) NOT NULL,
+PRIORITY INTEGER NOT NULL,
+STATE VARCHAR(16) NOT NULL,
+JOB_NAME VARCHAR(200) NULL,
+JOB_GROUP VARCHAR(200) NULL,
+IS_NONCONCURRENT VARCHAR(1) NULL,
+REQUESTS_RECOVERY VARCHAR(1) NULL,
+PRIMARY KEY (SCHED_NAME,ENTRY_ID))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+SCHED_NAME VARCHAR(120) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE TABLE QRTZ_LOCKS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+LOCK_NAME VARCHAR(40) NOT NULL,
+PRIMARY KEY (SCHED_NAME,LOCK_NAME))
+ENGINE=InnoDB;
+COMMIT;
+
+BEGIN;
+CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
+
+CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
+CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
+CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql b/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql
new file mode 100644
index 0000000..4384ac5
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql
@@ -0,0 +1,208 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+--
+-- A hint submitted by a user: Oracle DB MUST be created as "shared" and the 
+-- job_queue_processes parameter  must be greater than 2
+-- However, these settings are pretty much standard after any
+-- Oracle install, so most users need not worry about this.
+--
+-- Many other users (including the primary author of Quartz) have had success
+-- runing in dedicated mode, so only consider the above as a hint ;-)
+--
+
+delete from qrtz_fired_triggers;
+delete from qrtz_simple_triggers;
+delete from qrtz_simprop_triggers;
+delete from qrtz_cron_triggers;
+delete from qrtz_blob_triggers;
+delete from qrtz_triggers;
+delete from qrtz_job_details;
+delete from qrtz_calendars;
+delete from qrtz_paused_trigger_grps;
+delete from qrtz_locks;
+delete from qrtz_scheduler_state;
+
+drop table qrtz_calendars;
+drop table qrtz_fired_triggers;
+drop table qrtz_blob_triggers;
+drop table qrtz_cron_triggers;
+drop table qrtz_simple_triggers;
+drop table qrtz_simprop_triggers;
+drop table qrtz_triggers;
+drop table qrtz_job_details;
+drop table qrtz_paused_trigger_grps;
+drop table qrtz_locks;
+drop table qrtz_scheduler_state;
+
+
+CREATE TABLE qrtz_job_details
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    JOB_NAME  VARCHAR2(200) NOT NULL,
+    JOB_GROUP VARCHAR2(200) NOT NULL,
+    DESCRIPTION VARCHAR2(250) NULL,
+    JOB_CLASS_NAME   VARCHAR2(250) NOT NULL, 
+    IS_DURABLE VARCHAR2(1) NOT NULL,
+    IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
+    IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
+    REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
+    JOB_DATA BLOB NULL,
+    CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+CREATE TABLE qrtz_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    JOB_NAME  VARCHAR2(200) NOT NULL, 
+    JOB_GROUP VARCHAR2(200) NOT NULL,
+    DESCRIPTION VARCHAR2(250) NULL,
+    NEXT_FIRE_TIME NUMBER(13) NULL,
+    PREV_FIRE_TIME NUMBER(13) NULL,
+    PRIORITY NUMBER(13) NULL,
+    TRIGGER_STATE VARCHAR2(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR2(8) NOT NULL,
+    START_TIME NUMBER(13) NOT NULL,
+    END_TIME NUMBER(13) NULL,
+    CALENDAR_NAME VARCHAR2(200) NULL,
+    MISFIRE_INSTR NUMBER(2) NULL,
+    JOB_DATA BLOB NULL,
+    CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
+      REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
+);
+CREATE TABLE qrtz_simple_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    REPEAT_COUNT NUMBER(7) NOT NULL,
+    REPEAT_INTERVAL NUMBER(12) NOT NULL,
+    TIMES_TRIGGERED NUMBER(10) NOT NULL,
+    CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_cron_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR2(120) NOT NULL,
+    TIME_ZONE_ID VARCHAR2(80),
+    CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_simprop_triggers
+  (          
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    STR_PROP_1 VARCHAR2(512) NULL,
+    STR_PROP_2 VARCHAR2(512) NULL,
+    STR_PROP_3 VARCHAR2(512) NULL,
+    INT_PROP_1 NUMBER(10) NULL,
+    INT_PROP_2 NUMBER(10) NULL,
+    LONG_PROP_1 NUMBER(13) NULL,
+    LONG_PROP_2 NUMBER(13) NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 VARCHAR2(1) NULL,
+    BOOL_PROP_2 VARCHAR2(1) NULL,
+    CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_blob_triggers
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    BLOB_DATA BLOB NULL,
+    CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_calendars
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR2(200) NOT NULL, 
+    CALENDAR BLOB NOT NULL,
+    CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+CREATE TABLE qrtz_paused_trigger_grps
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR2(200) NOT NULL, 
+    CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_fired_triggers 
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    ENTRY_ID VARCHAR2(95) NOT NULL,
+    TRIGGER_NAME VARCHAR2(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+    INSTANCE_NAME VARCHAR2(200) NOT NULL,
+    FIRED_TIME NUMBER(13) NOT NULL,
+    SCHED_TIME NUMBER(13) NOT NULL,
+    PRIORITY NUMBER(13) NOT NULL,
+    STATE VARCHAR2(16) NOT NULL,
+    JOB_NAME VARCHAR2(200) NULL,
+    JOB_GROUP VARCHAR2(200) NULL,
+    IS_NONCONCURRENT VARCHAR2(1) NULL,
+    REQUESTS_RECOVERY VARCHAR2(1) NULL,
+    CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+CREATE TABLE qrtz_scheduler_state 
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    INSTANCE_NAME VARCHAR2(200) NOT NULL,
+    LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
+    CHECKIN_INTERVAL NUMBER(13) NOT NULL,
+    CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+CREATE TABLE qrtz_locks
+  (
+    SCHED_NAME VARCHAR2(120) NOT NULL,
+    LOCK_NAME  VARCHAR2(40) NOT NULL, 
+    CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql b/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql
new file mode 100644
index 0000000..9b7800f
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql
@@ -0,0 +1,204 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+-- Thanks to Patrick Lightbody for submitting this...
+--
+-- In your Quartz properties file, you'll need to set 
+-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
+
+drop table qrtz_fired_triggers;
+DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE QRTZ_SCHEDULER_STATE;
+DROP TABLE QRTZ_LOCKS;
+drop table qrtz_simple_triggers;
+drop table qrtz_cron_triggers;
+drop table qrtz_simprop_triggers;
+DROP TABLE QRTZ_BLOB_TRIGGERS;
+drop table qrtz_triggers;
+drop table qrtz_job_details;
+drop table qrtz_calendars;
+
+CREATE TABLE qrtz_job_details
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL,
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    JOB_CLASS_NAME   VARCHAR(250) NOT NULL, 
+    IS_DURABLE BOOL NOT NULL,
+    IS_NONCONCURRENT BOOL NOT NULL,
+    IS_UPDATE_DATA BOOL NOT NULL,
+    REQUESTS_RECOVERY BOOL NOT NULL,
+    JOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE qrtz_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    JOB_NAME  VARCHAR(200) NOT NULL, 
+    JOB_GROUP VARCHAR(200) NOT NULL,
+    DESCRIPTION VARCHAR(250) NULL,
+    NEXT_FIRE_TIME BIGINT NULL,
+    PREV_FIRE_TIME BIGINT NULL,
+    PRIORITY INTEGER NULL,
+    TRIGGER_STATE VARCHAR(16) NOT NULL,
+    TRIGGER_TYPE VARCHAR(8) NOT NULL,
+    START_TIME BIGINT NOT NULL,
+    END_TIME BIGINT NULL,
+    CALENDAR_NAME VARCHAR(200) NULL,
+    MISFIRE_INSTR SMALLINT NULL,
+    JOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
+	REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
+);
+
+CREATE TABLE qrtz_simple_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    REPEAT_COUNT BIGINT NOT NULL,
+    REPEAT_INTERVAL BIGINT NOT NULL,
+    TIMES_TRIGGERED BIGINT NOT NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_cron_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    CRON_EXPRESSION VARCHAR(120) NOT NULL,
+    TIME_ZONE_ID VARCHAR(80),
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_simprop_triggers
+  (          
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    STR_PROP_1 VARCHAR(512) NULL,
+    STR_PROP_2 VARCHAR(512) NULL,
+    STR_PROP_3 VARCHAR(512) NULL,
+    INT_PROP_1 INT NULL,
+    INT_PROP_2 INT NULL,
+    LONG_PROP_1 BIGINT NULL,
+    LONG_PROP_2 BIGINT NULL,
+    DEC_PROP_1 NUMERIC(13,4) NULL,
+    DEC_PROP_2 NUMERIC(13,4) NULL,
+    BOOL_PROP_1 BOOL NULL,
+    BOOL_PROP_2 BOOL NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_blob_triggers
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    BLOB_DATA BYTEA NULL,
+    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
+        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_calendars
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    CALENDAR_NAME  VARCHAR(200) NOT NULL, 
+    CALENDAR BYTEA NOT NULL,
+    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+
+
+CREATE TABLE qrtz_paused_trigger_grps
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_fired_triggers 
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    ENTRY_ID VARCHAR(95) NOT NULL,
+    TRIGGER_NAME VARCHAR(200) NOT NULL,
+    TRIGGER_GROUP VARCHAR(200) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    FIRED_TIME BIGINT NOT NULL,
+    SCHED_TIME BIGINT NOT NULL,
+    PRIORITY INTEGER NOT NULL,
+    STATE VARCHAR(16) NOT NULL,
+    JOB_NAME VARCHAR(200) NULL,
+    JOB_GROUP VARCHAR(200) NULL,
+    IS_NONCONCURRENT BOOL NULL,
+    REQUESTS_RECOVERY BOOL NULL,
+    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+
+CREATE TABLE qrtz_scheduler_state 
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    INSTANCE_NAME VARCHAR(200) NOT NULL,
+    LAST_CHECKIN_TIME BIGINT NOT NULL,
+    CHECKIN_INTERVAL BIGINT NOT NULL,
+    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+
+CREATE TABLE qrtz_locks
+  (
+    SCHED_NAME VARCHAR(120) NOT NULL,
+    LOCK_NAME  VARCHAR(40) NOT NULL, 
+    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
+
+
+commit;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql b/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql
new file mode 100644
index 0000000..288b990
--- /dev/null
+++ b/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql
@@ -0,0 +1,296 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS;
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_CALENDARS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_LOCKS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_JOB_DETAILS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS];
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+DROP TABLE [dbo].[QRTZ_TRIGGERS];
+
+CREATE TABLE [dbo].[QRTZ_CALENDARS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [CALENDAR_NAME] [VARCHAR] (200)  NOT NULL ,
+  [CALENDAR] [IMAGE] NOT NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [CRON_EXPRESSION] [VARCHAR] (120)  NOT NULL ,
+  [TIME_ZONE_ID] [VARCHAR] (80) 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [ENTRY_ID] [VARCHAR] (95)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
+  [FIRED_TIME] [BIGINT] NOT NULL ,
+  [SCHED_TIME] [BIGINT] NOT NULL ,
+  [PRIORITY] [INTEGER] NOT NULL ,
+  [STATE] [VARCHAR] (16)  NOT NULL,
+  [JOB_NAME] [VARCHAR] (200)  NULL ,
+  [JOB_GROUP] [VARCHAR] (200)  NULL ,
+  [IS_NONCONCURRENT] [VARCHAR] (1)  NULL ,
+  [REQUESTS_RECOVERY] [VARCHAR] (1)  NULL 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
+  [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
+  [CHECKIN_INTERVAL] [BIGINT] NOT NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_LOCKS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [LOCK_NAME] [VARCHAR] (40)  NOT NULL 
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
+  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [DESCRIPTION] [VARCHAR] (250) NULL ,
+  [JOB_CLASS_NAME] [VARCHAR] (250)  NOT NULL ,
+  [IS_DURABLE] [VARCHAR] (1)  NOT NULL ,
+  [IS_NONCONCURRENT] [VARCHAR] (1)  NOT NULL ,
+  [IS_UPDATE_DATA] [VARCHAR] (1)  NOT NULL ,
+  [REQUESTS_RECOVERY] [VARCHAR] (1)  NOT NULL ,
+  [JOB_DATA] [IMAGE] NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [REPEAT_COUNT] [BIGINT] NOT NULL ,
+  [REPEAT_INTERVAL] [BIGINT] NOT NULL ,
+  [TIMES_TRIGGERED] [BIGINT] NOT NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [STR_PROP_1] [VARCHAR] (512) NULL,
+  [STR_PROP_2] [VARCHAR] (512) NULL,
+  [STR_PROP_3] [VARCHAR] (512) NULL,
+  [INT_PROP_1] [INT] NULL,
+  [INT_PROP_2] [INT] NULL,
+  [LONG_PROP_1] [BIGINT] NULL,
+  [LONG_PROP_2] [BIGINT] NULL,
+  [DEC_PROP_1] [NUMERIC] (13,4) NULL,
+  [DEC_PROP_2] [NUMERIC] (13,4) NULL,
+  [BOOL_PROP_1] [VARCHAR] (1) NULL,
+  [BOOL_PROP_2] [VARCHAR] (1) NULL,
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [BLOB_DATA] [IMAGE] NULL
+) ON [PRIMARY];
+
+CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
+  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
+  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
+  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
+  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
+  [DESCRIPTION] [VARCHAR] (250) NULL ,
+  [NEXT_FIRE_TIME] [BIGINT] NULL ,
+  [PREV_FIRE_TIME] [BIGINT] NULL ,
+  [PRIORITY] [INTEGER] NULL ,
+  [TRIGGER_STATE] [VARCHAR] (16)  NOT NULL ,
+  [TRIGGER_TYPE] [VARCHAR] (8)  NOT NULL ,
+  [START_TIME] [BIGINT] NOT NULL ,
+  [END_TIME] [BIGINT] NULL ,
+  [CALENDAR_NAME] [VARCHAR] (200)  NULL ,
+  [MISFIRE_INSTR] [SMALLINT] NULL ,
+  [JOB_DATA] [IMAGE] NULL
+) ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [CALENDAR_NAME]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [ENTRY_ID]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [INSTANCE_NAME]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [LOCK_NAME]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [JOB_NAME],
+    [JOB_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
+  CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY  CLUSTERED
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  )  ON [PRIMARY];
+
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) ON DELETE CASCADE;
+
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) ON DELETE CASCADE;
+
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+    [SCHED_NAME],
+    [TRIGGER_NAME],
+    [TRIGGER_GROUP]
+  ) ON DELETE CASCADE;
+
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
+  CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
+  (
+    [SCHED_NAME],
+    [JOB_NAME],
+    [JOB_GROUP]
+  ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
+    [SCHED_NAME],
+    [JOB_NAME],
+    [JOB_GROUP]
+  );

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
index e26f238..07bda8a 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java;
 import org.junit.runner.RunWith;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.TransactionConfiguration;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = {
@@ -29,5 +30,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     "classpath:workflowContext.xml",
     "classpath:provisioningTest.xml"
 })
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
 public abstract class AbstractTest {
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
index 138fee3..1a71b89 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
@@ -65,7 +65,7 @@ public class ConnectorManagerTest extends AbstractTest {
         }
 
         assertEquals(expected,
-                ApplicationContextProvider.getApplicationContext().
+                ApplicationContextProvider.getBeanFactory().
                 getBeanNamesForType(Connector.class, false, true).length);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
new file mode 100644
index 0000000..98392af
--- /dev/null
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/TestInitializer.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.java;
+
+import org.apache.syncope.core.persistence.api.content.ContentLoader;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestInitializer implements InitializingBean {
+
+    @Autowired
+    private ContentLoader contentLoader;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        contentLoader.load();
+    }
+
+}


[11/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
new file mode 100644
index 0000000..d90518f
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<dataset>
+  <Realm id="1" name="/"/>
+
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="BaseUser"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="baseUser"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+        
+  <PlainSchema name="email" type="String" anyTypeClass_name="BaseUser"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  
+  <!-- Password reset notifications -->
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/>
+  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
+
+</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
new file mode 100644
index 0000000..5cb38c2
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
+                           http://www.springframework.org/schema/tx
+                           http://www.springframework.org/schema/tx/spring-tx.xsd
+                           http://www.springframework.org/schema/util
+                           http://www.springframework.org/schema/util/spring-util.xsd">
+  
+  <bean id="MasterContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
+    <property name="fallback" value="classpath:domains/MasterContent.xml"/>
+  </bean>
+  <bean id="MasterProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/Master.properties"/>
+    <property name="fallback" value="classpath:domains/Master.properties"/>
+  </bean>
+  <bean id="MasterDatabaseSchema" class="java.lang.String">
+    <constructor-arg value="${Master.schema}"/>
+  </bean>
+
+  <!-- Use JNDI datasource as default but, when not available, revert to
+  local datasource, with different properties for execution and testing. 
+  In any case, get all JDBC connections with a determined isolation level. -->
+  <bean id="MasterDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+    <property name="jndiName" value="java:comp/env/jdbc/syncopeMasterDataSource"/>
+    <property name="defaultObject" ref="localMasterDataSource"/>
+  </bean>
+
+  <bean id="localMasterDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
+    <property name="driverClassName" value="${Master.driverClassName}"/>
+    <property name="url" value="${Master.url}"/>
+    <property name="username" value="${Master.username}"/>
+    <property name="password" value="${Master.password}"/>
+    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
+    <property name="defaultTransactionIsolation">
+      <util:constant static-field="${Master.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
+    </property>
+    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
+    <property name="initialSize" value="${Master.pool.initialSize:0}"/>
+    <property name="maxTotal" value="${Master.pool.maxActive:8}"/>
+    <property name="maxIdle" value="${Master.pool.maxIdle:8}"/>
+    <property name="minIdle" value="${Master.pool.minIdle:0}"/>
+    <property name="maxWaitMillis" value="${Master.pool.maxWait:-1}"/>
+    <property name="validationQuery" value="${Master.pool.validationQuery}"/>
+    <property name="validationQueryTimeout" value="${Master.pool.validationQueryTimeout:-1}"/>
+    <property name="testOnBorrow" value="${Master.pool.testOnBorrow:true}"/>
+    <property name="testOnReturn" value="${Master.pool.testOnReturn:false}"/>
+    <property name="testWhileIdle" value="${Master.pool.testWhileIdle:false}"/>
+    <property name="timeBetweenEvictionRunsMillis" value="${Master.pool.timeBetweenEvictionRunsMillis:-1}"/>
+    <property name="numTestsPerEvictionRun" value="${Master.pool.numTestsPerEvictionRun:3}"/>
+    <property name="minEvictableIdleTimeMillis" value="${Master.pool.minEvictableIdleTimeMillis:1800000}"/>
+    <property name="removeAbandonedOnBorrow" value="${Master.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedOnMaintenance" value="${Master.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedTimeout" value="${Master.pool.removeAbandonedTimeout:300}"/>
+    <property name="logAbandoned" value="${Master.pool.logAbandoned:false}"/>
+  </bean>
+  
+  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/audit/${Master.audit.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+  
+  <bean id="MasterEntityManagerFactory"
+        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
+    <property name="mappingResources">
+      <list>
+        <value>${Master.orm}</value>
+      </list>
+    </property>
+    <property name="persistenceUnitName" value="Master"/>
+    <property name="dataSource" ref="MasterDataSource"/>
+    <property name="jpaVendorAdapter">
+      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+        <property name="showSql" value="false"/>
+        <property name="generateDdl" value="true"/>
+        <property name="databasePlatform" value="${Master.databasePlatform}"/>
+      </bean>
+    </property>
+    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
+  </bean>  
+
+  <bean id="MasterTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+    <property name="entityManagerFactory" ref="MasterEntityManagerFactory"/>
+    <qualifier value="Master"/>
+  </bean>
+  
+  <tx:annotation-driven transaction-manager="MasterTransactionManager"/>
+  
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistence.properties b/core/persistence-jpa/src/main/resources/persistence.properties
index 57f1af0..5aa696c 100644
--- a/core/persistence-jpa/src/main/resources/persistence.properties
+++ b/core/persistence-jpa/src/main/resources/persistence.properties
@@ -15,16 +15,3 @@
 # specific language governing permissions and limitations
 # under the License.
 content.directory=${conf.directory}
-jpa.driverClassName=org.postgresql.Driver
-jpa.url=jdbc:postgresql://localhost:5432/syncope
-jpa.username=syncope
-jpa.password=syncope
-jpa.dialect=org.apache.openjpa.jdbc.sql.PostgresDictionary
-jpa.pool.validationQuery=SELECT 1
-jpa.orm=META-INF/spring-orm.xml
-# note: other connection pool settings can also be configured here, see persistenceContext.xml
-quartz.jobstore=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
-quartz.sql=tables_postgres.sql
-audit.sql=audit.sql
-database.schema=
-

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/persistenceContext.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContext.xml b/core/persistence-jpa/src/main/resources/persistenceContext.xml
index bea1729..ad2d837 100644
--- a/core/persistence-jpa/src/main/resources/persistenceContext.xml
+++ b/core/persistence-jpa/src/main/resources/persistenceContext.xml
@@ -20,53 +20,19 @@ under the License.
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:tx="http://www.springframework.org/schema/tx"
-       xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
-                           http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/tx
-                           http://www.springframework.org/schema/tx/spring-tx.xsd
-                           http://www.springframework.org/schema/util
-                           http://www.springframework.org/schema/util/spring-util.xsd">
-
+                           http://www.springframework.org/schema/context/spring-context.xsd">
   
-  <import resource="classpath:persistenceContextEMFactory.xml"/>
+  <import resource="domains.xml"/>
 
-  <bean id="nonJPAdbInitializer" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
-    <property name="dataSource" ref="dataSource"/>
-    <property name="enabled" value="true"/>
-    <property name="databasePopulator">
-      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
-        <property name="continueOnError" value="true"/>
-        <property name="ignoreFailedDrops" value="true"/>
-        <property name="sqlScriptEncoding" value="UTF-8"/>
-        <property name="scripts">
-          <array>
-            <value type="org.springframework.core.io.Resource">
-              classpath:/quartz/${quartz.sql}
-            </value>
-          </array>
-        </property>
-      </bean>
-    </property>
-  </bean>
-  
   <context:annotation-config/>
+  
   <context:component-scan base-package="org.apache.syncope.core.persistence.jpa"/>
 
-  <bean id="database.schema" class="java.lang.String">
-    <constructor-arg value="${database.schema}"/>
-  </bean>
-  <bean id="persistenceProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/persistence.properties"/>
-    <property name="fallback" value="classpath:persistence.properties"/>
-  </bean>
-  <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${content.directory}/content.xml"/>
-    <property name="fallback" value="classpath:content.xml"/>
-  </bean>
+  <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
+
   <bean id="viewsXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${content.directory}/views.xml"/>
     <property name="fallback" value="classpath:views.xml"/>
@@ -75,52 +41,5 @@ under the License.
     <property name="primary" value="file:${content.directory}/indexes.xml"/>
     <property name="fallback" value="classpath:indexes.xml"/>
   </bean>
-
-  <!-- Use JNDI datasource as default but, when not available, revert to
-  local datasource, with different properties for execution and testing. 
-  In any case, get all JDBC connections with a determined isolation level. -->
-  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
-    <property name="jndiName" value="java:comp/env/jdbc/syncopeDataSource"/>
-    <property name="defaultObject" ref="localDataSource"/>
-  </bean>
-
-  <bean id="localDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
-    <property name="driverClassName" value="${jpa.driverClassName}"/>
-    <property name="url" value="${jpa.url}"/>
-    <property name="username" value="${jpa.username}"/>
-    <property name="password" value="${jpa.password}"/>
-    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
-    <property name="defaultTransactionIsolation">
-      <util:constant static-field="${jpa.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
-    </property>
-    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
-    <property name="initialSize" value="${jpa.pool.initialSize:0}"/>
-    <property name="maxTotal" value="${jpa.pool.maxActive:8}"/>
-    <property name="maxIdle" value="${jpa.pool.maxIdle:8}"/>
-    <property name="minIdle" value="${jpa.pool.minIdle:0}"/>
-    <property name="maxWaitMillis" value="${jpa.pool.maxWait:-1}"/>
-    <property name="validationQuery" value="${jpa.pool.validationQuery}"/>
-    <property name="validationQueryTimeout" value="${jpa.pool.validationQueryTimeout:-1}"/>
-    <property name="testOnBorrow" value="${jpa.pool.testOnBorrow:true}"/>
-    <property name="testOnReturn" value="${jpa.pool.testOnReturn:false}"/>
-    <property name="testWhileIdle" value="${jpa.pool.testWhileIdle:false}"/>
-    <property name="timeBetweenEvictionRunsMillis" value="${jpa.pool.timeBetweenEvictionRunsMillis:-1}"/>
-    <property name="numTestsPerEvictionRun" value="${jpa.pool.numTestsPerEvictionRun:3}"/>
-    <property name="minEvictableIdleTimeMillis" value="${jpa.pool.minEvictableIdleTimeMillis:1800000}"/>
-    <property name="removeAbandonedOnBorrow" value="${jpa.pool.removeAbandoned:false}"/>
-    <property name="removeAbandonedOnMaintenance" value="${jpa.pool.removeAbandoned:false}"/>
-    <property name="removeAbandonedTimeout" value="${jpa.pool.removeAbandonedTimeout:300}"/>
-    <property name="logAbandoned" value="${jpa.pool.logAbandoned:false}"/>
-  </bean>
-
-  <bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
-    <property name="entityManagerFactory" ref="entityManagerFactory"/>
-  </bean>
-
-  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-    <property name="entityManagerFactory" ref="entityManagerFactory"/>
-  </bean>
-  <tx:annotation-driven/>
-
-  <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
+  
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml b/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
deleted file mode 100644
index 5983ca6..0000000
--- a/core/persistence-jpa/src/main/resources/persistenceContextEMFactory.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you 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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                           http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-  <bean id="entityManagerFactory"
-        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
-    <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
-    <property name="validationMode" value="NONE"/>
-    <property name="mappingResources">
-      <list>
-        <value>${jpa.orm}</value>
-      </list>
-    </property>
-    <property name="persistenceUnitName" value="syncopePersistenceUnit"/>
-    <property name="persistenceUnitPostProcessors">
-      <list>
-        <bean class="org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor"/>
-      </list>
-    </property>
-    <property name="dataSource" ref="dataSource"/>
-    <property name="jpaVendorAdapter">
-      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
-        <property name="showSql" value="false"/>
-        <property name="generateDdl" value="true"/>
-        <property name="databasePlatform" value="${jpa.dialect}"/>
-      </bean>
-    </property>
-    <property name="jpaPropertyMap">
-      <map>
-        <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
-        <entry key="openjpa.ConnectionFactoryProperties" 
-        value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
-                                
-        <entry key="openjpa.NontransactionalWrite" value="false"/>
-        <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
-
-        <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
-        <entry key="openjpa.jdbc.MappingDefaults" 
-               value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
-                
-        <entry key="openjpa.DataCache" value="true"/>
-        <entry key="openjpa.QueryCache" value="true"/>
-        <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
-      </map>
-    </property>
-  </bean>
-
-</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql b/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql
deleted file mode 100644
index e798223..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_h2.sql
+++ /dev/null
@@ -1,266 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
--- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database, 
--- and verifying that it works with Quartz's StdJDBCDelegate
---
--- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE 
--- setting on your H2 database, or you will experience dead-locks
---
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-
-CREATE TABLE QRTZ_CALENDARS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  CALENDAR_NAME VARCHAR (200)  NOT NULL ,
-  CALENDAR IMAGE NOT NULL
-);
-
-CREATE TABLE QRTZ_CRON_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  CRON_EXPRESSION VARCHAR (120)  NOT NULL ,
-  TIME_ZONE_ID VARCHAR (80) 
-);
-
-CREATE TABLE QRTZ_FIRED_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  ENTRY_ID VARCHAR (95)  NOT NULL ,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
-  FIRED_TIME BIGINT NOT NULL ,
-  SCHED_TIME BIGINT NOT NULL ,
-  PRIORITY INTEGER NOT NULL ,
-  STATE VARCHAR (16)  NOT NULL,
-  JOB_NAME VARCHAR (200)  NULL ,
-  JOB_GROUP VARCHAR (200)  NULL ,
-  IS_NONCONCURRENT BOOLEAN  NULL ,
-  REQUESTS_RECOVERY BOOLEAN  NULL 
-);
-
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL 
-);
-
-CREATE TABLE QRTZ_SCHEDULER_STATE (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  INSTANCE_NAME VARCHAR (200)  NOT NULL ,
-  LAST_CHECKIN_TIME BIGINT NOT NULL ,
-  CHECKIN_INTERVAL BIGINT NOT NULL
-);
-
-CREATE TABLE QRTZ_LOCKS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  LOCK_NAME VARCHAR (40)  NOT NULL 
-);
-
-CREATE TABLE QRTZ_JOB_DETAILS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  JOB_NAME VARCHAR (200)  NOT NULL ,
-  JOB_GROUP VARCHAR (200)  NOT NULL ,
-  DESCRIPTION VARCHAR (250) NULL ,
-  JOB_CLASS_NAME VARCHAR (250)  NOT NULL ,
-  IS_DURABLE BOOLEAN  NOT NULL ,
-  IS_NONCONCURRENT BOOLEAN  NOT NULL ,
-  IS_UPDATE_DATA BOOLEAN  NOT NULL ,
-  REQUESTS_RECOVERY BOOLEAN  NOT NULL ,
-  JOB_DATA IMAGE NULL
-);
-
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  REPEAT_COUNT BIGINT NOT NULL ,
-  REPEAT_INTERVAL BIGINT NOT NULL ,
-  TIMES_TRIGGERED BIGINT NOT NULL
-);
-
-CREATE TABLE qrtz_simprop_triggers
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INTEGER NULL,
-    INT_PROP_2 INTEGER NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 BOOLEAN NULL,
-    BOOL_PROP_2 BOOLEAN NULL,
-);
-
-CREATE TABLE QRTZ_BLOB_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  BLOB_DATA IMAGE NULL
-);
-
-CREATE TABLE QRTZ_TRIGGERS (
-  SCHED_NAME VARCHAR(120) NOT NULL,
-  TRIGGER_NAME VARCHAR (200)  NOT NULL ,
-  TRIGGER_GROUP VARCHAR (200)  NOT NULL ,
-  JOB_NAME VARCHAR (200)  NOT NULL ,
-  JOB_GROUP VARCHAR (200)  NOT NULL ,
-  DESCRIPTION VARCHAR (250) NULL ,
-  NEXT_FIRE_TIME BIGINT NULL ,
-  PREV_FIRE_TIME BIGINT NULL ,
-  PRIORITY INTEGER NULL ,
-  TRIGGER_STATE VARCHAR (16)  NOT NULL ,
-  TRIGGER_TYPE VARCHAR (8)  NOT NULL ,
-  START_TIME BIGINT NOT NULL ,
-  END_TIME BIGINT NULL ,
-  CALENDAR_NAME VARCHAR (200)  NULL ,
-  MISFIRE_INSTR SMALLINT NULL ,
-  JOB_DATA IMAGE NULL
-);
-
-ALTER TABLE QRTZ_CALENDARS  ADD
-  CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    CALENDAR_NAME
-  );
-
-ALTER TABLE QRTZ_CRON_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_FIRED_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    ENTRY_ID
-  );
-
-ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS  ADD
-  CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_SCHEDULER_STATE  ADD
-  CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY  
-  (
-    SCHED_NAME,
-    INSTANCE_NAME
-  );
-
-ALTER TABLE QRTZ_LOCKS  ADD
-  CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    LOCK_NAME
-  );
-
-ALTER TABLE QRTZ_JOB_DETAILS  ADD
-  CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    JOB_NAME,
-    JOB_GROUP
-  );
-
-ALTER TABLE QRTZ_SIMPLE_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_SIMPROP_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_TRIGGERS  ADD
-  CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY  
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  );
-
-ALTER TABLE QRTZ_CRON_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) REFERENCES QRTZ_TRIGGERS (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) ON DELETE CASCADE;
-
-
-ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) REFERENCES QRTZ_TRIGGERS (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) ON DELETE CASCADE;
-
-ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
-  (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) REFERENCES QRTZ_TRIGGERS (
-    SCHED_NAME,
-    TRIGGER_NAME,
-    TRIGGER_GROUP
-  ) ON DELETE CASCADE;
-
-
-ALTER TABLE QRTZ_TRIGGERS ADD
-  CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
-  (
-    SCHED_NAME,
-    JOB_NAME,
-    JOB_GROUP
-  ) REFERENCES QRTZ_JOB_DETAILS (
-    SCHED_NAME,
-    JOB_NAME,
-    JOB_GROUP
-  );
-  
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql b/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql
deleted file mode 100644
index ebb8e59..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_mariadb.sql
+++ /dev/null
@@ -1,206 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
---
--- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
---
--- PLEASE consider using mysql with innodb tables to avoid locking issues
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
---
-
-BEGIN;
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-COMMIT;
-
-
-BEGIN;
-CREATE TABLE QRTZ_JOB_DETAILS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
-    IS_DURABLE VARCHAR(1) NOT NULL,
-    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
-    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    NEXT_FIRE_TIME BIGINT(13) NULL,
-    PREV_FIRE_TIME BIGINT(13) NULL,
-    PRIORITY INTEGER NULL,
-    TRIGGER_STATE VARCHAR(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR(8) NOT NULL,
-    START_TIME BIGINT(13) NOT NULL,
-    END_TIME BIGINT(13) NULL,
-    CALENDAR_NAME VARCHAR(200) NULL,
-    MISFIRE_INSTR SMALLINT(2) NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    REPEAT_COUNT BIGINT(7) NOT NULL,
-    REPEAT_INTERVAL BIGINT(12) NOT NULL,
-    TIMES_TRIGGERED BIGINT(10) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CRON_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR(200) NOT NULL,
-    TIME_ZONE_ID VARCHAR(80),
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPROP_TRIGGERS
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR(1) NULL,
-    BOOL_PROP_2 VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_BLOB_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    BLOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CALENDARS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR(200) NOT NULL,
-    CALENDAR BLOB NOT NULL,
-    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_FIRED_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    ENTRY_ID VARCHAR(95) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    FIRED_TIME BIGINT(13) NOT NULL,
-    SCHED_TIME BIGINT(13) NOT NULL,
-    PRIORITY INTEGER NOT NULL,
-    STATE VARCHAR(16) NOT NULL,
-    JOB_NAME VARCHAR(200) NULL,
-    JOB_GROUP VARCHAR(200) NULL,
-    IS_NONCONCURRENT VARCHAR(1) NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SCHEDULER_STATE
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
-    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_LOCKS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    LOCK_NAME  VARCHAR(40) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql b/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql
deleted file mode 100644
index ebb8e59..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_mysql.sql
+++ /dev/null
@@ -1,206 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
---
--- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
---
--- PLEASE consider using mysql with innodb tables to avoid locking issues
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
---
-
-BEGIN;
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-COMMIT;
-
-
-BEGIN;
-CREATE TABLE QRTZ_JOB_DETAILS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
-    IS_DURABLE VARCHAR(1) NOT NULL,
-    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
-    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    NEXT_FIRE_TIME BIGINT(13) NULL,
-    PREV_FIRE_TIME BIGINT(13) NULL,
-    PRIORITY INTEGER NULL,
-    TRIGGER_STATE VARCHAR(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR(8) NOT NULL,
-    START_TIME BIGINT(13) NOT NULL,
-    END_TIME BIGINT(13) NULL,
-    CALENDAR_NAME VARCHAR(200) NULL,
-    MISFIRE_INSTR SMALLINT(2) NULL,
-    JOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    REPEAT_COUNT BIGINT(7) NOT NULL,
-    REPEAT_INTERVAL BIGINT(12) NOT NULL,
-    TIMES_TRIGGERED BIGINT(10) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CRON_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR(200) NOT NULL,
-    TIME_ZONE_ID VARCHAR(80),
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPROP_TRIGGERS
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR(1) NULL,
-    BOOL_PROP_2 VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_BLOB_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    BLOB_DATA BLOB NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CALENDARS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR(200) NOT NULL,
-    CALENDAR BLOB NOT NULL,
-    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_FIRED_TRIGGERS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    ENTRY_ID VARCHAR(95) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    FIRED_TIME BIGINT(13) NOT NULL,
-    SCHED_TIME BIGINT(13) NOT NULL,
-    PRIORITY INTEGER NOT NULL,
-    STATE VARCHAR(16) NOT NULL,
-    JOB_NAME VARCHAR(200) NULL,
-    JOB_GROUP VARCHAR(200) NULL,
-    IS_NONCONCURRENT VARCHAR(1) NULL,
-    REQUESTS_RECOVERY VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SCHEDULER_STATE
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
-    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
-    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_LOCKS
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    LOCK_NAME  VARCHAR(40) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql b/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql
deleted file mode 100644
index c54493e..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_mysql_innodb.sql
+++ /dev/null
@@ -1,221 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
---
---
--- By: Ron Cordell - roncordell
--- I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
---
-
-BEGIN;
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_JOB_DETAILS(
-SCHED_NAME VARCHAR(120) NOT NULL,
-JOB_NAME VARCHAR(200) NOT NULL,
-JOB_GROUP VARCHAR(200) NOT NULL,
-DESCRIPTION VARCHAR(250) NULL,
-JOB_CLASS_NAME VARCHAR(250) NOT NULL,
-IS_DURABLE VARCHAR(1) NOT NULL,
-IS_NONCONCURRENT VARCHAR(1) NOT NULL,
-IS_UPDATE_DATA VARCHAR(1) NOT NULL,
-REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
-JOB_DATA BLOB NULL,
-PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-JOB_NAME VARCHAR(200) NOT NULL,
-JOB_GROUP VARCHAR(200) NOT NULL,
-DESCRIPTION VARCHAR(250) NULL,
-NEXT_FIRE_TIME BIGINT(13) NULL,
-PREV_FIRE_TIME BIGINT(13) NULL,
-PRIORITY INTEGER NULL,
-TRIGGER_STATE VARCHAR(16) NOT NULL,
-TRIGGER_TYPE VARCHAR(8) NOT NULL,
-START_TIME BIGINT(13) NOT NULL,
-END_TIME BIGINT(13) NULL,
-CALENDAR_NAME VARCHAR(200) NULL,
-MISFIRE_INSTR SMALLINT(2) NULL,
-JOB_DATA BLOB NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-REPEAT_COUNT BIGINT(7) NOT NULL,
-REPEAT_INTERVAL BIGINT(12) NOT NULL,
-TIMES_TRIGGERED BIGINT(10) NOT NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CRON_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-CRON_EXPRESSION VARCHAR(120) NOT NULL,
-TIME_ZONE_ID VARCHAR(80),
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SIMPROP_TRIGGERS
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR(1) NULL,
-    BOOL_PROP_2 VARCHAR(1) NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_BLOB_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-BLOB_DATA BLOB NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
-FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_CALENDARS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-CALENDAR_NAME VARCHAR(200) NOT NULL,
-CALENDAR BLOB NOT NULL,
-PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_FIRED_TRIGGERS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-ENTRY_ID VARCHAR(95) NOT NULL,
-TRIGGER_NAME VARCHAR(200) NOT NULL,
-TRIGGER_GROUP VARCHAR(200) NOT NULL,
-INSTANCE_NAME VARCHAR(200) NOT NULL,
-FIRED_TIME BIGINT(13) NOT NULL,
-SCHED_TIME BIGINT(13) NOT NULL,
-PRIORITY INTEGER NOT NULL,
-STATE VARCHAR(16) NOT NULL,
-JOB_NAME VARCHAR(200) NULL,
-JOB_GROUP VARCHAR(200) NULL,
-IS_NONCONCURRENT VARCHAR(1) NULL,
-REQUESTS_RECOVERY VARCHAR(1) NULL,
-PRIMARY KEY (SCHED_NAME,ENTRY_ID))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_SCHEDULER_STATE (
-SCHED_NAME VARCHAR(120) NOT NULL,
-INSTANCE_NAME VARCHAR(200) NOT NULL,
-LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
-CHECKIN_INTERVAL BIGINT(13) NOT NULL,
-PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE TABLE QRTZ_LOCKS (
-SCHED_NAME VARCHAR(120) NOT NULL,
-LOCK_NAME VARCHAR(40) NOT NULL,
-PRIMARY KEY (SCHED_NAME,LOCK_NAME))
-ENGINE=InnoDB;
-COMMIT;
-
-BEGIN;
-CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
-CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
-
-CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
-CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
-CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
-CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
-CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
-CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
-CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
-
-CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
-CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
-CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
-CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
-CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
-COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql b/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql
deleted file mode 100644
index 4384ac5..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_oracle.sql
+++ /dev/null
@@ -1,208 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
---
--- A hint submitted by a user: Oracle DB MUST be created as "shared" and the 
--- job_queue_processes parameter  must be greater than 2
--- However, these settings are pretty much standard after any
--- Oracle install, so most users need not worry about this.
---
--- Many other users (including the primary author of Quartz) have had success
--- runing in dedicated mode, so only consider the above as a hint ;-)
---
-
-delete from qrtz_fired_triggers;
-delete from qrtz_simple_triggers;
-delete from qrtz_simprop_triggers;
-delete from qrtz_cron_triggers;
-delete from qrtz_blob_triggers;
-delete from qrtz_triggers;
-delete from qrtz_job_details;
-delete from qrtz_calendars;
-delete from qrtz_paused_trigger_grps;
-delete from qrtz_locks;
-delete from qrtz_scheduler_state;
-
-drop table qrtz_calendars;
-drop table qrtz_fired_triggers;
-drop table qrtz_blob_triggers;
-drop table qrtz_cron_triggers;
-drop table qrtz_simple_triggers;
-drop table qrtz_simprop_triggers;
-drop table qrtz_triggers;
-drop table qrtz_job_details;
-drop table qrtz_paused_trigger_grps;
-drop table qrtz_locks;
-drop table qrtz_scheduler_state;
-
-
-CREATE TABLE qrtz_job_details
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    JOB_NAME  VARCHAR2(200) NOT NULL,
-    JOB_GROUP VARCHAR2(200) NOT NULL,
-    DESCRIPTION VARCHAR2(250) NULL,
-    JOB_CLASS_NAME   VARCHAR2(250) NOT NULL, 
-    IS_DURABLE VARCHAR2(1) NOT NULL,
-    IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
-    IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
-    REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
-    JOB_DATA BLOB NULL,
-    CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-CREATE TABLE qrtz_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    JOB_NAME  VARCHAR2(200) NOT NULL, 
-    JOB_GROUP VARCHAR2(200) NOT NULL,
-    DESCRIPTION VARCHAR2(250) NULL,
-    NEXT_FIRE_TIME NUMBER(13) NULL,
-    PREV_FIRE_TIME NUMBER(13) NULL,
-    PRIORITY NUMBER(13) NULL,
-    TRIGGER_STATE VARCHAR2(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR2(8) NOT NULL,
-    START_TIME NUMBER(13) NOT NULL,
-    END_TIME NUMBER(13) NULL,
-    CALENDAR_NAME VARCHAR2(200) NULL,
-    MISFIRE_INSTR NUMBER(2) NULL,
-    JOB_DATA BLOB NULL,
-    CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
-      REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
-);
-CREATE TABLE qrtz_simple_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    REPEAT_COUNT NUMBER(7) NOT NULL,
-    REPEAT_INTERVAL NUMBER(12) NOT NULL,
-    TIMES_TRIGGERED NUMBER(10) NOT NULL,
-    CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_cron_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR2(120) NOT NULL,
-    TIME_ZONE_ID VARCHAR2(80),
-    CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_simprop_triggers
-  (          
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    STR_PROP_1 VARCHAR2(512) NULL,
-    STR_PROP_2 VARCHAR2(512) NULL,
-    STR_PROP_3 VARCHAR2(512) NULL,
-    INT_PROP_1 NUMBER(10) NULL,
-    INT_PROP_2 NUMBER(10) NULL,
-    LONG_PROP_1 NUMBER(13) NULL,
-    LONG_PROP_2 NUMBER(13) NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 VARCHAR2(1) NULL,
-    BOOL_PROP_2 VARCHAR2(1) NULL,
-    CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_blob_triggers
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    BLOB_DATA BLOB NULL,
-    CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_calendars
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR2(200) NOT NULL, 
-    CALENDAR BLOB NOT NULL,
-    CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-CREATE TABLE qrtz_paused_trigger_grps
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR2(200) NOT NULL, 
-    CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-CREATE TABLE qrtz_fired_triggers 
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    ENTRY_ID VARCHAR2(95) NOT NULL,
-    TRIGGER_NAME VARCHAR2(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
-    INSTANCE_NAME VARCHAR2(200) NOT NULL,
-    FIRED_TIME NUMBER(13) NOT NULL,
-    SCHED_TIME NUMBER(13) NOT NULL,
-    PRIORITY NUMBER(13) NOT NULL,
-    STATE VARCHAR2(16) NOT NULL,
-    JOB_NAME VARCHAR2(200) NULL,
-    JOB_GROUP VARCHAR2(200) NULL,
-    IS_NONCONCURRENT VARCHAR2(1) NULL,
-    REQUESTS_RECOVERY VARCHAR2(1) NULL,
-    CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-CREATE TABLE qrtz_scheduler_state 
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    INSTANCE_NAME VARCHAR2(200) NOT NULL,
-    LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
-    CHECKIN_INTERVAL NUMBER(13) NOT NULL,
-    CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-CREATE TABLE qrtz_locks
-  (
-    SCHED_NAME VARCHAR2(120) NOT NULL,
-    LOCK_NAME  VARCHAR2(40) NOT NULL, 
-    CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-
-create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
-
-create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
-create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
-create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
-create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
-create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
-
-create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
-create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
-create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql b/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql
deleted file mode 100644
index 9b7800f..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_postgres.sql
+++ /dev/null
@@ -1,204 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
--- Thanks to Patrick Lightbody for submitting this...
---
--- In your Quartz properties file, you'll need to set 
--- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
-
-drop table qrtz_fired_triggers;
-DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE QRTZ_SCHEDULER_STATE;
-DROP TABLE QRTZ_LOCKS;
-drop table qrtz_simple_triggers;
-drop table qrtz_cron_triggers;
-drop table qrtz_simprop_triggers;
-DROP TABLE QRTZ_BLOB_TRIGGERS;
-drop table qrtz_triggers;
-drop table qrtz_job_details;
-drop table qrtz_calendars;
-
-CREATE TABLE qrtz_job_details
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL,
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    JOB_CLASS_NAME   VARCHAR(250) NOT NULL, 
-    IS_DURABLE BOOL NOT NULL,
-    IS_NONCONCURRENT BOOL NOT NULL,
-    IS_UPDATE_DATA BOOL NOT NULL,
-    REQUESTS_RECOVERY BOOL NOT NULL,
-    JOB_DATA BYTEA NULL,
-    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
-);
-
-CREATE TABLE qrtz_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    JOB_NAME  VARCHAR(200) NOT NULL, 
-    JOB_GROUP VARCHAR(200) NOT NULL,
-    DESCRIPTION VARCHAR(250) NULL,
-    NEXT_FIRE_TIME BIGINT NULL,
-    PREV_FIRE_TIME BIGINT NULL,
-    PRIORITY INTEGER NULL,
-    TRIGGER_STATE VARCHAR(16) NOT NULL,
-    TRIGGER_TYPE VARCHAR(8) NOT NULL,
-    START_TIME BIGINT NOT NULL,
-    END_TIME BIGINT NULL,
-    CALENDAR_NAME VARCHAR(200) NULL,
-    MISFIRE_INSTR SMALLINT NULL,
-    JOB_DATA BYTEA NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
-	REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
-);
-
-CREATE TABLE qrtz_simple_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    REPEAT_COUNT BIGINT NOT NULL,
-    REPEAT_INTERVAL BIGINT NOT NULL,
-    TIMES_TRIGGERED BIGINT NOT NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_cron_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    CRON_EXPRESSION VARCHAR(120) NOT NULL,
-    TIME_ZONE_ID VARCHAR(80),
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_simprop_triggers
-  (          
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    STR_PROP_1 VARCHAR(512) NULL,
-    STR_PROP_2 VARCHAR(512) NULL,
-    STR_PROP_3 VARCHAR(512) NULL,
-    INT_PROP_1 INT NULL,
-    INT_PROP_2 INT NULL,
-    LONG_PROP_1 BIGINT NULL,
-    LONG_PROP_2 BIGINT NULL,
-    DEC_PROP_1 NUMERIC(13,4) NULL,
-    DEC_PROP_2 NUMERIC(13,4) NULL,
-    BOOL_PROP_1 BOOL NULL,
-    BOOL_PROP_2 BOOL NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_blob_triggers
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    BLOB_DATA BYTEA NULL,
-    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
-    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
-        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_calendars
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    CALENDAR_NAME  VARCHAR(200) NOT NULL, 
-    CALENDAR BYTEA NOT NULL,
-    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
-);
-
-
-CREATE TABLE qrtz_paused_trigger_grps
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
-);
-
-CREATE TABLE qrtz_fired_triggers 
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    ENTRY_ID VARCHAR(95) NOT NULL,
-    TRIGGER_NAME VARCHAR(200) NOT NULL,
-    TRIGGER_GROUP VARCHAR(200) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    FIRED_TIME BIGINT NOT NULL,
-    SCHED_TIME BIGINT NOT NULL,
-    PRIORITY INTEGER NOT NULL,
-    STATE VARCHAR(16) NOT NULL,
-    JOB_NAME VARCHAR(200) NULL,
-    JOB_GROUP VARCHAR(200) NULL,
-    IS_NONCONCURRENT BOOL NULL,
-    REQUESTS_RECOVERY BOOL NULL,
-    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
-);
-
-CREATE TABLE qrtz_scheduler_state 
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    INSTANCE_NAME VARCHAR(200) NOT NULL,
-    LAST_CHECKIN_TIME BIGINT NOT NULL,
-    CHECKIN_INTERVAL BIGINT NOT NULL,
-    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
-);
-
-CREATE TABLE qrtz_locks
-  (
-    SCHED_NAME VARCHAR(120) NOT NULL,
-    LOCK_NAME  VARCHAR(40) NOT NULL, 
-    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
-);
-
-create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
-
-create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
-create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
-create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
-create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
-create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
-create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
-create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
-
-create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
-create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
-create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
-create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
-create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
-create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
-
-
-commit;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql b/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql
deleted file mode 100644
index 288b990..0000000
--- a/core/persistence-jpa/src/main/resources/quartz/tables_sqlServer.sql
+++ /dev/null
@@ -1,296 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you 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.
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
-ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS;
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_CALENDARS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_LOCKS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_JOB_DETAILS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS];
-
-IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
-DROP TABLE [dbo].[QRTZ_TRIGGERS];
-
-CREATE TABLE [dbo].[QRTZ_CALENDARS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [CALENDAR_NAME] [VARCHAR] (200)  NOT NULL ,
-  [CALENDAR] [IMAGE] NOT NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [CRON_EXPRESSION] [VARCHAR] (120)  NOT NULL ,
-  [TIME_ZONE_ID] [VARCHAR] (80) 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [ENTRY_ID] [VARCHAR] (95)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
-  [FIRED_TIME] [BIGINT] NOT NULL ,
-  [SCHED_TIME] [BIGINT] NOT NULL ,
-  [PRIORITY] [INTEGER] NOT NULL ,
-  [STATE] [VARCHAR] (16)  NOT NULL,
-  [JOB_NAME] [VARCHAR] (200)  NULL ,
-  [JOB_GROUP] [VARCHAR] (200)  NULL ,
-  [IS_NONCONCURRENT] [VARCHAR] (1)  NULL ,
-  [REQUESTS_RECOVERY] [VARCHAR] (1)  NULL 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [INSTANCE_NAME] [VARCHAR] (200)  NOT NULL ,
-  [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
-  [CHECKIN_INTERVAL] [BIGINT] NOT NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_LOCKS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [LOCK_NAME] [VARCHAR] (40)  NOT NULL 
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
-  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [DESCRIPTION] [VARCHAR] (250) NULL ,
-  [JOB_CLASS_NAME] [VARCHAR] (250)  NOT NULL ,
-  [IS_DURABLE] [VARCHAR] (1)  NOT NULL ,
-  [IS_NONCONCURRENT] [VARCHAR] (1)  NOT NULL ,
-  [IS_UPDATE_DATA] [VARCHAR] (1)  NOT NULL ,
-  [REQUESTS_RECOVERY] [VARCHAR] (1)  NOT NULL ,
-  [JOB_DATA] [IMAGE] NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [REPEAT_COUNT] [BIGINT] NOT NULL ,
-  [REPEAT_INTERVAL] [BIGINT] NOT NULL ,
-  [TIMES_TRIGGERED] [BIGINT] NOT NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [STR_PROP_1] [VARCHAR] (512) NULL,
-  [STR_PROP_2] [VARCHAR] (512) NULL,
-  [STR_PROP_3] [VARCHAR] (512) NULL,
-  [INT_PROP_1] [INT] NULL,
-  [INT_PROP_2] [INT] NULL,
-  [LONG_PROP_1] [BIGINT] NULL,
-  [LONG_PROP_2] [BIGINT] NULL,
-  [DEC_PROP_1] [NUMERIC] (13,4) NULL,
-  [DEC_PROP_2] [NUMERIC] (13,4) NULL,
-  [BOOL_PROP_1] [VARCHAR] (1) NULL,
-  [BOOL_PROP_2] [VARCHAR] (1) NULL,
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [BLOB_DATA] [IMAGE] NULL
-) ON [PRIMARY];
-
-CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
-  [SCHED_NAME] [VARCHAR] (120)  NOT NULL ,
-  [TRIGGER_NAME] [VARCHAR] (200)  NOT NULL ,
-  [TRIGGER_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [JOB_NAME] [VARCHAR] (200)  NOT NULL ,
-  [JOB_GROUP] [VARCHAR] (200)  NOT NULL ,
-  [DESCRIPTION] [VARCHAR] (250) NULL ,
-  [NEXT_FIRE_TIME] [BIGINT] NULL ,
-  [PREV_FIRE_TIME] [BIGINT] NULL ,
-  [PRIORITY] [INTEGER] NULL ,
-  [TRIGGER_STATE] [VARCHAR] (16)  NOT NULL ,
-  [TRIGGER_TYPE] [VARCHAR] (8)  NOT NULL ,
-  [START_TIME] [BIGINT] NOT NULL ,
-  [END_TIME] [BIGINT] NULL ,
-  [CALENDAR_NAME] [VARCHAR] (200)  NULL ,
-  [MISFIRE_INSTR] [SMALLINT] NULL ,
-  [JOB_DATA] [IMAGE] NULL
-) ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [CALENDAR_NAME]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [ENTRY_ID]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [INSTANCE_NAME]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [LOCK_NAME]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [JOB_NAME],
-    [JOB_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
-  CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY  CLUSTERED
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  )  ON [PRIMARY];
-
-ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) ON DELETE CASCADE;
-
-ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) ON DELETE CASCADE;
-
-ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
-    [SCHED_NAME],
-    [TRIGGER_NAME],
-    [TRIGGER_GROUP]
-  ) ON DELETE CASCADE;
-
-ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
-  CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
-  (
-    [SCHED_NAME],
-    [JOB_NAME],
-    [JOB_GROUP]
-  ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
-    [SCHED_NAME],
-    [JOB_NAME],
-    [JOB_GROUP]
-  );

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
index a3b6701..201708f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
@@ -18,15 +18,21 @@
  */
 package org.apache.syncope.core.persistence.jpa;
 
+import javax.persistence.EntityManager;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.TransactionConfiguration;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = { "classpath:persistenceTest.xml" })
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
 public abstract class AbstractTest {
 
     @Autowired
@@ -35,4 +41,14 @@ public abstract class AbstractTest {
     @Autowired
     protected AnyUtilsFactory anyUtilsFactory;
 
+    protected EntityManager entityManager() {
+        EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(
+                EntityManagerFactoryUtils.findEntityManagerFactory(
+                        ApplicationContextProvider.getBeanFactory(), AuthContextUtils.getDomain()));
+        if (entityManager == null) {
+            throw new IllegalStateException("Could not find EntityManager for domain " + AuthContextUtils.getDomain());
+        }
+
+        return entityManager;
+    }
 }


[07/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
new file mode 100644
index 0000000..2542a1a
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -0,0 +1,1131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<dataset>
+  <SyncopeDomain name="Two" adminCipherAlgorithm="SHA" adminPwd="2AA60A8FF7FCD473D321E0146AFD9E26DF395147"/>  
+  
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+  
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  
+  <!-- sample policies -->
+  <Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC" 
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+  <Policy DTYPE="PasswordPolicy" id="2" description="a password policy" type="PASSWORD" 
+          specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":true}'/>
+  <Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC" 
+          specification='{"conflictResolutionAction":"ALL","items":[{"anyTypeKey":"USER","javaRule":null,"altSearchSchemas":["username","firstname"]}]}'/>
+  <Policy DTYPE="PasswordPolicy" id="4" description="sample password policy" type="PASSWORD" 
+          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[], "allowNullPassword":true}'/>
+  <Policy DTYPE="AccountPolicy" id="5" description="an account policy" type="ACCOUNT" 
+          specification='{"maxLength":0,"minLength":0,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":0,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":[],"suffixesNotPermitted":[]}'/>
+  <Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT" 
+          specification='{"maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":3,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
+  <Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC" 
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+  <Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" 
+          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":false}'/>
+  <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+
+  <RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
+  <RelationshipType name="neighborhood"/>
+  
+  <AnyTypeClass name="generic membership"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="minimal user"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="minimal user"/>
+  <AnyTypeClass name="other"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="other"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  <AnyTypeClass name="minimal group"/>
+  <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
+  
+  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
+  <AnyTypeClass name="minimal printer"/>
+  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal printer"/>
+      
+  <AnyTypeClass name="csv"/>
+
+  <Realm id="1" name="/" passwordPolicy_id="4"/>
+  <Realm id="2" name="odd" parent_id="1" accountPolicy_id="6"/>
+  <Realm id="3" name="even" parent_id="1"/>
+  <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" passwordPolicy_id="2"/>
+  
+  <AnyObject id="1" realm_id="1" type_name="PRINTER"
+             creator="admin" lastModifier="admin" 
+             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <AnyObject id="2" realm_id="1" type_name="PRINTER"
+             creator="admin" lastModifier="admin" 
+             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  
+  <ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2" type_name="neighborhood"/>
+  
+  <SyncopeRole id="1" name="User reviewer"/>
+  <SyncopeRole_entitlements entitlement="USER_READ" role_id="1"/>
+  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="1"/>
+  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="1"/>
+  <SyncopeRole_Realm role_id="1" realm_id="2"/>
+  <SyncopeRole_Realm role_id="1" realm_id="3"/>
+  
+  <SyncopeRole id="2" name="User manager"/>
+  <SyncopeRole_entitlements entitlement="USER_READ" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="2"/>
+  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_SUBMIT" role_id="2"/>
+  <SyncopeRole_Realm role_id="2" realm_id="1"/>
+
+  <SyncopeRole id="3" name="Other"/>
+  <SyncopeRole_entitlements entitlement="SCHEMA_READ" role_id="3"/>
+  <SyncopeRole_entitlements entitlement="GROUP_READ" role_id="3"/>
+  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="3"/>
+  <SyncopeRole_Realm role_id="3" realm_id="2"/>
+  
+  <SyncopeRole id="4" name="Search for /even/two"/>
+  <SyncopeRole_entitlements entitlement="USER_READ" role_id="4"/>
+  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="4"/>
+  <SyncopeRole_Realm role_id="4" realm_id="4"/>
+
+  <SyncopeUser id="1" workflowId="4" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="3"
+               username="rossini" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser_SyncopeRole user_id="1" role_id="3"/>
+  <SyncopeUser id="2" workflowId="6" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="verdi" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser id="3" workflowId="8" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="vivaldi" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser id="4" workflowId="10" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="bellini" creator="admin" lastModifier="admin"
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser_SyncopeRole user_id="4" role_id="1"/>
+  <SyncopeUser_SyncopeRole user_id="4" role_id="2"/>
+  <SyncopeUser id="5" workflowId="12" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
+               realm_id="1"
+               username="puccini" creator="admin" lastModifier="admin" 
+               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
+  <SyncopeUser_SyncopeRole user_id="5" role_id="4"/>
+  
+  <SyncopeGroup id="1" name="root"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="2" name="child"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="3" name="citizen"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="4" name="employee"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="5" name="secretary"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="6" name="director" userOwner_id="5"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="7" name="managingDirector"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="8" name="otherchild"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="9" name="groupForWorkflowApproval"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="10" name="managingConsultant"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="11" name="groupForWorkflowOptIn"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup id="12" name="aGroupForPropagation"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup_AnyTypeClass group_id="12" anyTypeClass_name="csv"/>  
+  <SyncopeGroup id="13" name="bGroupForPropagation"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup_AnyTypeClass group_id="13" anyTypeClass_name="csv"/>  
+  <SyncopeGroup id="14" name="artDirector"
+                realm_id="1"
+                creator="admin" lastModifier="admin" 
+                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  
+  <URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
+
+  <UMembership id="1" user_id="1" group_id="1"/>
+  <UMembership id="2" user_id="2" group_id="1"/>
+  <UMembership id="3" user_id="2" group_id="2"/>
+  <UMembership id="4" user_id="4" group_id="7"/>
+  <UMembership id="5" user_id="1" group_id="8"/>
+  <UMembership id="6" user_id="2" group_id="3"/>
+  <UMembership id="7" user_id="5" group_id="14"/>
+
+  <PlainSchema name="fullname" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
+  <PlainSchema name="userId" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="loginDate" type="Date" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd"/>
+  <PlainSchema name="firstname" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="surname" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="type" type="String" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="email" type="String" anyTypeClass_name="minimal user"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  <PlainSchema name="activationDate" type="Date" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
+  <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
+  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               enumerationValues="M;F"/>
+  <PlainSchema name="aLong" type="Long" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="makeItDouble" type="Long" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="obscure" type="Encrypted" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
+  <PlainSchema name="photo" type="Binary" anyTypeClass_name="other"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               mimeType="image/jpeg"/>
+
+  <DerSchema name="csvuserid" expression="firstname + ',' + surname" anyTypeClass_name="csv"/>
+  <DerSchema name="cn" expression="surname + ', ' + firstname" anyTypeClass_name="minimal user"/>
+  <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/>
+
+  <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/>
+  <VirSchema name="virtualReadOnly" READONLY="1"  anyTypeClass_name="minimal user"/>
+
+  <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
+  <PlainSchema name="show" type="Boolean" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="rderived_sx" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="rderived_dx" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
+  <PlainSchema name="title" type="String" anyTypeClass_name="minimal group"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+
+  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"
+             anyTypeClass_name="minimal group"/>
+  <DerSchema name="displayProperty" expression="icon + ': ' + show"
+             anyTypeClass_name="minimal group"/>
+  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"
+             anyTypeClass_name="minimal group"/>
+
+  <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/>
+
+  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"  anyTypeClass_name="minimal group"/>
+
+  <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
+  <PlainSchema name="mderived_sx" type="String" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="mderived_dx" type="String" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
+  <PlainSchema name="postalAddress" type="String" anyTypeClass_name="generic membership"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+
+  <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
+  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx" 
+             anyTypeClass_name="generic membership"/>
+
+  <VirSchema name="mvirtualdata"/>
+        
+  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="location" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+    
+  <APlainAttr id="1" owner_id="1" schema_name="model"/>
+  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
+  <APlainAttr id="2" owner_id="1" schema_name="location"/>
+  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
+    
+  <APlainAttr id="3" owner_id="2" schema_name="model"/>
+  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
+  <APlainAttr id="4" owner_id="2" schema_name="location"/>
+  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
+
+  <UPlainAttr id="99" owner_id="1" schema_name="type"/>
+  <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
+  <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="10" attribute_id="100" schema_name="fullname" stringValue="Gioacchino Rossini"/>
+  <UPlainAttr id="101" owner_id="1" schema_name="firstname"/>
+  <UPlainAttrValue id="11" attribute_id="101" stringValue="Gioacchino"/>
+  <UPlainAttr id="102" owner_id="1" schema_name="surname"/>
+  <UPlainAttrValue id="12" attribute_id="102" stringValue="Rossini"/>
+  <UPlainAttr id="103" owner_id="1" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="13" attribute_id="103" schema_name="userId" stringValue="rossini@apache.org"/>
+  <UPlainAttr id="104" owner_id="1" schema_name="loginDate"/>
+  <UPlainAttrValue id="14" attribute_id="104" dateValue="2009-05-26"/>
+  <UPlainAttrValue id="15" attribute_id="104" dateValue="2010-05-26 15:40:04"/>
+
+  <UPlainAttr id="105" owner_id="2" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="16" attribute_id="105" schema_name="fullname" stringValue="Giuseppe Verdi"/>
+  <UPlainAttr id="106" owner_id="2" schema_name="firstname"/>
+  <UPlainAttrValue id="17" attribute_id="106" stringValue="Giuseppe"/>
+  <UPlainAttr id="107" owner_id="2" schema_name="surname"/>
+  <UPlainAttrValue id="18" attribute_id="107" stringValue="Verdi"/>
+  <UPlainAttr id="108" owner_id="2" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="19" attribute_id="108" schema_name="userId" stringValue="verdi@apache.org"/>
+
+  <UPlainAttr id="109" owner_id="3" schema_name="firstname"/>
+  <UPlainAttrValue id="20" attribute_id="109" stringValue="Antonio"/>
+  <UPlainAttr id="110" owner_id="3" schema_name="surname"/>
+  <UPlainAttrValue id="21" attribute_id="110" stringValue="Vivaldi"/>
+  <UPlainAttr id="111" owner_id="3" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="22" attribute_id="111" schema_name="fullname" stringValue="Antonio Vivaldi"/>
+  <UPlainAttr id="112" owner_id="3" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="23" attribute_id="112" schema_name="userId" stringValue="vivaldi@apache.org"/>
+
+  <UPlainAttr id="113" owner_id="4" schema_name="firstname"/>
+  <UPlainAttrValue id="24" attribute_id="113" stringValue="Vincenzo"/>
+  <UPlainAttr id="114" owner_id="4" schema_name="surname"/>
+  <UPlainAttrValue id="25" attribute_id="114" stringValue="Bellini"/>
+  <UPlainAttr id="115" owner_id="4" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="26" attribute_id="115" schema_name="fullname" stringValue="Vincenzo Bellini"/>
+  <UPlainAttr id="116" owner_id="4" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="27" attribute_id="116" schema_name="userId" stringValue="bellini@apache.org"/>
+  <UPlainAttr id="117" owner_id="4" schema_name="loginDate"/>
+  <UPlainAttrValue id="28" attribute_id="117" dateValue="2009-06-24"/>
+  <UPlainAttr id="118" owner_id="4" schema_name="cool"/>
+  <UPlainAttrValue id="29" attribute_id="118" booleanValue="1"/>
+  <UPlainAttr id="119" owner_id="4" schema_name="gender"/>
+  <UPlainAttrValue id="30" attribute_id="119" stringValue="M"/>
+  
+  <UPlainAttr id="120" owner_id="5" schema_name="firstname"/>
+  <UPlainAttrValue id="31" attribute_id="120" stringValue="Giacomo"/>
+  <UPlainAttr id="121" owner_id="5" schema_name="surname"/>
+  <UPlainAttrValue id="32" attribute_id="121" stringValue="Puccini"/>
+  <UPlainAttr id="122" owner_id="5" schema_name="fullname"/>
+  <UPlainAttrUniqueValue id="33" attribute_id="122" schema_name="fullname" stringValue="Giacomo Puccini"/>
+  <UPlainAttr id="123" owner_id="5" schema_name="userId"/>
+  <UPlainAttrUniqueValue id="34" attribute_id="123" schema_name="userId" stringValue="puccini@apache.org"/>
+  
+  <UPlainAttr id="124" owner_id="2" schema_name="email"/>
+  <UPlainAttrValue id="35" attribute_id="124" stringValue="verdi@syncope.org"/>
+  <UPlainAttr id="125" owner_id="3" schema_name="email"/>
+  <UPlainAttrValue id="36" attribute_id="125" stringValue="vivaldi@syncope.org"/>
+  <UPlainAttr id="126" owner_id="3" schema_name="type"/>
+  <UPlainAttrValue id="37" attribute_id="126" stringValue="F"/>
+    
+  <UVirAttr id="100" schema_name="virtualdata" owner_id="3"/>
+  
+  <UDerAttr id="100" schema_name="cn" owner_id="3"/>
+  <UDerAttr id="101" schema_name="cn" owner_id="1"/>
+
+  <GPlainAttr id="600" owner_id="1" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="600" id="40" stringValue="niceIcon"/>
+
+  <GPlainAttr id="700" owner_id="2" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="700" id="41" stringValue="badIcon"/>
+
+  <GPlainAttr id="800" owner_id="1"  schema_name="show"/>
+  <GPlainAttrValue attribute_id="800" id="42" booleanValue="1"/>
+
+  <GPlainAttr id="900" owner_id="6" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="900" id="43" stringValue="icon6"/>
+
+  <GPlainAttr id="950" owner_id="4" schema_name="icon"/>
+  <GPlainAttrValue attribute_id="950" id="44" stringValue="icon4"/>
+
+  <GPlainAttr id="992" owner_id="1" schema_name="rderived_sx"/>
+  <GPlainAttrValue attribute_id="992" id="92" stringValue="sx"/>
+
+  <GPlainAttr id="993" owner_id="1" schema_name="rderived_dx"/>
+  <GPlainAttrValue attribute_id="993" id="93" stringValue="dx"/>
+
+  <GPlainAttr id="994" owner_id="12" schema_name="title"/>
+  <GPlainAttrValue attribute_id="994" id="94" stringValue="r12"/>
+  
+  <GPlainAttr id="995" owner_id="13" schema_name="title"/>
+  <GPlainAttrValue attribute_id="995" id="95" stringValue="r13"/>
+
+  <GDerAttr id="100" owner_id="1" schema_name="rderiveddata"/>
+    
+  <GDerAttr id="101" owner_id="1" schema_name="displayProperty"/>
+  
+  <GDerAttr id="102" owner_id="4" schema_name="displayProperty"/>
+
+  <GDerAttr id="103" owner_id="1" schema_name="rderToBePropagated"/>    
+
+  <GVirAttr id="98" owner_id="4" schema_name="rvirtualdata"/>
+
+  <ConnInstance id="100" displayName="ConnInstance100"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.soap"
+                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
+                version="${connid.soap.version}"
+                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="100" capability="SEARCH"/>
+
+  <ConnInstance id="101" displayName="H2"
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                bundleName="net.tirasa.connid.bundles.db.table"
+                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
+                version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 ":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capability="SYNC"/>
+
+  <ConnInstance id="102" displayName="ConnInstance102"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.soap"
+                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
+                version="${connid.soap.version}"
+                connRequestTimeout="10"
+                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="102" capability="SEARCH"/>
+
+  <ConnInstance id="103" displayName="ConnInstance103"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.soap"
+                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
+                version="${connid.soap.version}"
+                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
+
+  <ConnInstance id="104" displayName="CSVDir"
+                location="${connid.location}"
+                bundleName="net.tirasa.connid.bundles.csvdir"
+                connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
+                version="${connid.csvdir.version}"
+                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["name","surname"]},{"schema":{"name":"deleteColumnName","displayName":"Delete column name","helpMessage":"Name of the column used to specify users to be deleted","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["deleted"]},{"schema":{"name":"passwordColumnName","displayName":"Password column name","helpMessage":"Name
  of the column used to specify user password","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"keyseparator","displayName":"Key separator","helpMessage":"Character used to separate keys in a multi-key scenario","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"ignoreHeader","displayName":"Ignore header","helpMessage":"Specify it first line file must be ignored","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"fieldDelimiter","displayName":"fieldDelimiter","helpMessage":"fieldDelimiter","type":"char","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"quotationRequired","displayName":"Value quotation requi
 red","helpMessage":"Specify if value quotation is required","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"statusColumn","displayName":"statusColumn","helpMessage":"Status column","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"sourcePath","displayName":"Source path","helpMessage":"Absolute path of a directory where are located CSV files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${test.csvdir.path}"]},{"schema":{"name":"fileMask","displayName":"File mask","helpMessage":"Regular expression describing files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test.csv"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="104" capability="SYNC"/>
+    
+  <ConnInstance id="105" bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
+                location="${connid.location}"
+                connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
+                version="${connid.ldap.version}" 
+                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership","helpMessage":"When enabled and a user is renamed or deleted, update any LDAP groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"The name or IP address of the host where the LDAP server is running.","type":"jav
 a.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["localhost"]},{"schema":{"name":"passwordHashAlgorithm","displayName":"Password Hash Algorithm","helpMessage":"Indicates the algorithm that the Identity system should use to hash the password. Currently supported values are SSHA, SHA, SSHA1, and SHA1. A blank value indicates that the system will not hash passwords. This will cause cleartext passwords to be stored in LDAP unless the LDAP server performs the hash (Netscape Directory Server and iPlanet Directory Server do).","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA"]},{"schema":{"name":"blockSize","displayName":"Block Size","helpMessage":"The maximum number of accounts that can be in a block when retrieving accounts in blocks.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"valu
 es":[]},{"schema":{"name":"useBlocks","displayName":"Use Blocks","helpMessage":"When performing operations on large numbers of accounts, the accounts are processed in blocks to reduce the amount of memory used by the operation. Select this option to process accounts in blocks.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"usePagedResultControl","displayName":"Use Paged Result Control","helpMessage":"When enabled, the LDAP Paged Results control is preferred over the VLV control when retrieving accounts.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"port","displayName":"TCP Port","helpMessage":"TCP/IP port number used to communicate with the LDAP server.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[1389]},{"schema":{"nam
 e":"vlvSortAttribute","displayName":"VLV Sort Attribute","helpMessage":"Specify the sort attribute to use for VLV indexes on the resource.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusManagementClass","displayName":"Status management class ","helpMessage":"Class to be used to manage enabled/disabled status. If no class is specified then identity status management wont be possible.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.ldap.commons.AttributeStatusManagement"]},{"schema":{"name":"accountObjectClasses","displayName":"Account Object Classes","helpMessage":"The object class or classes that will be used when creating new user objects in the LDAP tree. When entering more than one object class, each entry should be on its own line; do not use commas or semi-colons to s
 eparate multiple object classes. Some object classes may require that you specify all object classes in the class hierarchy.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["inetOrgPerson"]},{"schema":{"name":"accountUserNameAttributes","displayName":"Account User Name Attributes","helpMessage":"Attribute or attributes which holds the account user name. They will be used when authenticating to find the LDAP entry for the user name to authenticate.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid"]},{"schema":{"name":"baseContextsToSynchronize","displayName":"Base Contexts to Synchronize","helpMessage":"One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. The base contexts attribute will be used to synchronize a change if this property is not set.","type":"[Lja
 va.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"accountSynchronizationFilter","displayName":"LDAP Filter for Accounts to Synchronize","helpMessage":"An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"removeLogEntryObjectClassFromFilter","displayName":"Remove Log Entry Object Class from Filter","helpMessage":"If this property is set (the default), the filter used to fetch change log entries does not contain the \"changeLogEntry\" object class, expecting that there are no entri
 es of other object types in the change log.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordDecryptionKey","displayName":"Password Decryption Key","helpMessage":"The key to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"readSchema","displayName":"Read Schema","helpMessage":"If true, the connector will read the schema from the server. If false, the connector will provide a default schema based on the object classes in the configuration. This property must be true in order to use extended object classes.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"ssl","displayName":"SSL","hel
 pMessage":"Select the check box to connect to the LDAP server using SSL.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordAttributeToSynchronize","displayName":"Password Attribute to Synchronize","helpMessage":"The name of the password attribute to synchronize when performing password synchronization.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"accountSearchFilter","displayName":"LDAP Filter for Retrieving Accounts","helpMessage":"An optional LDAP filter to control which accounts are returned from the LDAP resource. If no filter is specified, only accounts that include all specified object classes are returned.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=*"]},{"schema":{"name":"passwordDec
 ryptionInitializationVector","displayName":"Password Decryption Initialization Vector","helpMessage":"The initialization vector to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupMemberAttribute","displayName":"Group Member Attribute","helpMessage":"The name of the group attribute that will be updated with the distinguished name of the user when the user is added to the group.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"failover","displayName":"Failover Servers","helpMessage":"List all servers that should be used for failover in case the preferred server fails. If the preferred server fails, JNDI will connect to the next available server in the list. List all servers in the
  form of \"ldap://ldap.example.com:389/\", which follows the standard LDAP v3 URLs described in RFC 2255. Only the host and port parts of the URL are relevant in this setting.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"modifiersNamesToFilterOut","displayName":"Filter Out Changes By","helpMessage":"The names (DNs) of directory administrators to filter from the changes. Changes with the attribute \"modifiersName\" that match entries in this list will be filtered out. The standard value is the administrator name used by this adapter, to prevent loops. Entries should be of the format \"cn=Directory Manager\".","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupNameAttributes","displayName":"Group Name Attributes","helpMessage":"Attribute or attributes which holds the group nam
 e.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"respectResourcePasswordPolicyChangeAfterReset","displayName":"Respect Resource Password Policy Change-After-Reset","helpMessage":"When this resource is specified in a Login Module (i.e., this resource is a pass-through authentication target) and the resource password policy is configured for change-after-reset, a user whose resource account password has been administratively reset will be required to change that password after successfully authenticating.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overrida
 ble":false,"values":["false"]},{"schema":{"name":"filterWithOrInsteadOfAnd","displayName":"Filter with Or Instead of And","helpMessage":"Normally the the filter used to fetch change log entries is an and-based filter retrieving an interval of change entries. If this property is set, the filter will or together the required change numbers instead.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"principal","displayName":"Principal","helpMessage":"The distinguished name with which to authenticate to the LDAP server.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=admin,ou=system"]},{"schema":{"name":"changeLogBlockSize","displayName":"Change Log Block Size","helpMessage":"The number of change log entries to fetch per query.","type":"int","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":[100]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"passwordAttribute","displayName":"Password Attribute","helpMessage":"The name of the LDAP attribute which holds the password. When changing an user password, the new password is set to this attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["userpassword"]},{"schema":{"name":"changeNumberAttribute","displayName":"Change Number Attribute","helpMessage":"The name of the change number attribute
  in the change log entry.","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["changeNumber"]},{"schema":{"name":"objectClassesToSynchronize","displayName":"Object Classes to Synchronize","helpMessage":"The object classes to synchronize. The change log is for all objects; this filters updates to just the listed object classes. You should not list the superclasses of an object class unless you intend to synchronize objects with any of the superclass values. For example, if only \"inetOrgPerson\" objects should be synchronized, but the superclasses of \"inetOrgPerson\" (\"person\", \"organizationalperson\" and \"top\") should be filtered out, then list only \"inetOrgPerson\" here. All objects in LDAP are subclassed from \"top\". For this reason, you should never list \"top\", otherwise no object would be filtered.","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":["inetOrgPerson","groupOfUniqueNames"]},{"schema":{"name":"credentials","displayName":"Password","helpMessage":"Password for the principal.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["secret"]},{"schema":{"name":"attributesToSynchronize","displayName":"Attributes to Synchronize","helpMessage":"The names of the attributes to synchronize. This ignores updates from the change log if they do not update any of the named attributes. For example, if only \"department\" is listed, then only changes that affect \"department\" will be processed. All other updates are ignored. If blank (the default), then all changes are processed.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"maintainPosixGroupMembership","displayName":"Maintain POSIX Group M
 embership","helpMessage":"When enabled and a user is renamed or deleted, update any POSIX groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["truemaintainLdapGroupMembership"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="105" capability="SEARCH"/>
+  
+  <ConnInstance id="106" displayName="H2-test2"
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                bundleName="net.tirasa.connid.bundles.db.table"
+                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
+                version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="106" capability="SYNC"/>
+  
+  <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
+                displayName="H2-testsync" version="${connid.database.version}"
+                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
+  
+  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
+                displayName="Scripted SQL" version="${connid.database.version}"
+                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is listening on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter the name of the database on the database server that contains the table.&quot;,&quot;type&
 quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a native format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access accounts table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy tab
 le could be more efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selections (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 &quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect to the Oracle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br/&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 &quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter the name of the mandatory Database user with permission to account table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot

<TRUNCATED>

[10/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
new file mode 100644
index 0000000..a39de84
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.test.context.transaction.TransactionConfiguration;
+import org.springframework.transaction.annotation.Transactional;
+
+@TransactionConfiguration(transactionManager = "TwoTransactionManager")
+@Transactional
+public class MultitenancyTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @BeforeClass
+    public static void setAuthContext() {
+        List<GrantedAuthority> authorities = CollectionUtils.collect(Entitlement.values(),
+                new Transformer<String, GrantedAuthority>() {
+
+                    @Override
+                    public GrantedAuthority transform(final String entitlement) {
+                        return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+                    }
+                }, new ArrayList<GrantedAuthority>());
+
+        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+                new org.springframework.security.core.userdetails.User(
+                        "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+        auth.setDetails(new SyncopeAuthenticationDetails("Two"));
+        SecurityContextHolder.getContext().setAuthentication(auth);
+    }
+
+    @AfterClass
+    public static void unsetAuthContext() {
+        SecurityContextHolder.getContext().setAuthentication(null);
+    }
+
+    @Test
+    public void readPlainSchemas() {
+        assertEquals(18, plainSchemaDAO.findAll().size());
+    }
+
+    @Test
+    public void readRealm() {
+        assertEquals(1, realmDAO.findAll().size());
+        assertEquals(realmDAO.getRoot(), realmDAO.findAll().get(0));
+    }
+
+    @Test
+    public void createUser() {
+        assertNull(realmDAO.getRoot().getPasswordPolicy());
+        assertTrue(userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 1000).isEmpty());
+
+        User user = entityFactory.newEntity(User.class);
+        user.setRealm(realmDAO.getRoot());
+        user.setPassword("password", CipherAlgorithm.SHA256);
+        user.setUsername("username");
+
+        User actual = userDAO.save(user);
+        assertNotNull("expected save to work", actual);
+        assertEquals(0, actual.getPasswordHistory().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
index a709638..a7e0d83 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -142,6 +142,7 @@ public class UserTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
+        user.setCreator("admin");
         user.setCreationDate(new Date());
 
         user.setPassword("pass", CipherAlgorithm.SHA256);
@@ -153,7 +154,7 @@ public class UserTest extends AbstractTest {
             assertNotNull(e);
         }
 
-        user.setPassword("password", CipherAlgorithm.SHA256);
+        user.setPassword("password123", CipherAlgorithm.SHA256);
 
         user.setUsername("username!");
 
@@ -186,6 +187,7 @@ public class UserTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
+        user.setCreator("admin");
         user.setCreationDate(new Date());
 
         user.setPassword("password123", CipherAlgorithm.AES);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
index d0f0213..c9e00bb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertNotNull;
 
 import static org.junit.Assert.assertTrue;
 
-import javax.persistence.EntityManager;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
@@ -43,9 +42,6 @@ public class AnyTypeClassTest extends AbstractTest {
     @Autowired
     private AnyTypeClassDAO anyTypeClassDAO;
 
-    @Autowired
-    private EntityManager entityManager;
-
     @Test
     public void create() {
         PlainSchema newSchema = entityFactory.newEntity(PlainSchema.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index d208106..0777854 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -63,9 +63,6 @@ import org.springframework.transaction.annotation.Transactional;
 public class GroupTest extends AbstractTest {
 
     @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
     private AnyTypeDAO anyTypeDAO;
 
     @Autowired
@@ -144,7 +141,7 @@ public class GroupTest extends AbstractTest {
      * this test class is architected.
      */
     private Collection<Group> findDynGroupMemberships(final User user) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);
@@ -226,7 +223,7 @@ public class GroupTest extends AbstractTest {
 
         groupDAO.flush();
 
-        assertNull(entityManager.find(JPAUDynGroupMembership.class, dynMembershipKey));
+        assertNull(entityManager().find(JPAUDynGroupMembership.class, dynMembershipKey));
 
         dynGroupMemberships = findDynGroupMemberships(user);
         assertTrue(dynGroupMemberships.isEmpty());
@@ -238,7 +235,7 @@ public class GroupTest extends AbstractTest {
      * this test class is architected.
      */
     private List<Group> findDynGroupMemberships(final AnyObject anyObject) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
                 + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
         query.setParameter("anyObject", anyObject);
@@ -319,7 +316,7 @@ public class GroupTest extends AbstractTest {
 
         groupDAO.flush();
 
-        assertNull(entityManager.find(JPAADynGroupMembership.class, dynMembershipKey));
+        assertNull(entityManager().find(JPAADynGroupMembership.class, dynMembershipKey));
 
         dynGroupMemberships = findDynGroupMemberships(anyObject);
         assertTrue(dynGroupMemberships.isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
index d092f3d..0e9c8db 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
@@ -57,9 +57,6 @@ import org.springframework.transaction.annotation.Transactional;
 public class ResourceTest extends AbstractTest {
 
     @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
@@ -279,7 +276,7 @@ public class ResourceTest extends AbstractTest {
         resourceDAO.flush();
 
         for (Long itemId : itemKeys) {
-            assertNull(entityManager.find(JPAMappingItem.class, itemId));
+            assertNull(entityManager().find(JPAMappingItem.class, itemId));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index 11b572c..c9c7ef2 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
@@ -51,9 +50,6 @@ import org.springframework.transaction.annotation.Transactional;
 public class RoleTest extends AbstractTest {
 
     @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
     private RoleDAO roleDAO;
 
     @Autowired
@@ -74,7 +70,7 @@ public class RoleTest extends AbstractTest {
      * this test class is architected.
      */
     private Collection<Role> findDynRoleMemberships(final User user) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Role.class);
         query.setParameter("user", user);
@@ -159,7 +155,7 @@ public class RoleTest extends AbstractTest {
 
         roleDAO.flush();
 
-        assertNull(entityManager.find(JPADynRoleMembership.class, dynMembershipKey));
+        assertNull(entityManager().find(JPADynRoleMembership.class, dynMembershipKey));
 
         dynRoleMemberships = findDynRoleMemberships(user);
         assertTrue(dynRoleMemberships.isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml b/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
index 8407b06..6b72247 100644
--- a/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
+++ b/core/persistence-jpa/src/test/resources/META-INF/persistence-enhance.xml
@@ -23,7 +23,7 @@ under the License.
                                  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
              version="2.0">
   
-  <persistence-unit name="syncopePersistenceUnit">
+  <persistence-unit name="Master">
     <mapping-file>META-INF/spring-orm.xml</mapping-file>
     <validation-mode>NONE</validation-mode>    
   </persistence-unit>


[08/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/domains/Master.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/Master.properties b/core/persistence-jpa/src/test/resources/domains/Master.properties
new file mode 100644
index 0000000..40a3852
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/Master.properties
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+Master.driverClassName=org.h2.Driver
+Master.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1
+Master.schema=
+Master.username=sa
+Master.password=
+Master.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
+Master.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Master.pool.validationQuery=SELECT 1
+
+Master.audit.sql=audit.sql


[09/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/content.xml b/core/persistence-jpa/src/test/resources/content.xml
deleted file mode 100644
index ffbd42f..0000000
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ /dev/null
@@ -1,1138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you 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.
--->
-<dataset>
-  <SyncopeConf id="1" 
-               creator="admin" lastModifier="admin"
-               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
-
-  <PlainSchema name="password.cipher.algorithm" type="String"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
-  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
-
-  <!-- notificationjob.cronExpression:
-  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
-  + provided as empty string: NotificationJob disabled
-  + provided as non-empty string: NotificationJob runs according to the given value -->
-  <PlainSchema name="notificationjob.cronExpression" type="String"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
-  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
-  
-  <PlainSchema name="notification.maxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
-  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
-
-  <PlainSchema name="token.length" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
-  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
-
-  <PlainSchema name="token.expireTime" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
-  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
-
-  <PlainSchema name="selfRegistration.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
-  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
-  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
-  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
-
-  <PlainSchema name="authentication.statuses" type="String"
-               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
-  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
-  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
-
-  <!-- Save user login date upon successful authentication -->
-  <PlainSchema name="log.lastlogindate" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
-  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
-
-  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
-  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
-
-  <!-- For usage with admin console -->
-  <PlainSchema name="admin.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  
-  <!-- sample policies -->
-  <Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC" 
-          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
-  <Policy DTYPE="PasswordPolicy" id="2" description="a password policy" type="PASSWORD" 
-          specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":true}'/>
-  <Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC" 
-          specification='{"conflictResolutionAction":"ALL","items":[{"anyTypeKey":"USER","javaRule":null,"altSearchSchemas":["username","firstname"]}]}'/>
-  <Policy DTYPE="PasswordPolicy" id="4" description="sample password policy" type="PASSWORD" 
-          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[], "allowNullPassword":true}'/>
-  <Policy DTYPE="AccountPolicy" id="5" description="an account policy" type="ACCOUNT" 
-          specification='{"maxLength":0,"minLength":0,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":0,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":[],"suffixesNotPermitted":[]}'/>
-  <Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT" 
-          specification='{"maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":3,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
-  <Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC" 
-          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
-  <Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" 
-          specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":false}'/>
-  <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
-          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
-
-  <RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
-  <RelationshipType name="neighborhood"/>
-  
-  <AnyTypeClass name="generic membership"/>
-
-  <AnyType name="USER" kind="USER"/>
-  <AnyTypeClass name="minimal user"/>
-  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="minimal user"/>
-  <AnyTypeClass name="other"/>
-  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="other"/>
-
-  <AnyType name="GROUP" kind="GROUP"/>
-  <AnyTypeClass name="minimal group"/>
-  <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
-  
-  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
-  <AnyTypeClass name="minimal printer"/>
-  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal printer"/>
-      
-  <AnyTypeClass name="csv"/>
-
-  <Realm id="1" name="/" passwordPolicy_id="4"/>
-  <Realm id="2" name="odd" parent_id="1" accountPolicy_id="6"/>
-  <Realm id="3" name="even" parent_id="1"/>
-  <Realm id="4" name="two" parent_id="3" accountPolicy_id="5" passwordPolicy_id="2"/>
-  
-  <AnyObject id="1" realm_id="1" type_name="PRINTER"
-             creator="admin" lastModifier="admin" 
-             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <AnyObject id="2" realm_id="1" type_name="PRINTER"
-             creator="admin" lastModifier="admin" 
-             creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  
-  <ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2" type_name="neighborhood"/>
-  
-  <SyncopeRole id="1" name="User reviewer"/>
-  <SyncopeRole_entitlements entitlement="USER_READ" role_id="1"/>
-  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="1"/>
-  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="1"/>
-  <SyncopeRole_Realm role_id="1" realm_id="2"/>
-  <SyncopeRole_Realm role_id="1" realm_id="3"/>
-  
-  <SyncopeRole id="2" name="User manager"/>
-  <SyncopeRole_entitlements entitlement="USER_READ" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="USER_LIST" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="2"/>
-  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_SUBMIT" role_id="2"/>
-  <SyncopeRole_Realm role_id="2" realm_id="1"/>
-
-  <SyncopeRole id="3" name="Other"/>
-  <SyncopeRole_entitlements entitlement="SCHEMA_READ" role_id="3"/>
-  <SyncopeRole_entitlements entitlement="GROUP_READ" role_id="3"/>
-  <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="3"/>
-  <SyncopeRole_Realm role_id="3" realm_id="2"/>
-  
-  <SyncopeRole id="4" name="Search for /even/two"/>
-  <SyncopeRole_entitlements entitlement="USER_READ" role_id="4"/>
-  <SyncopeRole_entitlements entitlement="USER_SEARCH" role_id="4"/>
-  <SyncopeRole_Realm role_id="4" realm_id="4"/>
-
-  <SyncopeUser id="1" workflowId="4" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="3"
-               username="rossini" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser_SyncopeRole user_id="1" role_id="3"/>
-  <SyncopeUser id="2" workflowId="6" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="verdi" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser id="3" workflowId="8" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="vivaldi" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser id="4" workflowId="10" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="bellini" creator="admin" lastModifier="admin"
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser_SyncopeRole user_id="4" role_id="1"/>
-  <SyncopeUser_SyncopeRole user_id="4" role_id="2"/>
-  <SyncopeUser id="5" workflowId="12" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1"
-               realm_id="1"
-               username="puccini" creator="admin" lastModifier="admin" 
-               creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/>
-  <SyncopeUser_SyncopeRole user_id="5" role_id="4"/>
-  
-  <SyncopeGroup id="1" name="root"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="2" name="child"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="3" name="citizen"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="4" name="employee"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="5" name="secretary"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="6" name="director" userOwner_id="5"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="7" name="managingDirector"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="8" name="otherchild"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="9" name="groupForWorkflowApproval"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="10" name="managingConsultant"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="11" name="groupForWorkflowOptIn"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup id="12" name="aGroupForPropagation"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup_AnyTypeClass group_id="12" anyTypeClass_name="csv"/>  
-  <SyncopeGroup id="13" name="bGroupForPropagation"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  <SyncopeGroup_AnyTypeClass group_id="13" anyTypeClass_name="csv"/>  
-  <SyncopeGroup id="14" name="artDirector"
-                realm_id="1"
-                creator="admin" lastModifier="admin" 
-                creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  
-  <URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
-
-  <UMembership id="1" user_id="1" group_id="1"/>
-  <UMembership id="2" user_id="2" group_id="1"/>
-  <UMembership id="3" user_id="2" group_id="2"/>
-  <UMembership id="4" user_id="4" group_id="7"/>
-  <UMembership id="5" user_id="1" group_id="8"/>
-  <UMembership id="6" user_id="2" group_id="3"/>
-  <UMembership id="7" user_id="5" group_id="14"/>
-
-  <PlainSchema name="fullname" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
-  <PlainSchema name="userId" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
-               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <PlainSchema name="loginDate" type="Date" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
-               conversionPattern="yyyy-MM-dd"/>
-  <PlainSchema name="firstname" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="surname" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="type" type="String" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="email" type="String" anyTypeClass_name="minimal user"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <PlainSchema name="activationDate" type="Date" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
-  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               enumerationValues="M;F"/>
-  <PlainSchema name="aLong" type="Long" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="makeItDouble" type="Long" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="obscure" type="Encrypted" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
-  <PlainSchema name="photo" type="Binary" anyTypeClass_name="other"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               mimeType="image/jpeg"/>
-
-  <DerSchema name="csvuserid" expression="firstname + ',' + surname" anyTypeClass_name="csv"/>
-  <DerSchema name="cn" expression="surname + ', ' + firstname" anyTypeClass_name="minimal user"/>
-  <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/>
-
-  <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/>
-  <VirSchema name="virtualReadOnly" READONLY="1"  anyTypeClass_name="minimal user"/>
-
-  <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
-  <PlainSchema name="show" type="Boolean" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="rderived_sx" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="rderived_dx" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
-  <PlainSchema name="title" type="String" anyTypeClass_name="minimal group"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-
-  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"
-             anyTypeClass_name="minimal group"/>
-  <DerSchema name="displayProperty" expression="icon + ': ' + show"
-             anyTypeClass_name="minimal group"/>
-  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"
-             anyTypeClass_name="minimal group"/>
-
-  <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/>
-
-  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"  anyTypeClass_name="minimal group"/>
-
-  <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <PlainSchema name="mderived_sx" type="String" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="mderived_dx" type="String" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
-  <PlainSchema name="postalAddress" type="String" anyTypeClass_name="generic membership"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-
-  <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
-  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx" 
-             anyTypeClass_name="generic membership"/>
-
-  <VirSchema name="mvirtualdata"/>
-        
-  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="location" type="String" anyTypeClass_name="minimal printer"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-    
-  <APlainAttr id="1" owner_id="1" schema_name="model"/>
-  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
-  <APlainAttr id="2" owner_id="1" schema_name="location"/>
-  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
-    
-  <APlainAttr id="3" owner_id="2" schema_name="model"/>
-  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
-  <APlainAttr id="4" owner_id="2" schema_name="location"/>
-  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
-
-  <UPlainAttr id="99" owner_id="1" schema_name="type"/>
-  <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
-  <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="10" attribute_id="100" schema_name="fullname" stringValue="Gioacchino Rossini"/>
-  <UPlainAttr id="101" owner_id="1" schema_name="firstname"/>
-  <UPlainAttrValue id="11" attribute_id="101" stringValue="Gioacchino"/>
-  <UPlainAttr id="102" owner_id="1" schema_name="surname"/>
-  <UPlainAttrValue id="12" attribute_id="102" stringValue="Rossini"/>
-  <UPlainAttr id="103" owner_id="1" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="13" attribute_id="103" schema_name="userId" stringValue="rossini@apache.org"/>
-  <UPlainAttr id="104" owner_id="1" schema_name="loginDate"/>
-  <UPlainAttrValue id="14" attribute_id="104" dateValue="2009-05-26"/>
-  <UPlainAttrValue id="15" attribute_id="104" dateValue="2010-05-26 15:40:04"/>
-
-  <UPlainAttr id="105" owner_id="2" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="16" attribute_id="105" schema_name="fullname" stringValue="Giuseppe Verdi"/>
-  <UPlainAttr id="106" owner_id="2" schema_name="firstname"/>
-  <UPlainAttrValue id="17" attribute_id="106" stringValue="Giuseppe"/>
-  <UPlainAttr id="107" owner_id="2" schema_name="surname"/>
-  <UPlainAttrValue id="18" attribute_id="107" stringValue="Verdi"/>
-  <UPlainAttr id="108" owner_id="2" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="19" attribute_id="108" schema_name="userId" stringValue="verdi@apache.org"/>
-
-  <UPlainAttr id="109" owner_id="3" schema_name="firstname"/>
-  <UPlainAttrValue id="20" attribute_id="109" stringValue="Antonio"/>
-  <UPlainAttr id="110" owner_id="3" schema_name="surname"/>
-  <UPlainAttrValue id="21" attribute_id="110" stringValue="Vivaldi"/>
-  <UPlainAttr id="111" owner_id="3" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="22" attribute_id="111" schema_name="fullname" stringValue="Antonio Vivaldi"/>
-  <UPlainAttr id="112" owner_id="3" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="23" attribute_id="112" schema_name="userId" stringValue="vivaldi@apache.org"/>
-
-  <UPlainAttr id="113" owner_id="4" schema_name="firstname"/>
-  <UPlainAttrValue id="24" attribute_id="113" stringValue="Vincenzo"/>
-  <UPlainAttr id="114" owner_id="4" schema_name="surname"/>
-  <UPlainAttrValue id="25" attribute_id="114" stringValue="Bellini"/>
-  <UPlainAttr id="115" owner_id="4" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="26" attribute_id="115" schema_name="fullname" stringValue="Vincenzo Bellini"/>
-  <UPlainAttr id="116" owner_id="4" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="27" attribute_id="116" schema_name="userId" stringValue="bellini@apache.org"/>
-  <UPlainAttr id="117" owner_id="4" schema_name="loginDate"/>
-  <UPlainAttrValue id="28" attribute_id="117" dateValue="2009-06-24"/>
-  <UPlainAttr id="118" owner_id="4" schema_name="cool"/>
-  <UPlainAttrValue id="29" attribute_id="118" booleanValue="1"/>
-  <UPlainAttr id="119" owner_id="4" schema_name="gender"/>
-  <UPlainAttrValue id="30" attribute_id="119" stringValue="M"/>
-  
-  <UPlainAttr id="120" owner_id="5" schema_name="firstname"/>
-  <UPlainAttrValue id="31" attribute_id="120" stringValue="Giacomo"/>
-  <UPlainAttr id="121" owner_id="5" schema_name="surname"/>
-  <UPlainAttrValue id="32" attribute_id="121" stringValue="Puccini"/>
-  <UPlainAttr id="122" owner_id="5" schema_name="fullname"/>
-  <UPlainAttrUniqueValue id="33" attribute_id="122" schema_name="fullname" stringValue="Giacomo Puccini"/>
-  <UPlainAttr id="123" owner_id="5" schema_name="userId"/>
-  <UPlainAttrUniqueValue id="34" attribute_id="123" schema_name="userId" stringValue="puccini@apache.org"/>
-  
-  <UPlainAttr id="124" owner_id="2" schema_name="email"/>
-  <UPlainAttrValue id="35" attribute_id="124" stringValue="verdi@syncope.org"/>
-  <UPlainAttr id="125" owner_id="3" schema_name="email"/>
-  <UPlainAttrValue id="36" attribute_id="125" stringValue="vivaldi@syncope.org"/>
-  <UPlainAttr id="126" owner_id="3" schema_name="type"/>
-  <UPlainAttrValue id="37" attribute_id="126" stringValue="F"/>
-    
-  <UVirAttr id="100" schema_name="virtualdata" owner_id="3"/>
-  
-  <UDerAttr id="100" schema_name="cn" owner_id="3"/>
-  <UDerAttr id="101" schema_name="cn" owner_id="1"/>
-
-  <GPlainAttr id="600" owner_id="1" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="600" id="40" stringValue="niceIcon"/>
-
-  <GPlainAttr id="700" owner_id="2" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="700" id="41" stringValue="badIcon"/>
-
-  <GPlainAttr id="800" owner_id="1"  schema_name="show"/>
-  <GPlainAttrValue attribute_id="800" id="42" booleanValue="1"/>
-
-  <GPlainAttr id="900" owner_id="6" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="900" id="43" stringValue="icon6"/>
-
-  <GPlainAttr id="950" owner_id="4" schema_name="icon"/>
-  <GPlainAttrValue attribute_id="950" id="44" stringValue="icon4"/>
-
-  <GPlainAttr id="992" owner_id="1" schema_name="rderived_sx"/>
-  <GPlainAttrValue attribute_id="992" id="92" stringValue="sx"/>
-
-  <GPlainAttr id="993" owner_id="1" schema_name="rderived_dx"/>
-  <GPlainAttrValue attribute_id="993" id="93" stringValue="dx"/>
-
-  <GPlainAttr id="994" owner_id="12" schema_name="title"/>
-  <GPlainAttrValue attribute_id="994" id="94" stringValue="r12"/>
-  
-  <GPlainAttr id="995" owner_id="13" schema_name="title"/>
-  <GPlainAttrValue attribute_id="995" id="95" stringValue="r13"/>
-
-  <GDerAttr id="100" owner_id="1" schema_name="rderiveddata"/>
-    
-  <GDerAttr id="101" owner_id="1" schema_name="displayProperty"/>
-  
-  <GDerAttr id="102" owner_id="4" schema_name="displayProperty"/>
-
-  <GDerAttr id="103" owner_id="1" schema_name="rderToBePropagated"/>    
-
-  <GVirAttr id="98" owner_id="4" schema_name="rvirtualdata"/>
-
-  <ConnInstance id="100" displayName="ConnInstance100"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.soap"
-                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
-                version="${connid.soap.version}"
-                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="100" capability="SEARCH"/>
-
-  <ConnInstance id="101" displayName="H2"
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                bundleName="net.tirasa.connid.bundles.db.table"
-                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 ":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="SEARCH"/>
-  <ConnInstance_capabilities ConnInstance_id="101" capability="SYNC"/>
-
-  <ConnInstance id="102" displayName="ConnInstance102"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.soap"
-                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
-                version="${connid.soap.version}"
-                connRequestTimeout="10"
-                jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="102" capability="SEARCH"/>
-
-  <ConnInstance id="103" displayName="ConnInstance103"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.soap"
-                connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector"
-                version="${connid.soap.version}"
-                jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/>
-
-  <ConnInstance id="104" displayName="CSVDir"
-                location="${connid.location}"
-                bundleName="net.tirasa.connid.bundles.csvdir"
-                connectorName="net.tirasa.connid.bundles.csvdir.CSVDirConnector"
-                version="${connid.csvdir.version}"
-                jsonConf='[{"schema":{"name":"fields","displayName":"fields","helpMessage":"Column names separated by comma","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id","name","surname","email","password","theirgroup","membership","status","deleted"]},{"schema":{"name":"keyColumnNames","displayName":"Key column name","helpMessage":"Name of the column used to identify user uniquely","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["name","surname"]},{"schema":{"name":"deleteColumnName","displayName":"Delete column name","helpMessage":"Name of the column used to specify users to be deleted","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["deleted"]},{"schema":{"name":"passwordColumnName","displayName":"Password column name","helpMessage":"Name
  of the column used to specify user password","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"keyseparator","displayName":"Key separator","helpMessage":"Character used to separate keys in a multi-key scenario","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"ignoreHeader","displayName":"Ignore header","helpMessage":"Specify it first line file must be ignored","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"fieldDelimiter","displayName":"fieldDelimiter","helpMessage":"fieldDelimiter","type":"char","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[","]},{"schema":{"name":"quotationRequired","displayName":"Value quotation requi
 red","helpMessage":"Specify if value quotation is required","type":"java.lang.Boolean","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"statusColumn","displayName":"statusColumn","helpMessage":"Status column","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"sourcePath","displayName":"Source path","helpMessage":"Absolute path of a directory where are located CSV files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${test.csvdir.path}"]},{"schema":{"name":"fileMask","displayName":"File mask","helpMessage":"Regular expression describing files to be processed","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test.csv"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="SEARCH"/>
-  <ConnInstance_capabilities ConnInstance_id="104" capability="SYNC"/>
-    
-  <ConnInstance id="105" bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS"
-                location="${connid.location}"
-                connectorName="net.tirasa.connid.bundles.ldap.LdapConnector"
-                version="${connid.ldap.version}" 
-                jsonConf='[{"schema":{"name":"synchronizePasswords","displayName":"Enable Password Synchronization","helpMessage":"If true, the connector will synchronize passwords. The Password Capture Plugin needs to be installed for password synchronization to work.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"maintainLdapGroupMembership","displayName":"Maintain LDAP Group Membership","helpMessage":"When enabled and a user is renamed or deleted, update any LDAP groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"The name or IP address of the host where the LDAP server is running.","type":"jav
 a.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["localhost"]},{"schema":{"name":"passwordHashAlgorithm","displayName":"Password Hash Algorithm","helpMessage":"Indicates the algorithm that the Identity system should use to hash the password. Currently supported values are SSHA, SHA, SSHA1, and SHA1. A blank value indicates that the system will not hash passwords. This will cause cleartext passwords to be stored in LDAP unless the LDAP server performs the hash (Netscape Directory Server and iPlanet Directory Server do).","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA"]},{"schema":{"name":"blockSize","displayName":"Block Size","helpMessage":"The maximum number of accounts that can be in a block when retrieving accounts in blocks.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"valu
 es":[]},{"schema":{"name":"useBlocks","displayName":"Use Blocks","helpMessage":"When performing operations on large numbers of accounts, the accounts are processed in blocks to reduce the amount of memory used by the operation. Select this option to process accounts in blocks.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[false]},{"schema":{"name":"usePagedResultControl","displayName":"Use Paged Result Control","helpMessage":"When enabled, the LDAP Paged Results control is preferred over the VLV control when retrieving accounts.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"port","displayName":"TCP Port","helpMessage":"TCP/IP port number used to communicate with the LDAP server.","type":"int","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[1389]},{"schema":{"nam
 e":"vlvSortAttribute","displayName":"VLV Sort Attribute","helpMessage":"Specify the sort attribute to use for VLV indexes on the resource.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusManagementClass","displayName":"Status management class ","helpMessage":"Class to be used to manage enabled/disabled status. If no class is specified then identity status management wont be possible.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.ldap.commons.AttributeStatusManagement"]},{"schema":{"name":"accountObjectClasses","displayName":"Account Object Classes","helpMessage":"The object class or classes that will be used when creating new user objects in the LDAP tree. When entering more than one object class, each entry should be on its own line; do not use commas or semi-colons to s
 eparate multiple object classes. Some object classes may require that you specify all object classes in the class hierarchy.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["inetOrgPerson"]},{"schema":{"name":"accountUserNameAttributes","displayName":"Account User Name Attributes","helpMessage":"Attribute or attributes which holds the account user name. They will be used when authenticating to find the LDAP entry for the user name to authenticate.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid"]},{"schema":{"name":"baseContextsToSynchronize","displayName":"Base Contexts to Synchronize","helpMessage":"One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. The base contexts attribute will be used to synchronize a change if this property is not set.","type":"[Lja
 va.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"accountSynchronizationFilter","displayName":"LDAP Filter for Accounts to Synchronize","helpMessage":"An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"removeLogEntryObjectClassFromFilter","displayName":"Remove Log Entry Object Class from Filter","helpMessage":"If this property is set (the default), the filter used to fetch change log entries does not contain the \"changeLogEntry\" object class, expecting that there are no entri
 es of other object types in the change log.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordDecryptionKey","displayName":"Password Decryption Key","helpMessage":"The key to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"readSchema","displayName":"Read Schema","helpMessage":"If true, the connector will read the schema from the server. If false, the connector will provide a default schema based on the object classes in the configuration. This property must be true in order to use extended object classes.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"ssl","displayName":"SSL","hel
 pMessage":"Select the check box to connect to the LDAP server using SSL.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordAttributeToSynchronize","displayName":"Password Attribute to Synchronize","helpMessage":"The name of the password attribute to synchronize when performing password synchronization.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"accountSearchFilter","displayName":"LDAP Filter for Retrieving Accounts","helpMessage":"An optional LDAP filter to control which accounts are returned from the LDAP resource. If no filter is specified, only accounts that include all specified object classes are returned.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=*"]},{"schema":{"name":"passwordDec
 ryptionInitializationVector","displayName":"Password Decryption Initialization Vector","helpMessage":"The initialization vector to decrypt passwords with when performing password synchronization.","type":"org.identityconnectors.common.security.GuardedByteArray","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupMemberAttribute","displayName":"Group Member Attribute","helpMessage":"The name of the group attribute that will be updated with the distinguished name of the user when the user is added to the group.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"failover","displayName":"Failover Servers","helpMessage":"List all servers that should be used for failover in case the preferred server fails. If the preferred server fails, JNDI will connect to the next available server in the list. List all servers in the
  form of \"ldap://ldap.example.com:389/\", which follows the standard LDAP v3 URLs described in RFC 2255. Only the host and port parts of the URL are relevant in this setting.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"modifiersNamesToFilterOut","displayName":"Filter Out Changes By","helpMessage":"The names (DNs) of directory administrators to filter from the changes. Changes with the attribute \"modifiersName\" that match entries in this list will be filtered out. The standard value is the administrator name used by this adapter, to prevent loops. Entries should be of the format \"cn=Directory Manager\".","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"groupNameAttributes","displayName":"Group Name Attributes","helpMessage":"Attribute or attributes which holds the group nam
 e.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["cn"]},{"schema":{"name":"respectResourcePasswordPolicyChangeAfterReset","displayName":"Respect Resource Password Policy Change-After-Reset","helpMessage":"When this resource is specified in a Login Module (i.e., this resource is a pass-through authentication target) and the resource password policy is configured for change-after-reset, a user whose resource account password has been administratively reset will be required to change that password after successfully authenticating.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overrida
 ble":false,"values":["false"]},{"schema":{"name":"filterWithOrInsteadOfAnd","displayName":"Filter with Or Instead of And","helpMessage":"Normally the the filter used to fetch change log entries is an and-based filter retrieving an interval of change entries. If this property is set, the filter will or together the required change numbers instead.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"principal","displayName":"Principal","helpMessage":"The distinguished name with which to authenticate to the LDAP server.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["uid=admin,ou=system"]},{"schema":{"name":"changeLogBlockSize","displayName":"Change Log Block Size","helpMessage":"The number of change log entries to fetch per query.","type":"int","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":[100]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["ou=people,o=isp","ou=groups,o=isp"]},{"schema":{"name":"passwordAttribute","displayName":"Password Attribute","helpMessage":"The name of the LDAP attribute which holds the password. When changing an user password, the new password is set to this attribute.","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["userpassword"]},{"schema":{"name":"changeNumberAttribute","displayName":"Change Number Attribute","helpMessage":"The name of the change number attribute
  in the change log entry.","type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["changeNumber"]},{"schema":{"name":"objectClassesToSynchronize","displayName":"Object Classes to Synchronize","helpMessage":"The object classes to synchronize. The change log is for all objects; this filters updates to just the listed object classes. You should not list the superclasses of an object class unless you intend to synchronize objects with any of the superclass values. For example, if only \"inetOrgPerson\" objects should be synchronized, but the superclasses of \"inetOrgPerson\" (\"person\", \"organizationalperson\" and \"top\") should be filtered out, then list only \"inetOrgPerson\" here. All objects in LDAP are subclassed from \"top\". For this reason, you should never list \"top\", otherwise no object would be filtered.","type":"[Ljava.lang.String;","required":true,"order":0,"confidential":false,"defaultValues":null},
 "overridable":false,"values":["inetOrgPerson","groupOfUniqueNames"]},{"schema":{"name":"credentials","displayName":"Password","helpMessage":"Password for the principal.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["secret"]},{"schema":{"name":"attributesToSynchronize","displayName":"Attributes to Synchronize","helpMessage":"The names of the attributes to synchronize. This ignores updates from the change log if they do not update any of the named attributes. For example, if only \"department\" is listed, then only changes that affect \"department\" will be processed. All other updates are ignored. If blank (the default), then all changes are processed.","type":"[Ljava.lang.String;","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"maintainPosixGroupMembership","displayName":"Maintain POSIX Group M
 embership","helpMessage":"When enabled and a user is renamed or deleted, update any POSIX groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.","type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["truemaintainLdapGroupMembership"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="105" capability="SEARCH"/>
-  
-  <ConnInstance id="106" displayName="H2-test2"
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                bundleName="net.tirasa.connid.bundles.db.table"
-                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="SEARCH"/>
-  <ConnInstance_capabilities ConnInstance_id="106" capability="SYNC"/>
-  
-  <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
-                displayName="H2-testsync" version="${connid.database.version}"
-                jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_CREATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_UPDATE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_DELETE"/>
-  <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
-  
-  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
-                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
-                connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
-                displayName="Scripted SQL" version="${connid.database.version}"
-                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is listening on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter the name of the database on the database server that contains the table.&quot;,&quot;type&
 quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a native format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access accounts table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy tab
 le could be more efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selections (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 &quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect to the Oracle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br/&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 &quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter the name of the mandatory Database user with permission to account table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SearchScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;searchScript&quot;,&q

<TRUNCATED>

[06/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/domains/Two.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/Two.properties b/core/persistence-jpa/src/test/resources/domains/Two.properties
new file mode 100644
index 0000000..b37a969
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/Two.properties
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+Two.driverClassName=org.h2.Driver
+Two.url=jdbc:h2:file:${project.build.directory}/test-classes/syncopetwo.db;DB_CLOSE_DELAY=-1
+Two.schema=
+Two.username=sa
+Two.password=
+Two.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
+Two.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Two.pool.validationQuery=SELECT 1
+
+Two.audit.sql=audit.sql

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoContent.xml b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
new file mode 100644
index 0000000..92216fd
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/TwoContent.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<dataset>
+  <Realm id="1" name="/"/>
+
+  <SyncopeConf id="1" 
+               creator="admin" lastModifier="admin"
+               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
+
+  <PlainSchema name="password.cipher.algorithm" type="String"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
+  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
+
+  <!-- notificationjob.cronExpression:
+  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
+  + provided as empty string: NotificationJob disabled
+  + provided as non-empty string: NotificationJob runs according to the given value -->
+  <PlainSchema name="notificationjob.cronExpression" type="String"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
+  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
+
+  <PlainSchema name="notification.maxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
+  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
+
+  <PlainSchema name="token.length" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
+  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
+
+  <PlainSchema name="token.expireTime" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
+  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
+
+  <PlainSchema name="selfRegistration.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
+  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.allowed" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
+  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
+  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
+
+  <PlainSchema name="authentication.statuses" type="String"
+               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
+  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
+  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
+
+  <!-- Save user login date upon successful authentication -->
+  <PlainSchema name="log.lastlogindate" type="Boolean"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
+  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
+
+  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
+               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
+  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
+
+  <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="BaseUser"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="BaseUser"/>
+
+  <AnyType name="GROUP" kind="GROUP"/>
+  
+  <!-- For usage with admin console -->
+  <PlainSchema name="admin.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.user.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.group.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="admin.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="self.membership.layout" type="String"
+               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+        
+  <PlainSchema name="email" type="String" anyTypeClass_name="BaseUser"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+  
+  <!-- Password reset notifications -->
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/>
+  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES"/> 
+  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
+
+</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
new file mode 100644
index 0000000..c7e7a9b
--- /dev/null
+++ b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd                           
+                           http://www.springframework.org/schema/tx
+                           http://www.springframework.org/schema/tx/spring-tx.xsd
+                           http://www.springframework.org/schema/util
+                           http://www.springframework.org/schema/util/spring-util.xsd">
+  
+  <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
+    <property name="fallback" value="classpath:domains/TwoContent.xml"/>
+  </bean>
+  <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${content.directory}/domains/Two.properties"/>
+    <property name="fallback" value="classpath:domains/Two.properties"/>
+  </bean>
+  <bean id="TwoDatabaseSchema" class="java.lang.String">
+    <constructor-arg value="${Two.schema}"/>
+  </bean>
+
+  <!-- Use JNDI datasource as default but, when not available, revert to
+  local datasource, with different properties for execution and testing. 
+  In any case, get all JDBC connections with a determined isolation level. -->
+  <bean id="TwoDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+    <property name="jndiName" value="java:comp/env/jdbc/syncopeTwoDataSource"/>
+    <property name="defaultObject" ref="localTwoDataSource"/>
+  </bean>
+
+  <bean id="localTwoDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
+    <property name="driverClassName" value="${Two.driverClassName}"/>
+    <property name="url" value="${Two.url}"/>
+    <property name="username" value="${Two.username}"/>
+    <property name="password" value="${Two.password}"/>
+    <!-- connection pool configuration - transaction isolation, default READ_COMMITTED (see SYNCOPE-202) -->
+    <property name="defaultTransactionIsolation">
+      <util:constant static-field="${Two.pool.defaultTransactionIsolation:java.sql.Connection.TRANSACTION_READ_COMMITTED}"/>
+    </property>
+    <!-- connection pool configuration - default values taken from BasicDataSource default values -->
+    <property name="initialSize" value="${Two.pool.initialSize:0}"/>
+    <property name="maxTotal" value="${Two.pool.maxActive:8}"/>
+    <property name="maxIdle" value="${Two.pool.maxIdle:8}"/>
+    <property name="minIdle" value="${Two.pool.minIdle:0}"/>
+    <property name="maxWaitMillis" value="${Two.pool.maxWait:-1}"/>
+    <!--<property name="validationQuery" value="${Two.pool.validationQuery}"/>-->
+    <property name="validationQueryTimeout" value="${Two.pool.validationQueryTimeout:-1}"/>
+    <property name="testOnBorrow" value="${Two.pool.testOnBorrow:true}"/>
+    <property name="testOnReturn" value="${Two.pool.testOnReturn:false}"/>
+    <property name="testWhileIdle" value="${Two.pool.testWhileIdle:false}"/>
+    <property name="timeBetweenEvictionRunsMillis" value="${Two.pool.timeBetweenEvictionRunsMillis:-1}"/>
+    <property name="numTestsPerEvictionRun" value="${Two.pool.numTestsPerEvictionRun:3}"/>
+    <property name="minEvictableIdleTimeMillis" value="${Two.pool.minEvictableIdleTimeMillis:1800000}"/>
+    <property name="removeAbandonedOnBorrow" value="${Two.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedOnMaintenance" value="${Two.pool.removeAbandoned:false}"/>
+    <property name="removeAbandonedTimeout" value="${Two.pool.removeAbandonedTimeout:300}"/>
+    <property name="logAbandoned" value="${Two.pool.logAbandoned:false}"/>
+  </bean>
+  
+  <bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
+    <property name="dataSource" ref="TwoDataSource"/>
+    <property name="enabled" value="true"/>
+    <property name="databasePopulator">
+      <bean class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
+        <property name="continueOnError" value="true"/>
+        <property name="ignoreFailedDrops" value="true"/>
+        <property name="sqlScriptEncoding" value="UTF-8"/>
+        <property name="scripts">
+          <array>
+            <value type="org.springframework.core.io.Resource">
+              classpath:/audit/${Two.audit.sql}
+            </value>
+          </array>
+        </property>
+      </bean>
+    </property>
+  </bean>
+  
+  <bean id="TwoEntityManagerFactory"
+        class="org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean">
+    <property name="mappingResources">
+      <list>
+        <value>${Two.orm}</value>
+      </list>
+    </property>
+    <property name="persistenceUnitName" value="Two"/>
+    <property name="dataSource" ref="TwoDataSource"/>
+    <property name="jpaVendorAdapter">
+      <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+        <property name="showSql" value="false"/>
+        <property name="generateDdl" value="true"/>
+        <property name="databasePlatform" value="${Two.databasePlatform}"/>
+      </bean>
+    </property>
+    <property name="commonEntityManagerFactoryConf" ref="commonEMFConf"/>
+  </bean>  
+
+  <bean id="TwoTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+    <property name="entityManagerFactory" ref="TwoEntityManagerFactory"/>
+    <qualifier value="Two"/>
+  </bean>
+  
+  <tx:annotation-driven transaction-manager="TwoTransactionManager"/>
+
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistence.properties b/core/persistence-jpa/src/test/resources/persistence.properties
deleted file mode 100644
index 31ea1b0..0000000
--- a/core/persistence-jpa/src/test/resources/persistence.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-content.directory=${conf.directory}
-jpa.driverClassName=org.h2.Driver
-jpa.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1
-jpa.username=sa
-jpa.password=
-jpa.dialect=org.apache.openjpa.jdbc.sql.H2Dictionary
-jpa.pool.validationQuery=SELECT 1
-jpa.orm=META-INF/spring-orm.xml
-# note: other connection pool settings can also be configured here, see persistenceContext.xml
-quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-quartz.scheduler.idleWaitTime=5000
-quartz.sql=tables_h2.sql
-audit.sql=audit.sql
-database.schema=
-

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/test/resources/persistenceTest.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistenceTest.xml b/core/persistence-jpa/src/test/resources/persistenceTest.xml
index a87172b..da8f321 100644
--- a/core/persistence-jpa/src/test/resources/persistenceTest.xml
+++ b/core/persistence-jpa/src/test/resources/persistenceTest.xml
@@ -29,6 +29,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
       </list>
     </property>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
index 6928ffd..5645979 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java
@@ -18,8 +18,13 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
+import java.util.List;
 import org.apache.syncope.common.lib.mod.AnyObjectMod;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
 
 public interface AnyObjectProvisioningManager extends ProvisioningManager<AnyObjectTO, AnyObjectMod> {
+
+    List<PropagationStatus> provision(Long key, Collection<String> resources);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
index 1dce013..c74b5df 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -31,4 +32,6 @@ public interface GroupProvisioningManager extends ProvisioningManager<GroupTO, G
     Pair<Long, List<PropagationStatus>> create(
             GroupTO groupTO, Map<Long, String> groupOwnerMap, Set<String> excludedResources);
 
+    List<PropagationStatus> provision(Long key, Collection<String> resources);
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index 810a788..3378707 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
@@ -30,11 +31,11 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserMod> {
 
-    Pair<Long, List<PropagationStatus>> activate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> activate(StatusMod statusMod);
 
-    Pair<Long, List<PropagationStatus>> reactivate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> reactivate(StatusMod statusMod);
 
-    Pair<Long, List<PropagationStatus>> suspend(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> suspend(StatusMod statusMod);
 
     void innerSuspend(User user, boolean propagate);
 
@@ -48,6 +49,8 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use
 
     void requestPasswordReset(Long key);
 
-    void confirmPasswordReset(User user, String token, String password);
+    void confirmPasswordReset(Long key, String token, String password);
+
+    List<PropagationStatus> provision(Long key, boolean changePwd, String password, Collection<String> resources);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
index 7434976..14f0c83 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobInstanceLoader.java
@@ -19,20 +19,20 @@
 package org.apache.syncope.core.provisioning.api.job;
 
 import java.text.ParseException;
+import java.util.Map;
 import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.quartz.SchedulerException;
 
 public interface JobInstanceLoader {
 
-    void registerJob(Task task, String jobClassName, String cronExpression)
-            throws ClassNotFoundException, SchedulerException, ParseException;
+    String DOMAIN = "domain";
 
-    void registerJob(Report report) throws SchedulerException, ParseException;
+    Map<String, Object> registerJob(final SchedTask task, final long interruptMaxRetries)
+            throws SchedulerException, ParseException;
 
-    void registerReportJob(Long reportKey) throws SchedulerException, ParseException;
-
-    void registerTaskJob(Long taskKey) throws ClassNotFoundException, SchedulerException, ParseException;
+    void registerJob(final Report report) throws SchedulerException, ParseException;
 
     void unregisterJob(Task task);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
index 9ddf563..22d7b54 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java
@@ -29,7 +29,7 @@ public final class JobNamer {
 
     private static final Logger LOG = LoggerFactory.getLogger(JobNamer.class);
 
-    private static Long getIdFromJobName(final String name, final String pattern, final int prefixLength) {
+    private static Long getKeyFromJobName(final String name, final String pattern, final int prefixLength) {
         Long result = null;
 
         Matcher jobMatcher = Pattern.compile(pattern).matcher(name);
@@ -45,17 +45,15 @@ public final class JobNamer {
     }
 
     public static Long getTaskKeyFromJobName(final String name) {
-        return getIdFromJobName(name, "taskJob[0-9]+", 7);
+        return getKeyFromJobName(name, "taskJob[0-9]+", 7);
     }
 
     public static Long getReportKeyFromJobName(final String name) {
-        return getIdFromJobName(name, "reportJob[0-9]+", 9);
+        return getKeyFromJobName(name, "reportJob[0-9]+", 9);
     }
 
     public static String getJobName(final Task task) {
-        return task == null
-                ? "taskNotificationJob"
-                : "taskJob" + task.getKey();
+        return "taskJob" + task.getKey();
     }
 
     public static String getJobName(final Report report) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
deleted file mode 100644
index 9a6386f..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/ProvisioningJob.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.api.job;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
-
-public interface ProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions> extends TaskJob {
-
-    void setActions(List<A> actions);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
deleted file mode 100644
index 388d780..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/PushJob.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.api.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-
-public interface PushJob extends ProvisioningJob<PushTask, PushActions> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
new file mode 100644
index 0000000..74e9247
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.api.job;
+
+import org.quartz.JobExecutionException;
+
+public interface SchedTaskJobDelegate {
+
+    void execute(Long taskKey, boolean dryRun) throws JobExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
deleted file mode 100644
index 147daa5..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SyncJob.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.api.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-
-public interface SyncJob extends ProvisioningJob<SyncTask, SyncActions> {
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
deleted file mode 100644
index 3df89bc..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/TaskJob.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.api.job;
-
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.InterruptableJob;
-
-/**
- * Interface for Quartz jobs bound to a given Task.
- */
-@DisallowConcurrentExecution
-public interface TaskJob extends InterruptableJob {
-
-    String DRY_RUN_JOBDETAIL_KEY = "dryRun";
-
-    /**
-     * Task execution status.
-     */
-    public enum Status {
-
-        SUCCESS,
-        FAILURE
-
-    }
-
-    void setTaskId(Long taskId);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
index cf8cde4..3155223 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
@@ -27,7 +27,6 @@ import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 
@@ -149,12 +148,12 @@ public interface PropagationManager {
     /**
      * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
      *
-     * @param user to be propagated
+     * @param key to be propagated
      * @param enable whether user must be enabled or not
      * @param noPropResourceNames external resource names not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserUpdateTasks(User user, Boolean enable, Collection<String> noPropResourceNames);
+    List<PropagationTask> getUserUpdateTasks(Long key, Boolean enable, Collection<String> noPropResourceNames);
 
     /**
      * Performs update on each resource associated to the user.

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index a1dc161..85ea59f 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -150,6 +150,13 @@ under the License.
         <filtering>true</filtering>
       </testResource>
       <testResource>
+        <directory>${basedir}/../persistence-jpa/src/main/resources</directory>
+        <includes>
+          <include>persistence.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </testResource>
+      <testResource>
         <directory>${basedir}/../persistence-jpa/src/test/resources</directory>
         <filtering>true</filtering>
       </testResource>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index e23143a..bcea03d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -95,7 +95,7 @@ public class ConnectorFacadeProxy implements Connector {
         this.activeConnInstance = connInstance;
 
         ConnIdBundleManager connIdBundleManager =
-                ApplicationContextProvider.getApplicationContext().getBean(ConnIdBundleManager.class);
+                ApplicationContextProvider.getBeanFactory().getBean(ConnIdBundleManager.class);
         ConnectorInfo info = connIdBundleManager.getConnectorInfo(connInstance);
 
         // create default configuration

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 7d0cf2f..38b3f2a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -25,13 +25,13 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.identityconnectors.common.l10n.CurrentLocale;
 import org.identityconnectors.framework.api.ConnectorFacadeFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index fd6bcf1..9722adb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
@@ -81,7 +82,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
         List<PropagationTask> tasks = propagationManager.getAnyObjectCreateTasks(
                 created, anyObjectTO.getVirAttrs(), excludedResources);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -118,7 +119,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -130,20 +131,20 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyObjectKey) {
-        return delete(anyObjectKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         List<PropagationTask> tasks = new ArrayList<>();
 
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        AnyObject anyObject = anyObjectDAO.authFind(key);
         if (anyObject != null) {
             tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey()));
         }
 
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -152,7 +153,7 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        awfAdapter.delete(anyObjectKey);
+        awfAdapter.delete(key);
 
         return propagationReporter.getStatuses();
     }
@@ -168,15 +169,36 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PropagationByResource propByRes = new PropagationByResource();
+        for (String resource : resources) {
+            propByRes.add(ResourceOperation.UPDATE, resource);
+        }
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        AnyObject anyObject = anyObjectDAO.authFind(key);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(anyObject.getResourceNames(), resources);
 
         List<PropagationTask> tasks = propagationManager.getAnyObjectDeleteTasks(
-                anyObjectKey, new HashSet<>(resources), noPropResourceName);
+                key, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index 5661df4..457f74d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -38,6 +38,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -81,8 +82,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(
-                PropagationReporter.class);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -98,6 +99,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             final GroupTO groupTO, final Map<Long, String> groupOwnerMap, final Set<String> excludedResources) {
 
         WorkflowResult<Long> created = gwfAdapter.create(groupTO);
+
+        // see ConnObjectUtils#getAnyTOFromConnObject for GroupOwnerSchema
         AttrTO groupOwner = groupTO.getPlainAttrMap().get(StringUtils.EMPTY);
         if (groupOwner != null) {
             groupOwnerMap.put(created.getResult(), groupOwner.getValues().iterator().next());
@@ -105,15 +108,21 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
-
-        taskExecutor.execute(tasks);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
 
         return new ImmutablePair<>(created.getResult(), null);
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupObjectMod) {
-        return update(groupObjectMod, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupMod) {
+        return update(groupMod, Collections.<String>emptySet());
     }
 
     @Override
@@ -137,7 +146,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -149,15 +158,15 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long groupObjectKey) {
-        return delete(groupObjectKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long groupKey, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         List<PropagationTask> tasks = new ArrayList<>();
 
-        Group group = groupDAO.authFind(groupKey);
+        Group group = groupDAO.authFind(key);
         if (group != null) {
             // Generate propagation tasks for deleting users from group resources, if they are on those resources only
             // because of the reason being deleted (see SYNCOPE-357)
@@ -180,7 +189,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             tasks.addAll(propagationManager.getGroupDeleteTasks(group.getKey()));
         }
 
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -189,7 +198,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        gwfAdapter.delete(groupKey);
+        gwfAdapter.delete(key);
 
         return propagationReporter.getStatuses();
     }
@@ -201,15 +210,34 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long groupKey, final Collection<String> resources) {
-        Group group = groupDAO.authFind(groupKey);
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        Group group = groupDAO.authFind(key);
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(group.getResourceNames(), resources);
 
         List<PropagationTask> tasks = propagationManager.getGroupDeleteTasks(
-                groupKey, new HashSet<>(resources), noPropResourceName);
+                key, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 656bc75..0809607 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -37,6 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
@@ -87,12 +88,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) {
 
-        WorkflowResult<Pair<Long, Boolean>> created;
-        try {
-            created = uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
-        } catch (PropagationException e) {
-            throw e;
-        }
+        WorkflowResult<Pair<Long, Boolean>> created =
+                uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
 
         List<PropagationTask> tasks = propagationManager.getUserCreateTasks(
                 created.getResult().getKey(),
@@ -102,7 +99,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 userTO.getVirAttrs(),
                 excludedResources);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -129,7 +126,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());
         }
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         if (!tasks.isEmpty()) {
             try {
@@ -140,9 +137,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             }
         }
 
-        Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>(
-                updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
-        return result;
+        return new ImmutablePair<>(updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
     }
 
     @Override
@@ -191,7 +186,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
                 updated, updated.getResult().getKey().getPassword() != null, excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+        PropagationReporter propagationReporter = ApplicationContextProvider.getBeanFactory().
                 getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
@@ -204,21 +199,21 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long userKey) {
-        return delete(userKey, Collections.<String>emptySet());
+    public List<PropagationStatus> delete(final Long key) {
+        return delete(key, Collections.<String>emptySet());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyId, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long key, final Set<String> excludedResources) {
         // Note here that we can only notify about "delete", not any other
         // task defined in workflow process definition: this because this
         // information could only be available after uwfAdapter.delete(), which
         // will also effectively remove user from db, thus making virtually
         // impossible by NotificationManager to fetch required user information
-        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(anyId, excludedResources);
+        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(key, excludedResources);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -227,7 +222,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         }
 
         try {
-            uwfAdapter.delete(anyId);
+            uwfAdapter.delete(key);
         } catch (PropagationException e) {
             throw e;
         }
@@ -247,40 +242,40 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> activate(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.activate(user.getKey(), statusMod.getToken())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.activate(statusMod.getKey(), statusMod.getToken())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> reactivate(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.reactivate(user.getKey())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.reactivate(statusMod.getKey())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> suspend(final StatusMod statusMod) {
         WorkflowResult<Long> updated = statusMod.isOnSyncope()
-                ? uwfAdapter.suspend(user.getKey())
-                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                ? uwfAdapter.suspend(statusMod.getKey())
+                : new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(statusMod));
     }
 
-    protected List<PropagationStatus> propagateStatus(final User user, final StatusMod statusMod) {
-        Collection<String> noPropResourceNames =
-                CollectionUtils.removeAll(userDAO.findAllResourceNames(user), statusMod.getResourceNames());
+    protected List<PropagationStatus> propagateStatus(final StatusMod statusMod) {
+        Collection<String> noPropResourceNames = CollectionUtils.removeAll(
+                userDAO.findAllResourceNames(userDAO.find(statusMod.getKey())), statusMod.getResourceNames());
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                user, statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
+                statusMod.getKey(), statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {
@@ -311,15 +306,50 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> deprovision(final Long userKey, final Collection<String> resources) {
-        final User user = userDAO.authFind(userKey);
+    public List<PropagationStatus> provision(
+            final Long key, final boolean changePwd, final String password, final Collection<String> resources) {
+
+        UserMod userMod = new UserMod();
+        userMod.setKey(key);
+        userMod.getResourcesToAdd().addAll(resources);
+
+        if (changePwd) {
+            StatusMod statusMod = new StatusMod();
+            statusMod.setOnSyncope(false);
+            statusMod.getResourceNames().addAll(resources);
+            userMod.setPwdPropRequest(statusMod);
+            userMod.setPassword(password);
+        }
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Pair<UserMod, Boolean>> wfResult = new WorkflowResult<Pair<UserMod, Boolean>>(
+                ImmutablePair.of(userMod, (Boolean) null), propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(wfResult, changePwd, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
+        User user = userDAO.authFind(key);
 
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(
-                userKey,
+                key,
                 new HashSet<>(resources),
                 CollectionUtils.removeAll(userDAO.findAllResourceNames(user), resources));
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {
@@ -331,16 +361,16 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public void requestPasswordReset(final Long id) {
-        uwfAdapter.requestPasswordReset(id);
+    public void requestPasswordReset(final Long key) {
+        uwfAdapter.requestPasswordReset(key);
     }
 
     @Override
-    public void confirmPasswordReset(final User user, final String token, final String password) {
-        uwfAdapter.confirmPasswordReset(user.getKey(), token, password);
+    public void confirmPasswordReset(final Long key, final String token, final String password) {
+        uwfAdapter.confirmPasswordReset(key, token, password);
 
         UserMod userMod = new UserMod();
-        userMod.setKey(user.getKey());
+        userMod.setKey(key);
         userMod.setPassword(password);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
@@ -348,7 +378,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                         new ImmutablePair<UserMod, Boolean>(userMod, null), null, "confirmPasswordReset"),
                 true, null);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
index bec5e28..7ff9e84 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/UserSuspenderImpl.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 92a9bd3..689037b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -345,8 +345,8 @@ abstract class AbstractAnyDataBinder {
         Set<ExternalResource> resources = getAllResources(any);
 
         // 5. attributes to be removed
-        for (String attributeToBeRemoved : anyMod.getPlainAttrsToRemove()) {
-            PlainSchema schema = getPlainSchema(attributeToBeRemoved);
+        for (String attrToRemove : anyMod.getPlainAttrsToRemove()) {
+            PlainSchema schema = getPlainSchema(attrToRemove);
             if (schema != null) {
                 PlainAttr<?> attr = any.getPlainAttr(schema.getKey());
                 if (attr == null) {
@@ -388,8 +388,8 @@ abstract class AbstractAnyDataBinder {
         LOG.debug("Attributes to be removed:\n{}", propByRes);
 
         // 6. attributes to be updated
-        for (AttrMod attributeMod : anyMod.getPlainAttrsToUpdate()) {
-            PlainSchema schema = getPlainSchema(attributeMod.getSchema());
+        for (AttrMod attrMod : anyMod.getPlainAttrsToUpdate()) {
+            PlainSchema schema = getPlainSchema(attrMod.getSchema());
             PlainAttr attr = null;
             if (schema != null) {
                 attr = any.getPlainAttr(schema.getKey());
@@ -407,7 +407,7 @@ abstract class AbstractAnyDataBinder {
 
                 // 1.1 remove values
                 Set<Long> valuesToBeRemoved = new HashSet<>();
-                for (String valueToBeRemoved : attributeMod.getValuesToBeRemoved()) {
+                for (String valueToBeRemoved : attrMod.getValuesToBeRemoved()) {
                     if (attr.getSchema().isUniqueConstraint()) {
                         if (attr.getUniqueValue() != null
                                 && valueToBeRemoved.equals(attr.getUniqueValue().getValueAsString())) {
@@ -422,17 +422,17 @@ abstract class AbstractAnyDataBinder {
                         }
                     }
                 }
-                for (Long attributeValueId : valuesToBeRemoved) {
-                    plainAttrValueDAO.delete(attributeValueId, anyUtils.plainAttrValueClass());
+                for (Long attrValueKey : valuesToBeRemoved) {
+                    plainAttrValueDAO.delete(attrValueKey, anyUtils.plainAttrValueClass());
                 }
 
                 // 1.2 add values
-                List<String> valuesToBeAdded = attributeMod.getValuesToBeAdded();
+                List<String> valuesToBeAdded = attrMod.getValuesToBeAdded();
                 if (valuesToBeAdded != null && !valuesToBeAdded.isEmpty()
                         && (!schema.isUniqueConstraint() || attr.getUniqueValue() == null
                         || !valuesToBeAdded.iterator().next().equals(attr.getUniqueValue().getValueAsString()))) {
 
-                    fillAttribute(attributeMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
+                    fillAttribute(attrMod.getValuesToBeAdded(), anyUtils, schema, attr, invalidValues);
                 }
 
                 // if no values are in, the attribute can be safely removed

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 258e713..08c7e1d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
-
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index 3cf65fd..fe135b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
-
 import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder;
 import java.util.Collections;
 import java.util.List;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index 762cca5..2295753 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -61,6 +61,8 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.Trigger;
@@ -147,6 +149,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
             final PushTask pushTask = (PushTask) task;
             final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
 
+            pushTask.setJobDelegateClassName(PushJobDelegate.class.getName());
+
             pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
                     ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
             pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
@@ -181,6 +185,8 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             syncTask.setDestinationRealm(realmDAO.find(syncTaskTO.getDestinationRealm()));
 
+            syncTask.setJobDelegateClassName(SyncJobDelegate.class.getName());
+
             syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
                     ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
             syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
@@ -239,7 +245,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         task.setDescription(taskTO.getDescription());
 
         if (taskUtils.getType() == TaskType.SCHEDULED) {
-            task.setJobClassName(taskTO.getJobClassName());
+            task.setJobDelegateClassName(taskTO.getJobDelegateClassName());
         } else if (taskTO instanceof AbstractProvisioningTaskTO) {
             AbstractProvisioningTaskTO provisioningTaskTO = (AbstractProvisioningTaskTO) taskTO;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
new file mode 100644
index 0000000..3042239
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.java.job;
+
+import java.util.Date;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+public abstract class AbstractSchedTaskJobDelegate implements SchedTaskJobDelegate {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(SchedTaskJobDelegate.class);
+
+    /**
+     * The actual task to be executed.
+     */
+    protected Task task;
+
+    /**
+     * Task execution DAO.
+     */
+    @Autowired
+    protected TaskExecDAO taskExecDAO;
+
+    /**
+     * Task DAO.
+     */
+    @Autowired
+    protected TaskDAO taskDAO;
+
+    @Autowired
+    protected EntityFactory entityFactory;
+
+    /**
+     * Notification manager.
+     */
+    @Autowired
+    protected NotificationManager notificationManager;
+
+    /**
+     * Audit manager.
+     */
+    @Autowired
+    protected AuditManager auditManager;
+
+    @Transactional
+    @Override
+    public void execute(final Long taskKey, final boolean dryRun) throws JobExecutionException {
+        task = taskDAO.find(taskKey);
+        if (task == null) {
+            throw new JobExecutionException("Task " + taskKey + " not found");
+        }
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setStartDate(new Date());
+        execution.setTask(task);
+
+        AuditElements.Result result;
+
+        try {
+            execution.setMessage(doExecute(dryRun));
+            execution.setStatus(TaskJob.Status.SUCCESS.name());
+            result = AuditElements.Result.SUCCESS;
+        } catch (JobExecutionException e) {
+            LOG.error("While executing task " + taskKey, e);
+            result = AuditElements.Result.FAILURE;
+
+            execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
+            execution.setStatus(TaskJob.Status.FAILURE.name());
+        }
+        execution.setEndDate(new Date());
+
+        if (hasToBeRegistered(execution)) {
+            taskExecDAO.saveAndAdd(taskKey, execution);
+        }
+        task = taskDAO.save(task);
+
+        notificationManager.createTasks(
+                AuditElements.EventCategoryType.TASK,
+                this.getClass().getSimpleName(),
+                null,
+                this.getClass().getSimpleName(), // searching for before object is too much expensive ...
+                result,
+                task,
+                execution);
+
+        auditManager.audit(
+                AuditElements.EventCategoryType.TASK,
+                task.getClass().getSimpleName(),
+                null,
+                null, // searching for before object is too much expensive ...
+                result,
+                task,
+                (Object[]) null);
+    }
+
+    /**
+     * The actual execution, delegated to child classes.
+     *
+     * @param dryRun whether to actually touch the data
+     * @return the task execution status to be set
+     * @throws JobExecutionException if anything goes wrong
+     */
+    protected abstract String doExecute(boolean dryRun) throws JobExecutionException;
+
+    /**
+     * Template method to determine whether this job's task execution has to be persisted or not.
+     *
+     * @param execution task execution
+     * @return wether to persist or not
+     */
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        return false;
+    }
+
+}


[12/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
index 793411d..6de5ffb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
@@ -32,12 +32,13 @@ import org.springframework.transaction.annotation.Transactional;
 @Repository
 public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO {
 
-    @Override
     @Transactional(readOnly = true)
+    @Override
     public Report find(final Long key) {
-        return entityManager.find(JPAReport.class, key);
+        return entityManager().find(JPAReport.class, key);
     }
 
+    @Transactional(readOnly = true)
     @Override
     public List<Report> findAll() {
         return findAll(-1, -1, Collections.<OrderByClause>emptyList());
@@ -45,7 +46,7 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
 
     @Override
     public List<Report> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
-        final TypedQuery<Report> query = entityManager.createQuery(
+        final TypedQuery<Report> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReport.class.getSimpleName() + " e "
                 + toOrderByStatement(Report.class, "e", orderByClauses), Report.class);
 
@@ -62,14 +63,14 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
 
     @Override
     public int count() {
-        Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
+        Query countQuery = entityManager().createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
         return ((Number) countQuery.getSingleResult()).intValue();
     }
 
     @Override
     @Transactional(rollbackFor = Throwable.class)
     public Report save(final Report report) {
-        return entityManager.merge(report);
+        return entityManager().merge(report);
     }
 
     @Override
@@ -84,6 +85,6 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
 
     @Override
     public void delete(final Report report) {
-        entityManager.remove(report);
+        entityManager().remove(report);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
index 95f57df..cf9e781 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
@@ -32,11 +32,11 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
 
     @Override
     public ReportExec find(final Long key) {
-        return entityManager.find(JPAReportExec.class, key);
+        return entityManager().find(JPAReportExec.class, key);
     }
 
     private ReportExec findLatest(final Report report, final String field) {
-        TypedQuery<ReportExec> query = entityManager.createQuery(
+        TypedQuery<ReportExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e "
                 + "WHERE e.report=:report ORDER BY e." + field + " DESC", ReportExec.class);
         query.setParameter("report", report);
@@ -60,7 +60,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
 
     @Override
     public List<ReportExec> findAll() {
-        TypedQuery<ReportExec> query = entityManager.createQuery(
+        TypedQuery<ReportExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e", ReportExec.class);
         return query.getResultList();
     }
@@ -75,7 +75,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
     @Override
     @Transactional(rollbackFor = Throwable.class)
     public ReportExec save(final ReportExec execution) {
-        return entityManager.merge(execution);
+        return entityManager().merge(execution);
     }
 
     @Override
@@ -94,6 +94,6 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
             execution.getReport().removeExec(execution);
         }
 
-        entityManager.remove(execution);
+        entityManager().remove(execution);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 5f600b6..6fb5ec3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -43,12 +43,12 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public Role find(final Long key) {
-        return entityManager.find(JPARole.class, key);
+        return entityManager().find(JPARole.class, key);
     }
 
     @Override
     public Role find(final String name) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.name=:name", Role.class);
         query.setParameter("name", name);
 
@@ -64,7 +64,7 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public List<Role> findByRealm(final Realm realm) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE :realm MEMBER OF e.realms", Role.class);
         query.setParameter("realm", realm);
         return query.getResultList();
@@ -72,7 +72,7 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
 
     @Override
     public List<Role> findAll() {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e FROM " + JPARole.class.getSimpleName() + " e ", Role.class);
         return query.getResultList();
     }
@@ -90,12 +90,12 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
             }
         }
 
-        return entityManager.merge(role);
+        return entityManager().merge(role);
     }
 
     @Override
     public void delete(final Role role) {
-        entityManager.remove(role);
+        entityManager().remove(role);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
index 5c242d6..7028080 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
@@ -36,19 +36,19 @@ public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long>
 
     @Override
     public SecurityQuestion find(final Long key) {
-        return entityManager.find(JPASecurityQuestion.class, key);
+        return entityManager().find(JPASecurityQuestion.class, key);
     }
 
     @Override
     public List<SecurityQuestion> findAll() {
-        final TypedQuery<SecurityQuestion> query = entityManager.createQuery(
+        final TypedQuery<SecurityQuestion> query = entityManager().createQuery(
                 "SELECT e FROM " + JPASecurityQuestion.class.getSimpleName() + " e ", SecurityQuestion.class);
         return query.getResultList();
     }
 
     @Override
     public SecurityQuestion save(final SecurityQuestion securityQuestion) {
-        return entityManager.merge(securityQuestion);
+        return entityManager().merge(securityQuestion);
     }
 
     @Override
@@ -64,7 +64,7 @@ public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long>
             userDAO.save(user);
         }
 
-        entityManager.remove(securityQuestion);
+        entityManager().remove(securityQuestion);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index ff93071..a70f65e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -75,7 +75,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     @SuppressWarnings("unchecked")
     @Override
     public <T extends Task> T find(final Long key) {
-        return (T) entityManager.find(JPATask.class, key);
+        return (T) entityManager().find(JPATask.class, key);
     }
 
     private <T extends Task> StringBuilder buildfindAllQuery(final TaskType type) {
@@ -96,7 +96,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
         }
         queryString.append("ORDER BY e.id DESC");
 
-        Query query = entityManager.createQuery(queryString.toString());
+        Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("type", type);
         return query.getResultList();
     }
@@ -106,13 +106,14 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     public <T extends Task> List<T> findAll(final ExternalResource resource, final TaskType type) {
         StringBuilder queryString = buildfindAllQuery(type).append("AND e.resource=:resource ORDER BY e.id DESC");
 
-        final Query query = entityManager.createQuery(queryString.toString());
+        final Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("type", type);
         query.setParameter("resource", resource);
 
         return query.getResultList();
     }
 
+    @Transactional(readOnly = true)
     @Override
     public <T extends Task> List<T> findAll(final TaskType type) {
         return findAll(-1, -1, Collections.<OrderByClause>emptyList(), type);
@@ -128,7 +129,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
                 ? "ORDER BY e.id DESC"
                 : toOrderByStatement(getEntityReference(type), "e", orderByClauses));
 
-        Query query = entityManager.createQuery(queryString.toString());
+        Query query = entityManager().createQuery(queryString.toString());
         query.setParameter("type", type);
 
         query.setFirstResult(itemsPerPage * (page <= 0
@@ -144,7 +145,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
 
     @Override
     public int count(final TaskType type) {
-        Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
+        Query countQuery = entityManager().createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
         countQuery.setParameter(1, type.name());
         return ((Number) countQuery.getSingleResult()).intValue();
     }
@@ -152,7 +153,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public <T extends Task> T save(final T task) {
-        return entityManager.merge(task);
+        return entityManager().merge(task);
     }
 
     @Override
@@ -167,7 +168,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
 
     @Override
     public void delete(final Task task) {
-        entityManager.remove(task);
+        entityManager().remove(task);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
index 5d840da..38155ff 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
@@ -38,11 +38,11 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
 
     @Override
     public TaskExec find(final Long key) {
-        return entityManager.find(JPATaskExec.class, key);
+        return entityManager().find(JPATaskExec.class, key);
     }
 
     private <T extends Task> TaskExec findLatest(final T task, final String field) {
-        TypedQuery<TaskExec> query = entityManager.createQuery(
+        TypedQuery<TaskExec> query = entityManager().createQuery(
                 "SELECT e FROM " + JPATaskExec.class.getSimpleName() + " e "
                 + "WHERE e.task=:task "
                 + "ORDER BY e." + field + " DESC", TaskExec.class);
@@ -71,13 +71,13 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
                 append(" e WHERE e.task IN (").append("SELECT t FROM ").
                 append(taskDAO.getEntityReference(type).getSimpleName()).append(" t)");
 
-        TypedQuery<TaskExec> query = entityManager.createQuery(queryString.toString(), TaskExec.class);
+        TypedQuery<TaskExec> query = entityManager().createQuery(queryString.toString(), TaskExec.class);
         return query.getResultList();
     }
 
     @Override
     public TaskExec save(final TaskExec execution) {
-        return entityManager.merge(execution);
+        return entityManager().merge(execution);
     }
 
     /**
@@ -111,6 +111,6 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
             execution.getTask().removeExec(execution);
         }
 
-        entityManager.remove(execution);
+        entityManager().remove(execution);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 3b413c0..50564f2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -29,8 +29,17 @@ import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.core.misc.policy.AccountPolicyEnforcer;
+import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.misc.policy.PasswordPolicyEnforcer;
+import org.apache.syncope.core.misc.policy.PolicyEvaluator;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -40,14 +49,21 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.Policy;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
+import org.apache.syncope.core.provisioning.api.UserSuspender;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
@@ -57,14 +73,32 @@ import org.springframework.transaction.annotation.Transactional;
 public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
     private GroupDAO groupDAO;
 
     @Autowired
     private RoleDAO roleDAO;
 
+    @Resource(name = "adminUser")
+    private String adminUser;
+
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
+    @Autowired
+    private PolicyEvaluator evaluator;
+
+    @Autowired
+    private PasswordPolicyEnforcer ppEnforcer;
+
+    @Autowired
+    private AccountPolicyEnforcer apEnforcer;
+
+    @Autowired(required = false)
+    private UserSuspender suspender;
+
     @Override
     protected AnyUtils init() {
         return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.USER);
@@ -110,7 +144,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public User find(final String username) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+        TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
                 + " e WHERE e.username = :username", User.class);
         query.setParameter("username", username);
 
@@ -126,7 +160,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public User findByToken(final String token) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+        TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
                 + " e WHERE e.token LIKE :token", User.class);
         query.setParameter("token", token);
 
@@ -142,16 +176,151 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public List<User> findBySecurityQuestion(final SecurityQuestion securityQuestion) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+        TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
                 + " e WHERE e.securityQuestion = :securityQuestion", User.class);
         query.setParameter("securityQuestion", securityQuestion);
 
         return query.getResultList();
     }
 
+    private List<PasswordPolicy> getPasswordPolicies(final User user) {
+        List<PasswordPolicy> policies = new ArrayList<>();
+
+        PasswordPolicy policy;
+
+        // add resource policies
+        for (ExternalResource resource : findAllResources(user)) {
+            policy = resource.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add realm policies
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            policy = realm.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+
+    private List<AccountPolicy> getAccountPolicies(final User user) {
+        List<AccountPolicy> policies = new ArrayList<>();
+
+        AccountPolicy policy;
+
+        // add resource policies        
+        for (ExternalResource resource : findAllResources(user)) {
+            policy = resource.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add realm policies
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            policy = realm.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+
+    private Pair<Boolean, Boolean> enforcePolicies(final User user) {
+        // ------------------------------
+        // Verify password policies
+        // ------------------------------
+        LOG.debug("Password Policy enforcement");
+
+        try {
+            int maxPPSpecHistory = 0;
+            for (Policy policy : getPasswordPolicies(user)) {
+                // evaluate policy
+                PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
+                // enforce policy
+                ppEnforcer.enforce(ppSpec, policy.getType(), user);
+
+                if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
+                    maxPPSpecHistory = ppSpec.getHistoryLength();
+                }
+            }
+
+            // update user's password history with encrypted password
+            if (maxPPSpecHistory > 0 && user.getPassword() != null) {
+                user.getPasswordHistory().add(user.getPassword());
+            }
+            // keep only the last maxPPSpecHistory items in user's password history
+            if (maxPPSpecHistory < user.getPasswordHistory().size()) {
+                for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
+                    user.getPasswordHistory().remove(i);
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Invalid password for {}", user, e);
+            throw new InvalidEntityException(User.class, EntityViolationType.InvalidPassword, e.getMessage());
+        } finally {
+            // password has been validated, let's remove its clear version
+            user.removeClearPassword();
+        }
+
+        // ------------------------------
+        // Verify account policies
+        // ------------------------------
+        LOG.debug("Account Policy enforcement");
+
+        boolean suspend = false;
+        boolean propagateSuspension = false;
+        try {
+            if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
+                throw new AccountPolicyException("Not allowed: " + user.getUsername());
+            }
+
+            // invalid username
+            for (Policy policy : getAccountPolicies(user)) {
+                // evaluate policy
+                AccountPolicySpec apSpec = evaluator.evaluate(policy, user);
+
+                // enforce policy
+                suspend |= apEnforcer.enforce(apSpec, policy.getType(), user);
+                propagateSuspension |= apSpec.isPropagateSuspension();
+            }
+        } catch (Exception e) {
+            LOG.error("Invalid username for {}", user, e);
+            throw new InvalidEntityException(User.class, EntityViolationType.InvalidUsername, e.getMessage());
+        }
+
+        return ImmutablePair.of(suspend, propagateSuspension);
+    }
+
     @Override
     public User save(final User user) {
+        // 1. save clear password value before save
+        String clearPwd = user.getClearPassword();
+
+        // 2. save and flush to trigger entity validation        
         User merged = super.save(user);
+        entityManager().flush();
+
+        // 3. set back the sole clear password value
+        JPAUser.class.cast(merged).setClearPassword(clearPwd);
+
+        // 4. enforce password and account policies
+        Pair<Boolean, Boolean> enforceSuspend = null;
+        try {
+            enforceSuspend = enforcePolicies(merged);
+        } catch (InvalidEntityException e) {
+            entityManager().remove(merged);
+            throw e;
+        }
+
+        if (suspender != null && enforceSuspend.getKey()) {
+            suspender.suspend(user, enforceSuspend.getValue());
+        }
 
         roleDAO.refreshDynMemberships(merged);
         groupDAO.refreshDynMemberships(merged);
@@ -168,13 +337,13 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
             group.getUDynMembership().remove(user);
         }
 
-        entityManager.remove(user);
+        entityManager().remove(user);
     }
 
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Role> findDynRoleMemberships(final User user) {
-        TypedQuery<Role> query = entityManager.createQuery(
+        TypedQuery<Role> query = entityManager().createQuery(
                 "SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Role.class);
         query.setParameter("user", user);
@@ -185,7 +354,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Group> findDynGroupMemberships(final User user) {
-        TypedQuery<Group> query = entityManager.createQuery(
+        TypedQuery<Group> query = entityManager().createQuery(
                 "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
index 3ef6791..2c8b99f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
@@ -49,19 +49,19 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirA
 
     @Override
     public <T extends VirAttr<?>> T find(final Long key, final Class<T> reference) {
-        return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+        return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
     }
 
     @Override
     public <T extends VirAttr<?>> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
+        TypedQuery<T> query = entityManager().createQuery(
                 "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
     public <T extends VirAttr<?>> T save(final T virAttr) {
-        return entityManager.merge(virAttr);
+        return entityManager().merge(virAttr);
     }
 
     @Override
@@ -81,6 +81,6 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirA
             ((Any<?, ?, T>) virAttr.getOwner()).remove(virAttr);
         }
 
-        entityManager.remove(virAttr);
+        entityManager().remove(virAttr);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
index dae6afc..46a06f6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public VirSchema find(final String key) {
-        return entityManager.find(JPAVirSchema.class, key);
+        return entityManager().find(JPAVirSchema.class, key);
     }
 
     @Override
@@ -54,7 +54,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
                 append(JPAVirSchema.class.getSimpleName()).
                 append(" e WHERE e.anyTypeClass=:anyTypeClass");
 
-        TypedQuery<VirSchema> query = entityManager.createQuery(queryString.toString(), VirSchema.class);
+        TypedQuery<VirSchema> query = entityManager().createQuery(queryString.toString(), VirSchema.class);
         query.setParameter("anyTypeClass", anyTypeClass);
 
         return query.getResultList();
@@ -62,7 +62,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public List<VirSchema> findAll() {
-        TypedQuery<VirSchema> query = entityManager.createQuery(
+        TypedQuery<VirSchema> query = entityManager().createQuery(
                 "SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", VirSchema.class);
         return query.getResultList();
     }
@@ -73,7 +73,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
                 append(((JPAVirAttrDAO) virAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
-        TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+        TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
 
         return query.getResultList();
@@ -81,7 +81,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
 
     @Override
     public VirSchema save(final VirSchema virSchema) {
-        return entityManager.merge(virSchema);
+        return entityManager().merge(virSchema);
     }
 
     @Override
@@ -106,6 +106,6 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
             schema.getAnyTypeClass().remove(schema);
         }
 
-        entityManager.remove(schema);
+        entityManager().remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index 06bebdb..2913dc6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -125,7 +125,7 @@ public class JPAGroup extends AbstractAny<GPlainAttr, GDerAttr, GVirAttr> implem
 
     @Override
     public AnyType getType() {
-        return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findGroup();
+        return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findGroup();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 9723f1d..463408e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -80,15 +80,15 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
     @Enumerated(EnumType.STRING)
     protected MatchingRule matchingRule;
 
-    public AbstractProvisioningTask(final TaskType type, final String jobClassName) {
+    public AbstractProvisioningTask(final TaskType type, final String jobDelegateClassName) {
         super();
 
         this.type = type;
-        super.setJobClassName(jobClassName);
+        super.setJobDelegateClassName(jobDelegateClassName);
     }
 
     @Override
-    public void setJobClassName(final String jobClassName) {
+    public void setJobDelegateClassName(final String jobClassName) {
         // fixed to SyncJob, cannot be changed
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
index 0592a9d..190cc0f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
@@ -37,7 +37,6 @@ import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
 
 @Entity
 @DiscriminatorValue("PushTask")
@@ -59,7 +58,7 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
      * Default constructor.
      */
     public JPAPushTask() {
-        super(TaskType.PUSH, PushJob.class.getName());
+        super(TaskType.PUSH, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
index 5703380..4f650ba 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
@@ -34,8 +34,7 @@ public class JPASchedTask extends JPATask implements SchedTask {
 
     protected String cronExpression;
 
-    @NotNull
-    protected String jobClassName;
+    protected String jobDelegateClassName;
 
     @NotNull
     protected String name;
@@ -58,13 +57,13 @@ public class JPASchedTask extends JPATask implements SchedTask {
     }
 
     @Override
-    public String getJobClassName() {
-        return jobClassName;
+    public String getJobDelegateClassName() {
+        return jobDelegateClassName;
     }
 
     @Override
-    public void setJobClassName(final String jobClassName) {
-        this.jobClassName = jobClassName;
+    public void setJobDelegateClassName(final String jobDelegateClassName) {
+        this.jobDelegateClassName = jobDelegateClassName;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index 41eb4ea..f2da581 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -40,7 +40,6 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
@@ -73,7 +72,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
      * Default constructor.
      */
     public JPASyncTask() {
-        super(TaskType.SYNCHRONIZATION, SyncJob.class.getName());
+        super(TaskType.SYNCHRONIZATION, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index 88c86fb..1f153da 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -55,7 +55,6 @@ import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.validation.entity.UserCheck;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.jpa.entity.JPASecurityQuestion;
 import org.apache.syncope.core.misc.security.Encryptor;
@@ -75,7 +74,6 @@ import org.apache.syncope.core.persistence.jpa.entity.JPARole;
 @Entity
 @Table(name = JPAUser.TABLE)
 @Cacheable
-@UserCheck
 public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> implements User {
 
     private static final long serialVersionUID = -3905046855521446823L;
@@ -212,7 +210,7 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
 
     @Override
     public AnyType getType() {
-        return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findUser();
+        return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findUser();
     }
 
     @Override
@@ -252,9 +250,13 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
         return clearPassword;
     }
 
+    public void setClearPassword(final String clearPassword) {
+        this.clearPassword = clearPassword;
+    }
+
     @Override
     public void removeClearPassword() {
-        clearPassword = null;
+        setClearPassword(null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
new file mode 100644
index 0000000..3e44864
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.persistence.jpa.spring;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.ValidationMode;
+import javax.sql.DataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
+
+/**
+ * Container for common configuration options among all EntityManagerFactory entities (one for each domain).
+ * <br/>
+ * Acts as a commodity place for fetching each domain's {@link DataSource}..
+ */
+public class CommonEntityManagerFactoryConf implements DomainsHolder, InitializingBean, ApplicationContextAware {
+
+    private ApplicationContext ctx;
+
+    private final Map<String, DataSource> domains = new HashMap<>();
+
+    private String[] packagesToScan;
+
+    private ValidationMode validationMode;
+
+    private PersistenceUnitPostProcessor[] postProcessors;
+
+    private final Map<String, Object> jpaPropertyMap = new HashMap<>();
+
+    @Override
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = ctx;
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        for (Map.Entry<String, DataSource> entry : ctx.getBeansOfType(DataSource.class).entrySet()) {
+            if (!entry.getKey().startsWith("local")) {
+                this.domains.put(
+                        StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName()),
+                        entry.getValue());
+            }
+        }
+    }
+
+    @Override
+    public Map<String, DataSource> getDomains() {
+        return domains;
+    }
+
+    public String[] getPackagesToScan() {
+        return packagesToScan;
+    }
+
+    public void setPackagesToScan(final String... packagesToScan) {
+        this.packagesToScan = packagesToScan;
+    }
+
+    public ValidationMode getValidationMode() {
+        return validationMode;
+    }
+
+    public void setValidationMode(final ValidationMode validationMode) {
+        this.validationMode = validationMode;
+    }
+
+    public PersistenceUnitPostProcessor[] getPersistenceUnitPostProcessors() {
+        return postProcessors;
+    }
+
+    public void setPersistenceUnitPostProcessors(final PersistenceUnitPostProcessor... postProcessors) {
+        this.postProcessors = postProcessors;
+    }
+
+    public Map<String, ?> getJpaPropertyMap() {
+        return jpaPropertyMap;
+    }
+
+    public void setJpaPropertyMap(final Map<String, ?> jpaProperties) {
+        if (jpaProperties != null) {
+            this.jpaPropertyMap.putAll(jpaProperties);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
new file mode 100644
index 0000000..a959f96
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.persistence.jpa.spring;
+
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+
+/**
+ * Extension of {@link LocalContainerEntityManagerFactoryBean} relying on {@link CommonEntityManagerFactoryConf} for
+ * common configuration options.
+ */
+public class DomainEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {
+
+    private static final long serialVersionUID = 49152547930966545L;
+
+    public void setCommonEntityManagerFactoryConf(final CommonEntityManagerFactoryConf commonEMFConf) {
+        super.setJpaPropertyMap(commonEMFConf.getJpaPropertyMap());
+
+        if (commonEMFConf.getPackagesToScan() != null) {
+            super.setPackagesToScan(commonEMFConf.getPackagesToScan());
+        }
+
+        super.setValidationMode(commonEMFConf.getValidationMode());
+
+        if (commonEMFConf.getPersistenceUnitPostProcessors() != null) {
+            super.setPersistenceUnitPostProcessors(commonEMFConf.getPersistenceUnitPostProcessors());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
new file mode 100644
index 0000000..42779ed
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.persistence.jpa.spring;
+
+import java.lang.reflect.Method;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
+ * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
+ * {@link AuthContextUtils#getDomain()}.
+ */
+public class DomainTransactionInterceptor extends TransactionInterceptor {
+
+    private static final long serialVersionUID = 5113728988680448551L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(DomainTransactionInterceptor.class);
+
+    @Override
+    public TransactionAttributeSource getTransactionAttributeSource() {
+        final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
+
+        return new TransactionAttributeSource() {
+
+            @Override
+            public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
+                TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
+
+                if (txAttr instanceof DefaultTransactionAttribute) {
+                    ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
+                }
+
+                return txAttr;
+            }
+        };
+    }
+
+    @Override
+    public Object invoke(final MethodInvocation invocation) throws Throwable {
+        try {
+            return super.invoke(invocation);
+        } catch (Throwable e) {
+            LOG.debug("Error during {} invocation", invocation.getMethod(), e);
+            throw e;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
new file mode 100644
index 0000000..e983426
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.persistence.jpa.spring;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Hack for dynamically replacing standard {@link TransactionInterceptor} with
+ * {@link DomainTransactionInterceptor} in Spring context.
+ */
+@Component
+public class SpringComponentReplacer implements BeanFactoryPostProcessor {
+
+    @Override
+    public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException {
+        for (String name : factory.getBeanNamesForType(TransactionInterceptor.class)) {
+            BeanDefinition bd = factory.getBeanDefinition(name);
+            bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
index b7616c7..f1df70c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -49,7 +49,7 @@ public class EntityValidationListener {
     @PrePersist
     @PreUpdate
     public void validate(final Object object) {
-        final Validator validator = ApplicationContextProvider.getApplicationContext().getBean(Validator.class);
+        final Validator validator = ApplicationContextProvider.getBeanFactory().getBean(Validator.class);
         Set<ConstraintViolation<Object>> violations = validator.validate(object);
         if (!violations.isEmpty()) {
             LOG.warn("Bean validation errors found: {}", violations);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
index 2b6e4e0..3c64499 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -37,11 +37,11 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
     }
 
     @Override
-    public boolean isValid(final ProvisioningTask object, final ConstraintValidatorContext context) {
-        boolean isValid = schedV.isValid(object, context);
+    public boolean isValid(final ProvisioningTask task, final ConstraintValidatorContext context) {
+        boolean isValid = schedV.isValid(task, context);
 
         if (isValid) {
-            isValid = object.getResource() != null;
+            isValid = task.getResource() != null;
             if (!isValid) {
                 LOG.error("Resource is null");
 
@@ -51,15 +51,15 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
                         addPropertyNode("resource").addConstraintViolation();
             }
 
-            if (!object.getActionsClassNames().isEmpty()) {
-                for (String className : object.getActionsClassNames()) {
+            if (!task.getActionsClassNames().isEmpty()) {
+                for (String className : task.getActionsClassNames()) {
                     Class<?> actionsClass = null;
                     boolean isAssignable = false;
                     try {
                         actionsClass = Class.forName(className);
-                        isAssignable = object instanceof JPASyncTask
+                        isAssignable = task instanceof JPASyncTask
                                 ? SyncActions.class.isAssignableFrom(actionsClass)
-                                : object instanceof JPAPushTask
+                                : task instanceof JPAPushTask
                                         ? PushActions.class.isAssignableFrom(actionsClass)
                                         : false;
                     } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
index 50a6d5d..5c159c2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
@@ -21,39 +21,43 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
 import java.text.ParseException;
 
 import javax.validation.ConstraintValidatorContext;
+import org.apache.commons.lang3.ClassUtils;
 import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
 import org.quartz.CronExpression;
-import org.quartz.Job;
 
 public class SchedTaskValidator extends AbstractValidator<SchedTaskCheck, SchedTask> {
 
     @Override
-    public boolean isValid(final SchedTask object, final ConstraintValidatorContext context) {
-        boolean isValid;
+    public boolean isValid(final SchedTask task, final ConstraintValidatorContext context) {
+        boolean isValid = true;
 
-        Class<?> jobClass = null;
-        try {
-            jobClass = Class.forName(object.getJobClassName());
-            isValid = Job.class.isAssignableFrom(jobClass);
-        } catch (Exception e) {
-            LOG.error("Invalid Job class specified", e);
-            isValid = false;
-        }
-        if (jobClass == null || !isValid) {
-            isValid = false;
+        if (!(task instanceof ProvisioningTask)) {
+            Class<?> jobDelegateClass = null;
+            try {
+                jobDelegateClass = ClassUtils.getClass(task.getJobDelegateClassName());
+                isValid = SchedTaskJobDelegate.class.isAssignableFrom(jobDelegateClass);
+            } catch (Exception e) {
+                LOG.error("Invalid JobDelegate class specified", e);
+                isValid = false;
+            }
+            if (jobDelegateClass == null || !isValid) {
+                isValid = false;
 
-            context.disableDefaultConstraintViolation();
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job class name")).
-                    addPropertyNode("jobClassName").addConstraintViolation();
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job delegate class name")).
+                        addPropertyNode("jobDelegateClassName").addConstraintViolation();
+            }
         }
 
-        if (isValid && object.getCronExpression() != null) {
+        if (isValid && task.getCronExpression() != null) {
             try {
-                new CronExpression(object.getCronExpression());
+                new CronExpression(task.getCronExpression());
             } catch (ParseException e) {
-                LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+                LOG.error("Invalid cron expression '" + task.getCronExpression() + "'", e);
                 isValid = false;
 
                 context.disableDefaultConstraintViolation();

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
deleted file mode 100644
index 2d9fec6..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.persistence.jpa.validation.entity;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.validation.Constraint;
-import javax.validation.Payload;
-
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-@Constraint(validatedBy = UserValidator.class)
-@Documented
-public @interface UserCheck {
-
-    String message() default "{org.apache.syncope.core.persistence.validation.user}";
-
-    Class<?>[] groups() default {};
-
-    Class<? extends Payload>[] payload() default {};
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
deleted file mode 100644
index e142de3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.persistence.jpa.validation.entity;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.Resource;
-import javax.validation.ConstraintValidatorContext;
-import org.apache.syncope.common.lib.types.AccountPolicySpec;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.PasswordPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.policy.AccountPolicyEnforcer;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
-import org.apache.syncope.core.misc.policy.PasswordPolicyEnforcer;
-import org.apache.syncope.core.misc.policy.PolicyEvaluator;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class UserValidator extends AbstractValidator<UserCheck, User> {
-
-    @Resource(name = "adminUser")
-    private String adminUser;
-
-    @Resource(name = "anonymousUser")
-    private String anonymousUser;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private PolicyEvaluator evaluator;
-
-    @Autowired
-    private PasswordPolicyEnforcer ppEnforcer;
-
-    @Autowired
-    private AccountPolicyEnforcer apEnforcer;
-
-    @Override
-    public boolean isValid(final User user, final ConstraintValidatorContext context) {
-        context.disableDefaultConstraintViolation();
-
-        // need to treat it explicitly, otherwise policy evaluation will silently fail
-        if (user.getRealm() == null) {
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidRealm, "realm not specified")).
-                    addPropertyNode("realm").addConstraintViolation();
-
-            return false;
-        }
-
-        // ------------------------------
-        // Verify password policies
-        // ------------------------------
-        LOG.debug("Password Policy enforcement");
-
-        try {
-            int maxPPSpecHistory = 0;
-            for (Policy policy : getPasswordPolicies(user)) {
-                // evaluate policy
-                PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
-                // enforce policy
-                ppEnforcer.enforce(ppSpec, policy.getType(), user);
-
-                if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
-                    maxPPSpecHistory = ppSpec.getHistoryLength();
-                }
-            }
-
-            // update user's password history with encrypted password
-            if (maxPPSpecHistory > 0 && user.getPassword() != null) {
-                user.getPasswordHistory().add(user.getPassword());
-            }
-            // keep only the last maxPPSpecHistory items in user's password history
-            if (maxPPSpecHistory < user.getPasswordHistory().size()) {
-                for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
-                    user.getPasswordHistory().remove(i);
-                }
-            }
-        } catch (Exception e) {
-            LOG.debug("Invalid password");
-
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidPassword, e.getMessage())).
-                    addPropertyNode("password").addConstraintViolation();
-
-            return false;
-        } finally {
-            // password has been validated, let's remove its clear version
-            user.removeClearPassword();
-        }
-        // ------------------------------
-
-        // ------------------------------
-        // Verify account policies
-        // ------------------------------
-        LOG.debug("Account Policy enforcement");
-
-        try {
-            if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
-                throw new AccountPolicyException("Not allowed: " + user.getUsername());
-            }
-
-            // invalid username
-            for (Policy policy : getAccountPolicies(user)) {
-                // evaluate policy
-                AccountPolicySpec accountPolicy = evaluator.evaluate(policy, user);
-
-                // enforce policy
-                apEnforcer.enforce(accountPolicy, policy.getType(), user);
-            }
-        } catch (Exception e) {
-            LOG.debug("Invalid username");
-
-            context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidUsername, e.getMessage())).
-                    addPropertyNode("username").addConstraintViolation();
-
-            return false;
-        }
-        // ------------------------------
-
-        return true;
-    }
-
-    private List<PasswordPolicy> getPasswordPolicies(final User user) {
-        List<PasswordPolicy> policies = new ArrayList<>();
-
-        PasswordPolicy policy;
-
-        // add resource policies
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            policy = resource.getPasswordPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        // add realm policies
-        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            policy = realm.getPasswordPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        return policies;
-    }
-
-    private List<AccountPolicy> getAccountPolicies(final User user) {
-        List<AccountPolicy> policies = new ArrayList<>();
-
-        AccountPolicy policy;
-
-        // add resource policies
-        for (ExternalResource resource : userDAO.findAllResources(user)) {
-            policy = resource.getAccountPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        // add realm policies
-        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
-            policy = realm.getAccountPolicy();
-            if (policy != null) {
-                policies.add(policy);
-            }
-        }
-
-        return policies;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/audit/audit.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/audit/audit.sql b/core/persistence-jpa/src/main/resources/audit/audit.sql
index faf8c5b..44ffb17 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit.sql
+++ b/core/persistence-jpa/src/main/resources/audit/audit.sql
@@ -21,4 +21,6 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
   LOGGER VARCHAR(255) NOT NULL,
   MESSAGE TEXT NOT NULL,
   THROWABLE TEXT
-)
+);
+
+COMMIT;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/content.xml b/core/persistence-jpa/src/main/resources/content.xml
deleted file mode 100644
index caba10e..0000000
--- a/core/persistence-jpa/src/main/resources/content.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you 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.
--->
-<dataset>
-  <Realm id="1" name="/"/>
-
-  <SyncopeConf id="1" 
-               creator="admin" lastModifier="admin"
-               creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
-
-  <PlainSchema name="password.cipher.algorithm" type="String"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
-  <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
-
-  <!-- notificationjob.cronExpression:
-  + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
-  + provided as empty string: NotificationJob disabled
-  + provided as non-empty string: NotificationJob runs according to the given value -->
-  <PlainSchema name="notificationjob.cronExpression" type="String"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
-  <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
-
-  <PlainSchema name="notification.maxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
-  <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
-
-  <PlainSchema name="token.length" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
-  <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
-
-  <PlainSchema name="token.expireTime" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
-  <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
-
-  <PlainSchema name="selfRegistration.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
-  <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.allowed" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
-  <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
-
-  <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
-  <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
-
-  <PlainSchema name="authentication.statuses" type="String"
-               mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
-  <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
-  <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
-
-  <!-- Save user login date upon successful authentication -->
-  <PlainSchema name="log.lastlogindate" type="Boolean"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
-  <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
-
-  <PlainSchema name="tasks.interruptMaxRetries" type="Long"
-               mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
-  <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
-
-  <!-- For usage with admin console -->
-  <PlainSchema name="admin.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.user.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.group.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="admin.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="self.membership.layout" type="String"
-               mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-        
-  <PlainSchema name="email" type="String"
-               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-               validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  
-  <!-- Password reset notifications -->
-  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
-                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
-                traceLevel="FAILURES" userAbout="token!=$null"/> 
-  <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
-  
-  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
-                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
-                traceLevel="FAILURES" userAbout="token!=$null"/> 
-  <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
-
-</dataset>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/domains.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains.xml b/core/persistence-jpa/src/main/resources/domains.xml
new file mode 100644
index 0000000..43fce14
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd">
+  
+  <import resource="classpath*:domains/*Domain.xml"/>
+    
+  <bean id="commonEMFConf" class="org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf">
+    <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
+    <property name="validationMode" value="NONE"/>
+    <property name="persistenceUnitPostProcessors">
+      <list>
+        <bean class="org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor"/>
+      </list>
+    </property>
+    <property name="jpaPropertyMap">
+      <map>
+        <entry key="openjpa.Log" value="slf4j"/>
+        <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
+        <entry key="openjpa.ConnectionFactoryProperties" 
+        value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
+                                
+        <entry key="openjpa.NontransactionalWrite" value="false"/>
+        <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
+
+        <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
+        <entry key="openjpa.jdbc.MappingDefaults" 
+               value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
+                
+        <entry key="openjpa.DataCache" value="true"/>
+        <entry key="openjpa.QueryCache" value="true"/>
+        <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
+      </map>
+    </property>    
+  </bean>
+  
+</beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/persistence-jpa/src/main/resources/domains/Master.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/Master.properties b/core/persistence-jpa/src/main/resources/domains/Master.properties
new file mode 100644
index 0000000..177e988
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/Master.properties
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+Master.driverClassName=org.postgresql.Driver
+Master.url=jdbc:postgresql://localhost:5432/syncope
+Master.schema=
+Master.username=syncope
+Master.password=syncope
+Master.databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary
+Master.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Master.pool.validationQuery=SELECT 1
+
+Master.audit.sql=audit.sql


[14/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
deleted file mode 100644
index b35c42d..0000000
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.logic.audit;
-
-import java.io.InputStream;
-import java.sql.Connection;
-import java.util.Properties;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.rmi.PortableRemoteObject;
-import javax.sql.DataSource;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathFactory;
-import org.apache.commons.dbcp2.BasicDataSource;
-import org.apache.commons.io.IOUtils;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PropertiesLoaderUtils;
-import org.springframework.jdbc.datasource.DataSourceUtils;
-import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
-import org.springframework.jdbc.datasource.init.ScriptUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSParser;
-
-/**
- * LOG4J SQL connection factory that first attempts to obtain a {@link javax.sql.DataSource} from the JNDI name
- * configured in Spring or, when not found, builds a new {@link javax.sql.DataSource DataSource} via Commons DBCP; if
- * any datasource if found, the SQL init script is used to populate the database.
- */
-public final class AuditConnectionFactory {
-
-    private static DataSource DATASOURCE;
-
-    private static final String PERSISTENCE_CONTEXT = "/persistenceContext.xml";
-
-    static {
-        // 1. Attempts to lookup for configured JNDI datasource (if present and available)
-        InputStream springConf = AuditConnectionFactory.class.getResourceAsStream(PERSISTENCE_CONTEXT);
-        String primary = null;
-        String fallback = null;
-        try {
-            DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
-            DOMImplementationLS impl = (DOMImplementationLS) reg.getDOMImplementation("LS");
-            LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
-            LSInput lsinput = impl.createLSInput();
-            lsinput.setByteStream(springConf);
-            Document source = parser.parse(lsinput);
-
-            XPathFactory xPathfactory = XPathFactory.newInstance();
-            XPath xpath = xPathfactory.newXPath();
-
-            XPathExpression expr = xpath.compile("//*[local-name()='bean' and @id='persistenceProperties']/"
-                    + "child::*[local-name()='property' and @name='primary']/@value");
-            primary = (String) expr.evaluate(source, XPathConstants.STRING);
-            expr = xpath.compile("//*[local-name()='bean' and @id='persistenceProperties']/"
-                    + "child::*[local-name()='property' and @name='fallback']/@value");
-            fallback = (String) expr.evaluate(source, XPathConstants.STRING);
-
-            expr = xpath.compile("//*[local-name()='property' and @name='jndiName']/@value");
-            String jndiName = (String) expr.evaluate(source, XPathConstants.STRING);
-
-            Context ctx = new InitialContext();
-            Object obj = ctx.lookup(jndiName);
-
-            DATASOURCE = (DataSource) PortableRemoteObject.narrow(obj, DataSource.class);
-        } catch (Exception e) {
-            // ignore
-        } finally {
-            IOUtils.closeQuietly(springConf);
-        }
-
-        // 2. Creates Commons DBCP datasource
-        String initSQLScript = null;
-        try {
-            Resource persistenceProperties = null;
-            if (primary != null) {
-                if (primary.startsWith("file:")) {
-                    persistenceProperties = new FileSystemResource(primary.substring(5));
-                }
-                if (primary.startsWith("classpath:")) {
-                    persistenceProperties = new ClassPathResource(primary.substring(10));
-                }
-            }
-            if ((persistenceProperties == null || !persistenceProperties.exists()) && fallback != null) {
-                if (fallback.startsWith("file:")) {
-                    persistenceProperties = new FileSystemResource(fallback.substring(5));
-                }
-                if (fallback.startsWith("classpath:")) {
-                    persistenceProperties = new ClassPathResource(fallback.substring(10));
-                }
-            }
-            Properties persistence = PropertiesLoaderUtils.loadProperties(persistenceProperties);
-
-            initSQLScript = persistence.getProperty("audit.sql");
-
-            if (DATASOURCE == null) {
-                BasicDataSource bds = new BasicDataSource();
-                bds.setDriverClassName(persistence.getProperty("jpa.driverClassName"));
-                bds.setUrl(persistence.getProperty("jpa.url"));
-                bds.setUsername(persistence.getProperty("jpa.username"));
-                bds.setPassword(persistence.getProperty("jpa.password"));
-
-                bds.setLogAbandoned(true);
-                bds.setRemoveAbandonedOnBorrow(true);
-                bds.setRemoveAbandonedOnMaintenance(true);
-
-                DATASOURCE = bds;
-            }
-        } catch (Exception e) {
-            throw new IllegalStateException("Audit datasource configuration failed", e);
-        }
-
-        // 3. Initializes the chosen datasource
-        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
-        populator.setScripts(new Resource[] { new ClassPathResource("/audit/" + initSQLScript) });
-        // forces no statement separation
-        populator.setSeparator(ScriptUtils.EOF_STATEMENT_SEPARATOR);
-        Connection conn = DataSourceUtils.getConnection(DATASOURCE);
-        try {
-            populator.populate(conn);
-        } finally {
-            DataSourceUtils.releaseConnection(conn, DATASOURCE);
-        }
-    }
-
-    public static Connection getConnection() {
-        if (DATASOURCE != null) {
-            return DataSourceUtils.getConnection(DATASOURCE);
-        }
-
-        throw new IllegalStateException("Audit dataSource init failed: check logs");
-    }
-
-    private AuditConnectionFactory() {
-        // empty constructor for static utility class
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
index b22a54d..2bcd78f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
@@ -25,9 +25,6 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
@@ -35,6 +32,9 @@ import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
 import org.apache.syncope.core.logic.report.Reportlet;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -52,7 +52,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
     public enum Type {
 
         REPORTLET,
-        TASKJOB,
+        TASKJOBDELEGATE,
         PROPAGATION_ACTIONS,
         SYNC_ACTIONS,
         PUSH_ACTIONS,
@@ -83,7 +83,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
 
         ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
         scanner.addIncludeFilter(new AssignableTypeFilter(Reportlet.class));
-        scanner.addIncludeFilter(new AssignableTypeFilter(TaskJob.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PushActions.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(SyncCorrelationRule.class));
@@ -102,11 +102,11 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
                     classNames.get(Type.REPORTLET).add(clazz.getName());
                 }
 
-                if (TaskJob.class.isAssignableFrom(clazz) && !isAbsractClazz
-                        && !SyncJob.class.isAssignableFrom(clazz)
-                        && !PushJob.class.isAssignableFrom(clazz)) {
+                if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbsractClazz
+                        && !SyncJobDelegate.class.isAssignableFrom(clazz)
+                        && !PushJobDelegate.class.isAssignableFrom(clazz)) {
 
-                    classNames.get(Type.TASKJOB).add(bd.getBeanClassName());
+                    classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName());
                 }
 
                 if (SyncActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
index 6a8289a..3e7e90f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
@@ -19,11 +19,13 @@
 package org.apache.syncope.core.logic.init;
 
 import java.text.ParseException;
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -37,17 +39,17 @@ import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.logic.notification.NotificationJob;
 import org.apache.syncope.core.logic.report.ReportJob;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.java.sync.PushJobImpl;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobImpl;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.quartz.Job;
+import org.quartz.JobDataMap;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobKey;
 import org.quartz.Scheduler;
@@ -70,6 +72,9 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
     private static final Logger LOG = LoggerFactory.getLogger(JobInstanceLoader.class);
 
     @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Autowired
     private SchedulerFactoryBean scheduler;
 
     @Autowired
@@ -81,7 +86,8 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
     @Autowired
     private ConfDAO confDAO;
 
-    private void registerJob(final String jobName, final Job jobInstance, final String cronExpression)
+    private void registerJob(
+            final String jobName, final Job jobInstance, final String cronExpression, final Map<String, Object> jobMap)
             throws SchedulerException, ParseException {
 
         synchronized (scheduler.getScheduler()) {
@@ -112,6 +118,7 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         jobDetail.setName(jobName);
         jobDetail.setGroup(Scheduler.DEFAULT_GROUP);
         jobDetail.setJobClass(jobInstance.getClass());
+        jobDetail.setJobDataMap(new JobDataMap(jobMap));
 
         // 3. Trigger
         if (cronExpression == null) {
@@ -127,12 +134,13 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         }
     }
 
-    private Job createSpringBean(final Class<?> jobClass) {
-        Job jobInstance = null;
+    @SuppressWarnings("unchecked")
+    private <T> T createSpringBean(final Class<T> jobClass) {
+        T jobInstance = null;
         for (int i = 0; i < 5 && jobInstance == null; i++) {
             LOG.debug("{} attempt to create Spring bean for {}", i, jobClass);
             try {
-                jobInstance = (Job) ApplicationContextProvider.getBeanFactory().
+                jobInstance = (T) ApplicationContextProvider.getBeanFactory().
                         createBean(jobClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
                 LOG.debug("{} attempt to create Spring bean for {} succeeded", i, jobClass);
             } catch (BeanCreationException e) {
@@ -151,75 +159,43 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         return jobInstance;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public void registerJob(final Task task, final String jobClassName, final String cronExpression)
-            throws ClassNotFoundException, SchedulerException, ParseException {
-
-        Class<?> jobClass = Class.forName(jobClassName);
-        if (SyncJob.class.equals(jobClass)) {
-            jobClass = SyncJobImpl.class;
-        } else if (PushJob.class.equals(jobClass)) {
-            jobClass = PushJobImpl.class;
-        }
-
-        Job jobInstance = createSpringBean(jobClass);
-        if (jobInstance instanceof TaskJob) {
-            ((TaskJob) jobInstance).setTaskId(task.getKey());
-        }
-
-        // In case of synchronization job/task retrieve and set synchronization actions:
-        // actions cannot be changed at runtime but connector and synchronization policies (reloaded at execution time).
-        if (jobInstance instanceof SyncJob && task instanceof SyncTask) {
-            final List<SyncActions> actions = new ArrayList<>();
-            for (String className : ((SyncTask) task).getActionsClassNames()) {
-                try {
-                    Class<?> actionsClass = Class.forName(className);
-
-                    SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
-                            createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-                    actions.add(syncActions);
-                } catch (Exception e) {
-                    LOG.info("Class '{}' not found", className, e);
-                }
-            }
+    public Map<String, Object> registerJob(final SchedTask task, final long interruptMaxRetries)
+            throws SchedulerException, ParseException {
 
-            ((SyncJob) jobInstance).setActions(actions);
-        }
+        TaskJob job = createSpringBean(TaskJob.class);
+        job.setTaskKey(task.getKey());
 
-        registerJob(JobNamer.getJobName(task), jobInstance, cronExpression);
-    }
+        String jobDelegateClassName = task instanceof SyncTask
+                ? SyncJobDelegate.class.getName()
+                : task instanceof PushTask
+                        ? PushJobDelegate.class.getName()
+                        : task.getJobDelegateClassName();
 
-    @Transactional(readOnly = true)
-    @Override
-    public void registerTaskJob(final Long taskKey)
-            throws ClassNotFoundException, SchedulerException, ParseException {
+        Map<String, Object> jobMap = new HashMap<>();
+        jobMap.put(JobInstanceLoader.DOMAIN, AuthContextUtils.getDomain());
+        jobMap.put(TaskJob.DELEGATE_CLASS_KEY, jobDelegateClassName);
+        jobMap.put(TaskJob.INTERRUPT_MAX_RETRIES_KEY, interruptMaxRetries);
 
-        SchedTask task = taskDAO.find(taskKey);
-        if (task == null) {
-            throw new NotFoundException("Task " + taskKey);
-        } else {
-            registerJob(task, task.getJobClassName(), task.getCronExpression());
-        }
+        registerJob(JobNamer.getJobName(task), job, task.getCronExpression(), jobMap);
+        return jobMap;
     }
 
     @Override
     public void registerJob(final Report report) throws SchedulerException, ParseException {
-        Job jobInstance = createSpringBean(ReportJob.class);
-        ((ReportJob) jobInstance).setReportKey(report.getKey());
+        ReportJob job = createSpringBean(ReportJob.class);
+        job.setReportKey(report.getKey());
+
+        Map<String, Object> jobMap = new HashMap<>();
+        jobMap.put(JobInstanceLoader.DOMAIN, AuthContextUtils.getDomain());
 
-        registerJob(JobNamer.getJobName(report), jobInstance, report.getCronExpression());
+        registerJob(JobNamer.getJobName(report), job, report.getCronExpression(), jobMap);
     }
 
-    @Transactional(readOnly = true)
-    @Override
-    public void registerReportJob(final Long reportKey) throws SchedulerException, ParseException {
-        Report report = reportDAO.find(reportKey);
-        if (report == null) {
-            throw new NotFoundException("Report " + reportKey);
-        } else {
-            registerJob(report);
-        }
+    private void registerNotificationJob(final String cronExpression) throws SchedulerException, ParseException {
+        NotificationJob job = createSpringBean(NotificationJob.class);
+
+        registerJob("taskNotificationJob", job, cronExpression, Collections.<String, Object>emptyMap());
     }
 
     private void unregisterJob(final String jobName) {
@@ -253,41 +229,62 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
     @Transactional
     @Override
     public void load() {
-        // 1. jobs for SchedTasks
-        Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
-        tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
-        tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
-        for (SchedTask task : tasks) {
+        AuthContextUtils.setFakeAuth(SyncopeConstants.MASTER_DOMAIN);
+        String notificationJobCronExpression = StringUtils.EMPTY;
+        long interruptMaxRetries = 1;
+        try {
+            CPlainAttr notificationJobCronExp =
+                    confDAO.find("notificationjob.cronExpression", NotificationJob.DEFAULT_CRON_EXP);
+            if (!notificationJobCronExp.getValuesAsStrings().isEmpty()) {
+                notificationJobCronExpression = notificationJobCronExp.getValuesAsStrings().get(0);
+            }
+
+            interruptMaxRetries = confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue();
+        } finally {
+            AuthContextUtils.clearFakeAuth();
+        }
+
+        for (String domain : domainsHolder.getDomains().keySet()) {
+            AuthContextUtils.setFakeAuth(domain);
+
             try {
-                registerJob(task, task.getJobClassName(), task.getCronExpression());
-            } catch (Exception e) {
-                LOG.error("While loading job instance for task " + task.getKey(), e);
+                // 1. jobs for SchedTasks
+                Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
+                tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
+                tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
+                for (SchedTask task : tasks) {
+                    try {
+                        registerJob(task, interruptMaxRetries);
+                    } catch (Exception e) {
+                        LOG.error("While loading job instance for task " + task.getKey(), e);
+                    }
+                }
+
+                // 2. ReportJobs
+                for (Report report : reportDAO.findAll()) {
+                    try {
+                        registerJob(report);
+                    } catch (Exception e) {
+                        LOG.error("While loading job instance for report " + report.getName(), e);
+                    }
+                }
+            } finally {
+                AuthContextUtils.clearFakeAuth();
             }
         }
 
-        // 2. NotificationJob
-        CPlainAttr notificationJobCronExp =
-                confDAO.find("notificationjob.cronExpression", NotificationJob.DEFAULT_CRON_EXP);
-        if (StringUtils.isBlank(notificationJobCronExp.getValuesAsStrings().get(0))) {
+        // 3. NotificationJob
+        if (StringUtils.isBlank(notificationJobCronExpression)) {
             LOG.debug("Empty value provided for NotificationJob's cron, not registering anything on Quartz");
         } else {
             LOG.debug("NotificationJob's cron expression: {} - registering Quartz job and trigger",
-                    notificationJobCronExp);
+                    notificationJobCronExpression);
 
             try {
-                registerJob(null, NotificationJob.class.getName(), notificationJobCronExp.getValuesAsStrings().get(0));
+                registerNotificationJob(notificationJobCronExpression);
             } catch (Exception e) {
                 LOG.error("While loading NotificationJob instance", e);
             }
         }
-
-        // 3. ReportJobs
-        for (Report report : reportDAO.findAll()) {
-            try {
-                registerJob(report);
-            } catch (Exception e) {
-                LOG.error("While loading job instance for report " + report.getName(), e);
-            }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index 447a92f..e86b46a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -18,19 +18,30 @@
  */
 package org.apache.syncope.core.logic.init;
 
+import java.sql.Connection;
+import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.Map;
+import javax.sql.DataSource;
+import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
+import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
+import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.LoggerLevel;
 import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -38,6 +49,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class LoggerLoader implements SyncopeLoader {
 
     @Autowired
+    private DomainsHolder domainsHolder;
+
+    @Autowired
     private LoggerDAO loggerDAO;
 
     @Autowired
@@ -51,6 +65,39 @@ public class LoggerLoader implements SyncopeLoader {
     @Transactional
     @Override
     public void load() {
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+
+        // 1. Audit table and DataSource for each configured domain
+        ColumnConfig[] columns = {
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "EVENT_DATE", null, null, "true", null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER_LEVEL", "%level", null, null, null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER", "%logger", null, null, null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "MESSAGE", "%message", null, null, null, null),
+            ColumnConfig.createColumnConfig(ctx.getConfiguration(), "THROWABLE", "%ex{full}", null, null, null, null)
+        };
+        for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+            Appender appender = ctx.getConfiguration().getAppender("audit_for_" + entry.getKey());
+            if (appender == null) {
+                appender = JdbcAppender.createAppender(
+                        "audit_for_" + entry.getKey(),
+                        "false",
+                        null,
+                        new DataSourceConnectionSource(entry.getValue()),
+                        "0",
+                        "SYNCOPEAUDIT",
+                        columns);
+                appender.start();
+                ctx.getConfiguration().addAppender(appender);
+            }
+
+            LoggerConfig logConf = new LoggerConfig(
+                    AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
+            logConf.addAppender(appender, Level.DEBUG, null);
+            ctx.getConfiguration().addLogger(AuditManager.getDomainAuditLoggerName(entry.getKey()), logConf);
+        }
+        ctx.updateLoggers();
+
+        // 2. Aligning log4j conf with database content
         Map<String, Logger> syncopeLoggers = new HashMap<>();
         for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.LOG)) {
             syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
@@ -60,8 +107,6 @@ public class LoggerLoader implements SyncopeLoader {
             syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
         }
 
-        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-
         /*
          * Traverse all defined log4j loggers: if there is a matching SyncopeLogger, set log4j level accordingly,
          * otherwise create a SyncopeLogger instance with given name and level.
@@ -95,4 +140,19 @@ public class LoggerLoader implements SyncopeLoader {
 
         ctx.updateLoggers();
     }
+
+    private static class DataSourceConnectionSource implements ConnectionSource {
+
+        private final DataSource dataSource;
+
+        public DataSourceConnectionSource(final DataSource dataSource) {
+            this.dataSource = dataSource;
+        }
+
+        @Override
+        public Connection getConnection() throws SQLException {
+            return DataSourceUtils.getConnection(dataSource);
+        }
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
index 9ae6aa9..856fa13 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -61,6 +62,8 @@ public class LogicInitializer implements InitializingBean, BeanFactoryAware {
             }
         });
 
+        ApplicationContextProvider.setBeanFactory(beanFactory);
+
         LOG.debug("Starting initialization...");
         for (SyncopeLoader loader : loaders) {
             LOG.debug("Invoking {} with priority {}", AopUtils.getTargetClass(loader).getName(), loader.getPriority());

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
index 9e40ff1..a0f21f3 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
@@ -18,21 +18,8 @@
  */
 package org.apache.syncope.core.logic.notification;
 
-import java.util.Date;
-import java.util.Properties;
-import javax.mail.internet.MimeMessage;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.ExceptionUtils2;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
@@ -40,15 +27,12 @@ import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.mail.javamail.MimeMessageHelper;
 import org.springframework.stereotype.Component;
 
 /**
  * Periodically checks for notification to send.
  *
- * @see NotificationTask
+ * @see org.apache.syncope.core.persistence.api.entity.task.NotificationTask
  */
 @Component
 @DisallowConcurrentExecution
@@ -63,221 +47,30 @@ public class NotificationJob implements Job {
 
     public static final String DEFAULT_CRON_EXP = "0 0/5 * * * ?";
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(NotificationJob.class);
 
     @Autowired
-    private AuditManager auditManager;
+    private DomainsHolder domainsHolder;
 
     @Autowired
-    private NotificationManager notificationManager;
-
-    @Autowired
-    private JavaMailSender mailSender;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    /**
-     * Task DAO.
-     */
-    @Autowired
-    private TaskDAO taskDAO;
-
-    private long maxRetries;
-
-    private void init() {
-        maxRetries = notificationManager.getMaxRetries();
-
-        if (mailSender instanceof JavaMailSenderImpl
-                && StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
-
-            Properties javaMailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties();
-            javaMailProperties.setProperty("mail.smtp.auth", "true");
-            ((JavaMailSenderImpl) mailSender).setJavaMailProperties(javaMailProperties);
-        }
-    }
-
-    public TaskExec executeSingle(final NotificationTask task) {
-        init();
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setTask(task);
-        execution.setStartDate(new Date());
-
-        boolean retryPossible = true;
-
-        if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
-                || StringUtils.isBlank(task.getHtmlBody()) || StringUtils.isBlank(task.getTextBody())) {
-
-            String message = "Could not fetch all required information for sending e-mails:\n"
-                    + task.getRecipients() + "\n"
-                    + task.getSender() + "\n"
-                    + task.getSubject() + "\n"
-                    + task.getHtmlBody() + "\n"
-                    + task.getTextBody();
-            LOG.error(message);
-
-            execution.setStatus(Status.NOT_SENT.name());
-            retryPossible = false;
-
-            if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
-                execution.setMessage(message);
-            }
-        } else {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("About to send e-mails:\n"
-                        + task.getRecipients() + "\n"
-                        + task.getSender() + "\n"
-                        + task.getSubject() + "\n"
-                        + task.getHtmlBody() + "\n"
-                        + task.getTextBody() + "\n");
-            }
-
-            for (String to : task.getRecipients()) {
-                try {
-                    MimeMessage message = mailSender.createMimeMessage();
-                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
-                    helper.setTo(to);
-                    helper.setFrom(task.getSender());
-                    helper.setSubject(task.getSubject());
-                    helper.setText(task.getTextBody(), task.getHtmlBody());
-
-                    mailSender.send(message);
-
-                    execution.setStatus(Status.SENT.name());
-
-                    StringBuilder report = new StringBuilder();
-                    switch (task.getTraceLevel()) {
-                        case ALL:
-                            report.append("FROM: ").append(task.getSender()).append('\n').
-                                    append("TO: ").append(to).append('\n').
-                                    append("SUBJECT: ").append(task.getSubject()).append('\n').append('\n').
-                                    append(task.getTextBody()).append('\n').append('\n').
-                                    append(task.getHtmlBody()).append('\n');
-                            break;
-
-                        case SUMMARY:
-                            report.append("E-mail sent to ").append(to).append('\n');
-                            break;
-
-                        case FAILURES:
-                        case NONE:
-                        default:
-                    }
-                    if (report.length() > 0) {
-                        execution.setMessage(report.toString());
-                    }
-
-                    auditManager.audit(
-                            AuditElements.EventCategoryType.TASK,
-                            "notification",
-                            null,
-                            "send",
-                            Result.SUCCESS,
-                            null,
-                            null,
-                            task,
-                            "Successfully sent notification to " + to);
-                } catch (Exception e) {
-                    LOG.error("Could not send e-mail", e);
-
-                    execution.setStatus(Status.NOT_SENT.name());
-                    if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
-                        execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
-                    }
-
-                    auditManager.audit(
-                            AuditElements.EventCategoryType.TASK,
-                            "notification",
-                            null,
-                            "send",
-                            Result.FAILURE,
-                            null,
-                            null,
-                            task,
-                            "Could not send notification to " + to, e);
-                }
-
-                execution.setEndDate(new Date());
-            }
-        }
-
-        if (hasToBeRegistered(execution)) {
-            execution = notificationManager.storeExec(execution);
-            if (retryPossible && (Status.valueOf(execution.getStatus()) == Status.NOT_SENT)) {
-                handleRetries(execution);
-            }
-        } else {
-            notificationManager.setTaskExecuted(execution.getTask().getKey(), true);
-        }
-
-        return execution;
-    }
+    private NotificationJobDelegate delegate;
 
     @Override
-    public void execute(final JobExecutionContext context)
-            throws JobExecutionException {
-
+    public void execute(final JobExecutionContext context) throws JobExecutionException {
         LOG.debug("Waking up...");
 
-        for (NotificationTask task : taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION)) {
-            LOG.debug("Found notification task {} to be executed: starting...", task);
-            executeSingle(task);
-            LOG.debug("Notification task {} executed", task);
+        for (String domain : domainsHolder.getDomains().keySet()) {
+            AuthContextUtils.setFakeAuth(domain);
+            try {
+                delegate.execute();
+            } catch (Exception e) {
+                throw new JobExecutionException(e);
+            } finally {
+                AuthContextUtils.clearFakeAuth();
+            }
         }
 
         LOG.debug("Sleeping again...");
     }
 
-    private boolean hasToBeRegistered(final TaskExec execution) {
-        NotificationTask task = (NotificationTask) execution.getTask();
-
-        // True if either failed and failures have to be registered, or if ALL
-        // has to be registered.
-        return (Status.valueOf(execution.getStatus()) == Status.NOT_SENT
-                && task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
-                || task.getTraceLevel() == TraceLevel.ALL;
-    }
-
-    private void handleRetries(final TaskExec execution) {
-        if (maxRetries <= 0) {
-            return;
-        }
-
-        long failedExecutionsCount = notificationManager.countExecutionsWithStatus(
-                execution.getTask().getKey(), Status.NOT_SENT.name());
-
-        if (failedExecutionsCount <= maxRetries) {
-            LOG.debug("Execution of notification task {} will be retried [{}/{}]",
-                    execution.getTask(), failedExecutionsCount, maxRetries);
-            notificationManager.setTaskExecuted(execution.getTask().getKey(), false);
-
-            auditManager.audit(
-                    AuditElements.EventCategoryType.TASK,
-                    "notification",
-                    null,
-                    "retry",
-                    Result.SUCCESS,
-                    null,
-                    null,
-                    execution,
-                    "Notification task " + execution.getTask().getKey() + " will be retried");
-        } else {
-            LOG.error("Maximum number of retries reached for task {} - giving up", execution.getTask());
-
-            auditManager.audit(
-                    AuditElements.EventCategoryType.TASK,
-                    "notification",
-                    null,
-                    "retry",
-                    Result.FAILURE,
-                    null,
-                    null,
-                    execution,
-                    "Giving up retries on notification task " + execution.getTask().getKey());
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
new file mode 100644
index 0000000..aaebe77
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.logic.notification;
+
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.internet.MimeMessage;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class NotificationJobDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationJobDelegate.class);
+
+    /**
+     * Task DAO.
+     */
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private JavaMailSender mailSender;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
+    private AuditManager auditManager;
+
+    @Autowired
+    private NotificationManager notificationManager;
+
+    private long maxRetries;
+
+    private void init() {
+        maxRetries = notificationManager.getMaxRetries();
+
+        if (mailSender instanceof JavaMailSenderImpl
+                && StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
+
+            Properties javaMailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties();
+            javaMailProperties.setProperty("mail.smtp.auth", "true");
+            ((JavaMailSenderImpl) mailSender).setJavaMailProperties(javaMailProperties);
+        }
+    }
+
+    @Transactional
+    public TaskExec executeSingle(final NotificationTask task) {
+        init();
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setTask(task);
+        execution.setStartDate(new Date());
+
+        boolean retryPossible = true;
+
+        if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
+                || StringUtils.isBlank(task.getHtmlBody()) || StringUtils.isBlank(task.getTextBody())) {
+
+            String message = "Could not fetch all required information for sending e-mails:\n"
+                    + task.getRecipients() + "\n"
+                    + task.getSender() + "\n"
+                    + task.getSubject() + "\n"
+                    + task.getHtmlBody() + "\n"
+                    + task.getTextBody();
+            LOG.error(message);
+
+            execution.setStatus(NotificationJob.Status.NOT_SENT.name());
+            retryPossible = false;
+
+            if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
+                execution.setMessage(message);
+            }
+        } else {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("About to send e-mails:\n"
+                        + task.getRecipients() + "\n"
+                        + task.getSender() + "\n"
+                        + task.getSubject() + "\n"
+                        + task.getHtmlBody() + "\n"
+                        + task.getTextBody() + "\n");
+            }
+
+            for (String to : task.getRecipients()) {
+                try {
+                    MimeMessage message = mailSender.createMimeMessage();
+                    MimeMessageHelper helper = new MimeMessageHelper(message, true);
+                    helper.setTo(to);
+                    helper.setFrom(task.getSender());
+                    helper.setSubject(task.getSubject());
+                    helper.setText(task.getTextBody(), task.getHtmlBody());
+
+                    mailSender.send(message);
+
+                    execution.setStatus(NotificationJob.Status.SENT.name());
+
+                    StringBuilder report = new StringBuilder();
+                    switch (task.getTraceLevel()) {
+                        case ALL:
+                            report.append("FROM: ").append(task.getSender()).append('\n').
+                                    append("TO: ").append(to).append('\n').
+                                    append("SUBJECT: ").append(task.getSubject()).append('\n').append('\n').
+                                    append(task.getTextBody()).append('\n').append('\n').
+                                    append(task.getHtmlBody()).append('\n');
+                            break;
+
+                        case SUMMARY:
+                            report.append("E-mail sent to ").append(to).append('\n');
+                            break;
+
+                        case FAILURES:
+                        case NONE:
+                        default:
+                    }
+                    if (report.length() > 0) {
+                        execution.setMessage(report.toString());
+                    }
+
+                    auditManager.audit(
+                            AuditElements.EventCategoryType.TASK,
+                            "notification",
+                            null,
+                            "send",
+                            AuditElements.Result.SUCCESS,
+                            null,
+                            null,
+                            task,
+                            "Successfully sent notification to " + to);
+                } catch (Exception e) {
+                    LOG.error("Could not send e-mail", e);
+
+                    execution.setStatus(NotificationJob.Status.NOT_SENT.name());
+                    if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
+                        execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
+                    }
+
+                    auditManager.audit(
+                            AuditElements.EventCategoryType.TASK,
+                            "notification",
+                            null,
+                            "send",
+                            AuditElements.Result.FAILURE,
+                            null,
+                            null,
+                            task,
+                            "Could not send notification to " + to, e);
+                }
+
+                execution.setEndDate(new Date());
+            }
+        }
+
+        if (hasToBeRegistered(execution)) {
+            execution = notificationManager.storeExec(execution);
+            if (retryPossible && (NotificationJob.Status.valueOf(execution.getStatus())
+                    == NotificationJob.Status.NOT_SENT)) {
+                handleRetries(execution);
+            }
+        } else {
+            notificationManager.setTaskExecuted(execution.getTask().getKey(), true);
+        }
+
+        return execution;
+    }
+
+    @Transactional
+    public void execute() throws JobExecutionException {
+        for (NotificationTask task : taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION)) {
+            LOG.debug("Found notification task {} to be executed: starting...", task);
+            executeSingle(task);
+            LOG.debug("Notification task {} executed", task);
+        }
+    }
+
+    private boolean hasToBeRegistered(final TaskExec execution) {
+        NotificationTask task = (NotificationTask) execution.getTask();
+
+        // True if either failed and failures have to be registered, or if ALL
+        // has to be registered.
+        return (NotificationJob.Status.valueOf(execution.getStatus()) == NotificationJob.Status.NOT_SENT
+                && task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
+                || task.getTraceLevel() == TraceLevel.ALL;
+    }
+
+    private void handleRetries(final TaskExec execution) {
+        if (maxRetries <= 0) {
+            return;
+        }
+
+        long failedExecutionsCount = notificationManager.countExecutionsWithStatus(
+                execution.getTask().getKey(), NotificationJob.Status.NOT_SENT.name());
+
+        if (failedExecutionsCount <= maxRetries) {
+            LOG.debug("Execution of notification task {} will be retried [{}/{}]",
+                    execution.getTask(), failedExecutionsCount, maxRetries);
+            notificationManager.setTaskExecuted(execution.getTask().getKey(), false);
+
+            auditManager.audit(
+                    AuditElements.EventCategoryType.TASK,
+                    "notification",
+                    null,
+                    "retry",
+                    AuditElements.Result.SUCCESS,
+                    null,
+                    null,
+                    execution,
+                    "Notification task " + execution.getTask().getKey() + " will be retried");
+        } else {
+            LOG.error("Maximum number of retries reached for task {} - giving up", execution.getTask());
+
+            auditManager.audit(
+                    AuditElements.EventCategoryType.TASK,
+                    "notification",
+                    null,
+                    "retry",
+                    AuditElements.Result.FAILURE,
+                    null,
+                    null,
+                    execution,
+                    "Giving up retries on notification task " + execution.getTask().getKey());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
index e07612a..8e5af91 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
@@ -18,74 +18,28 @@
  */
 package org.apache.syncope.core.logic.report;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Date;
-import java.util.zip.Deflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.report.ReportletConf;
-import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.core.persistence.api.dao.ReportDAO;
-import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.Report;
-import org.apache.syncope.core.persistence.api.entity.ReportExec;
-import org.apache.syncope.core.logic.ReportLogic;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.xml.sax.helpers.AttributesImpl;
 
 /**
  * Quartz job for executing a given report.
  */
-@SuppressWarnings("unchecked")
 @DisallowConcurrentExecution
 public class ReportJob implements Job {
 
     /**
-     * Logger.
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(ReportJob.class);
-
-    /**
-     * Report DAO.
-     */
-    @Autowired
-    private ReportDAO reportDAO;
-
-    /**
-     * Report execution DAO.
-     */
-    @Autowired
-    private ReportExecDAO reportExecDAO;
-
-    @Autowired
-    private ReportLogic dataBinder;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    /**
      * Key, set by the caller, for identifying the report to be executed.
      */
     private Long reportKey;
 
+    @Autowired
+    private ReportJobDelegate delegate;
+
     /**
      * Report id setter.
      *
@@ -95,109 +49,15 @@ public class ReportJob implements Job {
         this.reportKey = reportKey;
     }
 
-    @SuppressWarnings("rawtypes")
     @Override
     public void execute(final JobExecutionContext context) throws JobExecutionException {
-        Report report = reportDAO.find(reportKey);
-        if (report == null) {
-            throw new JobExecutionException("Report " + reportKey + " not found");
-        }
-
-        // 1. create execution
-        ReportExec execution = entityFactory.newEntity(ReportExec.class);
-        execution.setStatus(ReportExecStatus.STARTED);
-        execution.setStartDate(new Date());
-        execution.setReport(report);
-        execution = reportExecDAO.save(execution);
-
-        report.addExec(execution);
-        report = reportDAO.save(report);
-
-        // 2. define a SAX handler for generating result as XML
-        TransformerHandler handler;
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ZipOutputStream zos = new ZipOutputStream(baos);
-        zos.setLevel(Deflater.BEST_COMPRESSION);
-        try {
-            SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
-            handler = tFactory.newTransformerHandler();
-            Transformer serializer = handler.getTransformer();
-            serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
-            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
-
-            // a single ZipEntry in the ZipOutputStream
-            zos.putNextEntry(new ZipEntry(report.getName()));
-
-            // streaming SAX handler in a compressed byte array stream
-            handler.setResult(new StreamResult(zos));
-        } catch (Exception e) {
-            throw new JobExecutionException("While configuring for SAX generation", e, true);
-        }
-
-        execution.setStatus(ReportExecStatus.RUNNING);
-        execution = reportExecDAO.save(execution);
-
-        // 3. actual report execution
-        StringBuilder reportExecutionMessage = new StringBuilder();
+        AuthContextUtils.setFakeAuth(context.getMergedJobDataMap().getString(JobInstanceLoader.DOMAIN));
         try {
-            // report header
-            handler.startDocument();
-            AttributesImpl atts = new AttributesImpl();
-            atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, report.getName());
-            handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts);
-
-            // iterate over reportlet instances defined for this report
-            for (ReportletConf reportletConf : report.getReportletConfs()) {
-                Class<Reportlet> reportletClass =
-                        dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
-                if (reportletClass != null) {
-                    Reportlet<ReportletConf> autowired =
-                            (Reportlet<ReportletConf>) ApplicationContextProvider.getBeanFactory().
-                            createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
-                    autowired.setConf(reportletConf);
-
-                    // invoke reportlet
-                    try {
-                        autowired.extract(handler);
-                    } catch (Exception e) {
-                        execution.setStatus(ReportExecStatus.FAILURE);
-
-                        Throwable t = e instanceof ReportException
-                                ? e.getCause()
-                                : e;
-                        reportExecutionMessage.
-                                append(ExceptionUtils2.getFullStackTrace(t)).
-                                append("\n==================\n");
-                    }
-                }
-            }
-
-            // report footer
-            handler.endElement("", "", ReportXMLConst.ELEMENT_REPORT);
-            handler.endDocument();
-
-            if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
-                execution.setStatus(ReportExecStatus.SUCCESS);
-            }
+            delegate.execute(reportKey);
         } catch (Exception e) {
-            execution.setStatus(ReportExecStatus.FAILURE);
-            reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
-
-            throw new JobExecutionException(e, true);
+            throw new JobExecutionException(e);
         } finally {
-            try {
-                zos.closeEntry();
-                IOUtils.closeQuietly(zos);
-                IOUtils.closeQuietly(baos);
-            } catch (IOException e) {
-                LOG.error("While closing StreamResult's backend", e);
-            }
-
-            execution.setExecResult(baos.toByteArray());
-            execution.setMessage(reportExecutionMessage.toString());
-            execution.setEndDate(new Date());
-            reportExecDAO.save(execution);
+            AuthContextUtils.clearFakeAuth();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
new file mode 100644
index 0000000..9920c1f
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.logic.report;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.core.logic.ReportLogic;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.ReportExec;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.xml.sax.helpers.AttributesImpl;
+
+@Component
+public class ReportJobDelegate {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ReportJobDelegate.class);
+
+    /**
+     * Report DAO.
+     */
+    @Autowired
+    private ReportDAO reportDAO;
+
+    /**
+     * Report execution DAO.
+     */
+    @Autowired
+    private ReportExecDAO reportExecDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
+    private ReportLogic dataBinder;
+
+    @Transactional
+    public void execute(final Long reportKey) throws JobExecutionException {
+        Report report = reportDAO.find(reportKey);
+        if (report == null) {
+            throw new JobExecutionException("Report " + reportKey + " not found");
+        }
+
+        // 1. create execution
+        ReportExec execution = entityFactory.newEntity(ReportExec.class);
+        execution.setStatus(ReportExecStatus.STARTED);
+        execution.setStartDate(new Date());
+        execution.setReport(report);
+        execution = reportExecDAO.save(execution);
+
+        report.addExec(execution);
+        report = reportDAO.save(report);
+
+        // 2. define a SAX handler for generating result as XML
+        TransformerHandler handler;
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipOutputStream zos = new ZipOutputStream(baos);
+        zos.setLevel(Deflater.BEST_COMPRESSION);
+        try {
+            SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+            handler = tFactory.newTransformerHandler();
+            Transformer serializer = handler.getTransformer();
+            serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
+            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+            // a single ZipEntry in the ZipOutputStream
+            zos.putNextEntry(new ZipEntry(report.getName()));
+
+            // streaming SAX handler in a compressed byte array stream
+            handler.setResult(new StreamResult(zos));
+        } catch (Exception e) {
+            throw new JobExecutionException("While configuring for SAX generation", e, true);
+        }
+
+        execution.setStatus(ReportExecStatus.RUNNING);
+        execution = reportExecDAO.save(execution);
+
+        // 3. actual report execution
+        StringBuilder reportExecutionMessage = new StringBuilder();
+        try {
+            // report header
+            handler.startDocument();
+            AttributesImpl atts = new AttributesImpl();
+            atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, report.getName());
+            handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts);
+
+            // iterate over reportlet instances defined for this report
+            for (ReportletConf reportletConf : report.getReportletConfs()) {
+                Class<Reportlet> reportletClass =
+                        dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
+                if (reportletClass != null) {
+                    @SuppressWarnings("unchecked")
+                    Reportlet<ReportletConf> autowired =
+                            (Reportlet<ReportletConf>) ApplicationContextProvider.getBeanFactory().
+                            createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+                    autowired.setConf(reportletConf);
+
+                    // invoke reportlet
+                    try {
+                        autowired.extract(handler);
+                    } catch (Exception e) {
+                        execution.setStatus(ReportExecStatus.FAILURE);
+
+                        Throwable t = e instanceof ReportException
+                                ? e.getCause()
+                                : e;
+                        reportExecutionMessage.
+                                append(ExceptionUtils2.getFullStackTrace(t)).
+                                append("\n==================\n");
+                    }
+                }
+            }
+
+            // report footer
+            handler.endElement("", "", ReportXMLConst.ELEMENT_REPORT);
+            handler.endDocument();
+
+            if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
+                execution.setStatus(ReportExecStatus.SUCCESS);
+            }
+        } catch (Exception e) {
+            execution.setStatus(ReportExecStatus.FAILURE);
+            reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
+
+            throw new JobExecutionException(e, true);
+        } finally {
+            try {
+                zos.closeEntry();
+                IOUtils.closeQuietly(zos);
+                IOUtils.closeQuietly(baos);
+            } catch (IOException e) {
+                LOG.error("While closing StreamResult's backend", e);
+            }
+
+            execution.setExecResult(baos.toByteArray());
+            execution.setMessage(reportExecutionMessage.toString());
+            execution.setEndDate(new Date());
+            reportExecDAO.save(execution);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
index 161d0c1..d4b0fa4 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
@@ -23,7 +23,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
+import org.springframework.test.context.transaction.TransactionConfiguration;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = {
@@ -33,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
     "classpath:persistenceTest.xml",
     "classpath:logicTest.xml"
 })
-@Transactional
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
 public abstract class AbstractTest {
 
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
index 1f1dab7..770bac9 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
@@ -31,7 +31,9 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.identityconnectors.framework.common.objects.Name;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional
 public class MappingTest extends AbstractTest {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
index c5dc13c..6c208a2 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
@@ -79,7 +79,9 @@ import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional
 public class NotificationTest extends AbstractTest {
 
     private static final String SMTP_HOST = "localhost";
@@ -164,7 +166,7 @@ public class NotificationTest extends AbstractTest {
     }
 
     private static UserTO getSampleTO(final String email) {
-        String uid = email;
+        String uid = UUID.randomUUID().toString().substring(0, 8) + email;
         UserTO userTO = new UserTO();
         userTO.setPassword("password123");
         userTO.setUsername(uid);
@@ -175,7 +177,7 @@ public class NotificationTest extends AbstractTest {
         userTO.getPlainAttrs().add(attributeTO("surname", "surname"));
         userTO.getPlainAttrs().add(attributeTO("type", "a type"));
         userTO.getPlainAttrs().add(attributeTO("userId", uid));
-        userTO.getPlainAttrs().add(attributeTO("email", uid));
+        userTO.getPlainAttrs().add(attributeTO("email", email));
         userTO.getPlainAttrs().add(attributeTO("loginDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
         userTO.getDerAttrs().add(attributeTO("cn", null));
         userTO.getVirAttrs().add(attributeTO("virtualdata", "virtualvalue"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/resources/logicTest.xml
----------------------------------------------------------------------
diff --git a/core/logic/src/test/resources/logicTest.xml b/core/logic/src/test/resources/logicTest.xml
index 3cf0ab0..2dca918 100644
--- a/core/logic/src/test/resources/logicTest.xml
+++ b/core/logic/src/test/resources/logicTest.xml
@@ -26,6 +26,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
         <value>classpath:connid.properties</value>
         <value>classpath:mail.properties</value>
@@ -37,10 +38,5 @@ under the License.
     <property name="ignoreResourceNotFound" value="true"/>
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
-  
-  <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${conf.directory}/content.xml"/>
-    <property name="fallback" value="classpath:content.xml"/>
-  </bean>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
index a8d8aac..d370895 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
@@ -23,13 +23,18 @@ import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.AuditLoggerName;
 import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
 @Component
 public class AuditManager {
@@ -39,6 +44,11 @@ public class AuditManager {
     @Autowired
     private LoggerDAO loggerDAO;
 
+    public static String getDomainAuditLoggerName(final String domain) {
+        return LoggerType.AUDIT.getPrefix() + "." + domain;
+    }
+
+    @Transactional(readOnly = true)
     public void audit(
             final AuditElements.EventCategoryType type,
             final String category,
@@ -88,13 +98,22 @@ public class AuditManager {
             if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
                 StringBuilder auditMessage = new StringBuilder();
 
-                final SecurityContext ctx = SecurityContextHolder.getContext();
+                SecurityContext ctx = SecurityContextHolder.getContext();
                 if (ctx != null && ctx.getAuthentication() != null) {
                     auditMessage.append('[').append(ctx.getAuthentication().getName()).append("] ");
                 }
                 auditMessage.append(message);
 
-                final Logger logger = LoggerFactory.getLogger(auditLoggerName.toLoggerName());
+                String domain = AuthContextUtils.getDomain();
+                if (input != null && input.length > 0 && input[0] instanceof UsernamePasswordAuthenticationToken) {
+                    UsernamePasswordAuthenticationToken token =
+                            UsernamePasswordAuthenticationToken.class.cast(input[0]);
+                    if (token.getDetails() instanceof SyncopeAuthenticationDetails) {
+                        domain = SyncopeAuthenticationDetails.class.cast(token.getDetails()).getDomain();
+                    }
+                }
+
+                Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(domain));
                 if (throwable == null) {
                     logger.debug(auditMessage.toString());
                 } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
index e655809..95a16b1 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
@@ -73,7 +73,7 @@ import org.identityconnectors.framework.common.objects.Name;
 import org.identityconnectors.framework.common.objects.OperationalAttributes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 
 public final class MappingUtils {
 
@@ -141,9 +141,9 @@ public final class MappingUtils {
         LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
                 any, provision, any.getPlainAttrs());
 
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        VirAttrCache virAttrCache = context.getBean(VirAttrCache.class);
-        PasswordGenerator passwordGenerator = context.getBean(PasswordGenerator.class);
+        DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
+        VirAttrCache virAttrCache = beanFactory.getBean(VirAttrCache.class);
+        PasswordGenerator passwordGenerator = beanFactory.getBean(PasswordGenerator.class);
 
         Set<Attribute> attributes = new HashSet<>();
         String connObjectKey = null;
@@ -227,9 +227,9 @@ public final class MappingUtils {
 
         List<Any<?, ?, ?>> anys = new ArrayList<>();
 
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        AnyUtilsFactory anyUtilsFactory = context.getBean(AnyUtilsFactory.class);
-        VirAttrHandler virAttrHandler = context.getBean(VirAttrHandler.class);
+        DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
+        AnyUtilsFactory anyUtilsFactory = beanFactory.getBean(AnyUtilsFactory.class);
+        VirAttrHandler virAttrHandler = beanFactory.getBean(VirAttrHandler.class);
 
         switch (mapItem.getIntMappingType().getAnyTypeKind()) {
             case USER:
@@ -240,7 +240,7 @@ public final class MappingUtils {
 
             case GROUP:
                 if (any instanceof User) {
-                    UserDAO userDAO = context.getBean(UserDAO.class);
+                    UserDAO userDAO = beanFactory.getBean(UserDAO.class);
                     for (Group group : userDAO.findAllGroups((User) any)) {
                         virAttrHandler.retrieveVirAttrValues(group);
                         anys.add(group);
@@ -271,7 +271,7 @@ public final class MappingUtils {
             case UserPlainSchema:
             case GroupPlainSchema:
             case AnyObjectPlainSchema:
-                final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
+                PlainSchemaDAO plainSchemaDAO = beanFactory.getBean(PlainSchemaDAO.class);
                 schema = plainSchemaDAO.find(mapItem.getIntAttrName());
                 schemaType = schema == null ? AttrSchemaType.String : schema.getType();
                 break;
@@ -279,7 +279,7 @@ public final class MappingUtils {
             case UserVirtualSchema:
             case GroupVirtualSchema:
             case AnyObjectVirtualSchema:
-                VirSchemaDAO virSchemaDAO = context.getBean(VirSchemaDAO.class);
+                VirSchemaDAO virSchemaDAO = beanFactory.getBean(VirSchemaDAO.class);
                 VirSchema virSchema = virSchemaDAO.find(mapItem.getIntAttrName());
                 readOnlyVirSchema = (virSchema != null && virSchema.isReadonly());
                 schemaType = AttrSchemaType.String;
@@ -434,9 +434,9 @@ public final class MappingUtils {
         LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
 
         EntityFactory entityFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(EntityFactory.class);
+                ApplicationContextProvider.getBeanFactory().getBean(EntityFactory.class);
         AnyUtilsFactory anyUtilsFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
+                ApplicationContextProvider.getBeanFactory().getBean(AnyUtilsFactory.class);
         List<PlainAttrValue> values = new ArrayList<>();
         PlainAttrValue attrValue;
         switch (mappingItem.getIntMappingType()) {
@@ -551,7 +551,7 @@ public final class MappingUtils {
                 break;
 
             case GroupOwnerSchema:
-                AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class);
+                AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class);
                 Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
                         ? null
                         : provision.getMapping();

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
index 4b8faec..13ddc84 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
@@ -22,8 +22,6 @@ import java.util.regex.Pattern;
 import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.UserSuspender;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -31,11 +29,8 @@ public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec,
 
     private static final Pattern DEFAULT_PATTERN = Pattern.compile("[a-zA-Z0-9-_@. ]+");
 
-    @Autowired(required = false)
-    private UserSuspender userSuspender;
-
     @Override
-    public void enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
+    public boolean enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
         if (user.getUsername() == null) {
             throw new PolicyEnforceException("Invalid account");
         }
@@ -90,11 +85,7 @@ public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec,
         }
 
         // check for subsequent failed logins
-        if (userSuspender != null
-                && user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
-                && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended()) {
-
-            userSuspender.suspend(user, policy.isPropagateSuspension());
-        }
+        return (user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
+                && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
index 41a6bb6..1313d2e 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Component;
 public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec, User> {
 
     @Override
-    public void enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
+    public boolean enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
         final String clearPassword = user.getClearPassword();
         final String password = user.getPassword();
 
@@ -147,6 +147,8 @@ public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec
                 throw new PasswordPolicyException("Password mustn't end with a non-alphanumeric character");
             }
         }
+
+        return false;
     }
 
     private boolean checkForDigit(final String str) {


[03/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/test/resources/provisioningTest.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/resources/provisioningTest.xml b/core/provisioning-java/src/test/resources/provisioningTest.xml
index b6621c3..54797a5 100644
--- a/core/provisioning-java/src/test/resources/provisioningTest.xml
+++ b/core/provisioning-java/src/test/resources/provisioningTest.xml
@@ -26,6 +26,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
         <value>classpath:connid.properties</value>
         <value>classpath:mail.properties</value>
@@ -37,10 +38,4 @@ under the License.
     <property name="ignoreUnresolvablePlaceholders" value="true"/>
   </bean>
   
-  <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
-    <property name="primary" value="file:${conf.directory}/content.xml"/>
-    <property name="fallback" value="classpath:content.xml"/>
-  </bean>
-  <bean class="org.apache.syncope.core.persistence.jpa.content.XMLContentLoader" init-method="load"/>
-  
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 600b6d0..d54dbca 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import static org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl.LOG;
-
 import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.commons.collections4.CollectionUtils;
@@ -34,7 +32,7 @@ import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -129,7 +127,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
     }
 
     @Override
-    public Response bulkDeassociation(
+    public Response deassociate(
             final Long key, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
 
         TO any = getAnyLogic().read(key);
@@ -174,8 +172,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
     }
 
     @Override
-    public Response bulkAssociation(
-            final Long key, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
+    public Response associate(
+            final Long key, final ResourceAssociationAction type, final ResourceAssociationMod associationMod) {
 
         TO any = getAnyLogic().read(key);
 
@@ -211,7 +209,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
 
         BulkActionResult result = new BulkActionResult();
 
-        if (type == ResourceAssociationActionType.LINK) {
+        if (type == ResourceAssociationAction.LINK) {
             for (ResourceKey resourceName : associationMod.getTargetResources()) {
                 result.getResults().put(resourceName.getElement(),
                         updated.getResources().contains(resourceName.getElement())
@@ -234,7 +232,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
 
         BulkActionResult result = new BulkActionResult();
 
-        switch (bulkAction.getOperation()) {
+        switch (bulkAction.getType()) {
             case DELETE:
                 for (String key : bulkAction.getTargets()) {
                     try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index 6725bf9..bc43165 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -132,7 +132,7 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     public BulkActionResult bulk(final BulkAction bulkAction) {
         BulkActionResult result = new BulkActionResult();
 
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
+        if (bulkAction.getType() == BulkAction.Type.DELETE) {
             for (String key : bulkAction.getTargets()) {
                 try {
                     result.getResults().put(

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
index ae7c426..179e021 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -144,7 +144,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     public BulkActionResult bulk(final BulkAction bulkAction) {
         BulkActionResult result = new BulkActionResult();
 
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
+        if (bulkAction.getType() == BulkAction.Type.DELETE) {
             for (String name : bulkAction.getTargets()) {
                 try {
                     result.getResults().put(logic.delete(name).getKey(), BulkActionResult.Status.SUCCESS);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 5fb19e2..3acf5c8 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -124,7 +124,7 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     public BulkActionResult bulk(final BulkAction bulkAction) {
         BulkActionResult result = new BulkActionResult();
 
-        switch (bulkAction.getOperation()) {
+        switch (bulkAction.getType()) {
             case DELETE:
                 for (String key : bulkAction.getTargets()) {
                     try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
index 6108b2b..494a03e 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
@@ -24,15 +24,17 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
+import java.util.Map;
 import javax.annotation.Resource;
 import org.activiti.editor.constants.ModelDataJsonConstants;
-import org.activiti.engine.RepositoryService;
+import org.activiti.engine.ProcessEngine;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.activiti.spring.SpringProcessEngineConfiguration;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,13 +49,7 @@ public class ActivitiDefinitionLoader implements SyncopeLoader {
     private ResourceWithFallbackLoader userWorkflowDef;
 
     @Autowired
-    private RepositoryService repositoryService;
-
-    @Autowired
-    private SpringProcessEngineConfiguration conf;
-
-    @Autowired
-    private ActivitiImportUtils importUtils;
+    private DomainProcessEngine dpEngine;
 
     @Override
     public Integer getPriority() {
@@ -62,22 +58,34 @@ public class ActivitiDefinitionLoader implements SyncopeLoader {
 
     @Override
     public void load() {
-        List<ProcessDefinition> processes = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                ActivitiUserWorkflowAdapter.WF_PROCESS_ID).list();
-        LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes);
+        byte[] wfDef = new byte[0];
 
-        // Only loads process definition from file if not found in repository
-        if (processes.isEmpty()) {
-            InputStream wfIn = null;
-            try {
-                wfIn = userWorkflowDef.getResource().getInputStream();
-                repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
-                        new ByteArrayInputStream(IOUtils.toByteArray(wfIn))).deploy();
+        InputStream wfIn = null;
+        try {
+            wfIn = userWorkflowDef.getResource().getInputStream();
+            wfDef = IOUtils.toByteArray(wfIn);
+        } catch (IOException e) {
+            LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+        } finally {
+            IOUtils.closeQuietly(wfIn);
+        }
 
-                ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionKey(
-                        ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
+        for (Map.Entry<String, ProcessEngine> entry : dpEngine.getEngines().entrySet()) {
+            List<ProcessDefinition> processes = entry.getValue().getRepositoryService().
+                    createProcessDefinitionQuery().processDefinitionKey(ActivitiUserWorkflowAdapter.WF_PROCESS_ID).
+                    list();
+            LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes);
 
-                Model model = repositoryService.newModel();
+            // Only loads process definition from file if not found in repository
+            if (processes.isEmpty()) {
+                entry.getValue().getRepositoryService().createDeployment().addInputStream(
+                        ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, new ByteArrayInputStream(wfDef)).deploy();
+
+                ProcessDefinition procDef = entry.getValue().getRepositoryService().createProcessDefinitionQuery().
+                        processDefinitionKey(ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().
+                        singleResult();
+
+                Model model = entry.getValue().getRepositoryService().newModel();
                 ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
                 modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, procDef.getName());
                 modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
@@ -85,19 +93,16 @@ public class ActivitiDefinitionLoader implements SyncopeLoader {
                 model.setMetaInfo(modelObjectNode.toString());
                 model.setName(procDef.getName());
                 model.setDeploymentId(procDef.getDeploymentId());
-                importUtils.fromJSON(procDef, model);
+                ActivitiImportUtils.fromJSON(entry.getValue(), procDef, model);
 
-                LOG.debug("Activiti Workflow definition loaded");
-            } catch (IOException e) {
-                LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
-            } finally {
-                IOUtils.closeQuietly(wfIn);
+                LOG.debug("Activiti Workflow definition loaded for domain {}", entry.getKey());
             }
-        }
 
-        // jump to the next ID block
-        for (int i = 0; i < conf.getIdBlockSize(); i++) {
-            conf.getIdGenerator().getNextId();
+            // jump to the next ID block
+            for (int i = 0; i < entry.getValue().getProcessEngineConfiguration().getIdBlockSize(); i++) {
+                SpringProcessEngineConfiguration.class.cast(entry.getValue().getProcessEngineConfiguration()).
+                        getIdGenerator().getNextId();
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
index 973584d..5df8ac4 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java
@@ -28,53 +28,50 @@ import org.activiti.bpmn.converter.BpmnXMLConverter;
 import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.editor.language.json.converter.BpmnJsonConverter;
 import org.activiti.engine.ActivitiException;
-import org.activiti.engine.RepositoryService;
+import org.activiti.engine.ProcessEngine;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.core.workflow.api.WorkflowException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
-@Component
-public class ActivitiImportUtils {
+public final class ActivitiImportUtils {
 
-    @Autowired
-    private RepositoryService repositoryService;
-
-    public void fromXML(final byte[] definition) {
+    public static void fromXML(final ProcessEngine engine, final byte[] definition) {
         try {
-            repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
-                    new ByteArrayInputStream(definition)).deploy();
+            engine.getRepositoryService().createDeployment().
+                    addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE,
+                            new ByteArrayInputStream(definition)).deploy();
         } catch (ActivitiException e) {
             throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
         }
     }
 
-    public void fromJSON(final byte[] definition, final ProcessDefinition procDef, final Model model) {
+    public static void fromJSON(
+            final ProcessEngine engine, final byte[] definition, final ProcessDefinition procDef, final Model model) {
+
         try {
             model.setVersion(procDef.getVersion());
             model.setDeploymentId(procDef.getDeploymentId());
-            repositoryService.saveModel(model);
+            engine.getRepositoryService().saveModel(model);
 
-            repositoryService.addModelEditorSource(model.getId(), definition);
+            engine.getRepositoryService().addModelEditorSource(model.getId(), definition);
         } catch (Exception e) {
             throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
         }
     }
 
-    public void fromJSON(final ProcessDefinition procDef, final Model model) {
+    public static void fromJSON(final ProcessEngine engine, final ProcessDefinition procDef, final Model model) {
         InputStream bpmnStream = null;
         InputStreamReader isr = null;
         XMLStreamReader xtr = null;
         try {
-            bpmnStream = repositoryService.getResourceAsStream(
+            bpmnStream = engine.getRepositoryService().getResourceAsStream(
                     procDef.getDeploymentId(), procDef.getResourceName());
             isr = new InputStreamReader(bpmnStream);
             xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr);
             BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
 
-            fromJSON(new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model);
+            fromJSON(engine, new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model);
         } catch (Exception e) {
             throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
         } finally {
@@ -89,4 +86,8 @@ public class ActivitiImportUtils {
             IOUtils.closeQuietly(bpmnStream);
         }
     }
+
+    private ActivitiImportUtils() {
+        // private constructor for static utility class
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index c124c05..1ce0d97 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -38,11 +38,7 @@ import org.activiti.bpmn.model.BpmnModel;
 import org.activiti.editor.constants.ModelDataJsonConstants;
 import org.activiti.editor.language.json.converter.BpmnJsonConverter;
 import org.activiti.engine.ActivitiException;
-import org.activiti.engine.FormService;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.TaskService;
+import org.activiti.engine.ProcessEngine;
 import org.activiti.engine.form.FormProperty;
 import org.activiti.engine.form.FormType;
 import org.activiti.engine.form.TaskFormData;
@@ -136,22 +132,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected String adminUser;
 
     @Autowired
-    protected RuntimeService runtimeService;
-
-    @Autowired
-    protected TaskService taskService;
-
-    @Autowired
-    protected FormService formService;
-
-    @Autowired
-    protected HistoryService historyService;
-
-    @Autowired
-    protected RepositoryService repositoryService;
-
-    @Autowired
-    protected ActivitiImportUtils importUtils;
+    protected ProcessEngine engine;
 
     @Autowired
     protected UserDataBinder userDataBinder;
@@ -176,7 +157,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     }
 
     protected void updateStatus(final User user) {
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
         if (tasks.isEmpty() || tasks.size() > 1) {
             LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
         } else {
@@ -187,12 +168,12 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected String getFormTask(final User user) {
         String result = null;
 
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
         if (tasks.isEmpty() || tasks.size() > 1) {
             LOG.warn("While checking if form task: unexpected task number ({})", tasks.size());
         } else {
             try {
-                TaskFormData formData = formService.getTaskFormData(tasks.get(0).getId());
+                TaskFormData formData = engine.getFormService().getTaskFormData(tasks.get(0).getId());
                 if (formData != null && !formData.getFormProperties().isEmpty()) {
                     result = tasks.get(0).getId();
                 }
@@ -207,8 +188,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected Set<String> getPerformedTasks(final User user) {
         final Set<String> result = new HashSet<>();
 
-        for (HistoricActivityInstance task
-                : historyService.createHistoricActivityInstanceQuery().executionId(user.getWorkflowId()).list()) {
+        for (HistoricActivityInstance task : engine.getHistoryService().createHistoricActivityInstanceQuery().
+                executionId(user.getWorkflowId()).list()) {
 
             result.add(task.getActivityId());
         }
@@ -223,14 +204,14 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         String formTaskId = getFormTask(user);
         if (formTaskId != null) {
             // SYNCOPE-238: This is needed to simplify the task query in this.getForms()
-            taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
-            runtimeService.setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
+            engine.getTaskService().setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
+            engine.getRuntimeService().setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
             if (propByRes != null) {
                 propByRes.clear();
             }
 
             if (StringUtils.isNotBlank(password)) {
-                runtimeService.setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
+                engine.getRuntimeService().setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
             }
         }
     }
@@ -259,15 +240,15 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         ProcessInstance processInstance = null;
         try {
-            processInstance = runtimeService.startProcessInstanceByKey(WF_PROCESS_ID, variables);
+            processInstance = engine.getRuntimeService().startProcessInstanceByKey(WF_PROCESS_ID, variables);
         } catch (ActivitiException e) {
             throwException(e, "While starting " + WF_PROCESS_ID + " instance");
         }
 
-        User user = runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
+        User user = engine.getRuntimeService().getVariable(processInstance.getProcessInstanceId(), USER, User.class);
 
         Boolean updatedEnabled =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
+                engine.getRuntimeService().getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
         if (updatedEnabled != null) {
             user.setSuspended(!updatedEnabled);
         }
@@ -280,8 +261,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         updateStatus(user);
         user = userDAO.save(user);
 
-        Boolean propagateEnable =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
+        Boolean propagateEnable = engine.getRuntimeService().getVariable(
+                processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
         if (propagateEnable == null) {
             propagateEnable = enabled;
         }
@@ -315,10 +296,10 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             throw new WorkflowException(new NotFoundException("Empty workflow id for " + user));
         }
 
-        List<Task> tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+        List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
         if (tasks.size() == 1) {
             try {
-                taskService.complete(tasks.get(0).getId(), variables);
+                engine.getTaskService().complete(tasks.get(0).getId(), variables);
             } catch (ActivitiException e) {
                 throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user);
             }
@@ -349,14 +330,15 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         updateStatus(user);
         User updated = userDAO.save(user);
 
-        PropagationByResource propByRes =
-                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
-        UserMod updatedMod =
-                runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
+        PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+        UserMod updatedMod = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), USER_MOD, UserMod.class);
 
         saveForFormSubmit(updated, updatedMod.getPassword(), propByRes);
 
-        Boolean propagateEnable = runtimeService.getVariable(user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
+        Boolean propagateEnable = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
 
         return new WorkflowResult<Pair<UserMod, Boolean>>(
                 new ImmutablePair<>(updatedMod, propagateEnable), propByRes, tasks);
@@ -413,15 +395,15 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         saveForFormSubmit(user, null, propByRes);
 
-        if (runtimeService.createProcessInstanceQuery().
+        if (engine.getRuntimeService().createProcessInstanceQuery().
                 processInstanceId(user.getWorkflowId()).active().list().isEmpty()) {
 
             userDAO.delete(user.getKey());
 
-            if (!historyService.createHistoricProcessInstanceQuery().
+            if (!engine.getHistoryService().createHistoricProcessInstanceQuery().
                     processInstanceId(user.getWorkflowId()).list().isEmpty()) {
 
-                historyService.deleteHistoricProcessInstance(user.getWorkflowId());
+                engine.getHistoryService().deleteHistoricProcessInstance(user.getWorkflowId());
             }
         } else {
             updateStatus(user);
@@ -445,7 +427,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     protected ProcessDefinition getProcessDefinition() {
         try {
-            return repositoryService.createProcessDefinitionQuery().processDefinitionKey(
+            return engine.getRepositoryService().createProcessDefinitionQuery().processDefinitionKey(
                     ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
@@ -455,7 +437,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     protected Model getModel(final ProcessDefinition procDef) {
         try {
-            Model model = repositoryService.createModelQuery().deploymentId(procDef.getDeploymentId()).singleResult();
+            Model model = engine.getRepositoryService().createModelQuery().
+                    deploymentId(procDef.getDeploymentId()).singleResult();
             if (model == null) {
                 throw new NotFoundException("Could not find Model for deployment " + procDef.getDeploymentId());
             }
@@ -468,7 +451,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected void exportProcessResource(final String resourceName, final OutputStream os) {
         ProcessDefinition procDef = getProcessDefinition();
 
-        InputStream procDefIS = repositoryService.getResourceAsStream(procDef.getDeploymentId(), resourceName);
+        InputStream procDefIS = engine.getRepositoryService().getResourceAsStream(procDef.getDeploymentId(),
+                resourceName);
         try {
             IOUtils.copy(procDefIS, os);
         } catch (IOException e) {
@@ -486,7 +470,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             ObjectNode modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
             modelNode.put(ModelDataJsonConstants.MODEL_ID, model.getId());
             modelNode.replace(MODEL_DATA_JSON_MODEL,
-                    objectMapper.readTree(repositoryService.getModelEditorSource(model.getId())));
+                    objectMapper.readTree(engine.getRepositoryService().getModelEditorSource(model.getId())));
 
             os.write(modelNode.toString().getBytes());
         } catch (IOException e) {
@@ -529,20 +513,21 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                     }
 
                     BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
-                    importUtils.fromXML(new BpmnXMLConverter().convertToXML(bpmnModel));
+                    ActivitiImportUtils.fromXML(engine, new BpmnXMLConverter().convertToXML(bpmnModel));
                 } catch (Exception e) {
                     throw new WorkflowException("While updating process "
                             + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
                 }
 
-                importUtils.fromJSON(definitionNode.toString().getBytes(), getProcessDefinition(), model);
+                ActivitiImportUtils.fromJSON(
+                        engine, definitionNode.toString().getBytes(), getProcessDefinition(), model);
                 break;
 
             case XML:
             default:
-                importUtils.fromXML(definition.getBytes());
+                ActivitiImportUtils.fromXML(engine, definition.getBytes());
 
-                importUtils.fromJSON(getProcessDefinition(), model);
+                ActivitiImportUtils.fromJSON(engine, getProcessDefinition(), model);
         }
     }
 
@@ -569,7 +554,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     }
 
     protected WorkflowFormTO getFormTO(final Task task) {
-        return getFormTO(task, formService.getTaskFormData(task.getId()));
+        return getFormTO(task, engine.getFormService().getTaskFormData(task.getId()));
     }
 
     protected WorkflowFormTO getFormTO(final Task task, final TaskFormData fd) {
@@ -583,7 +568,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected WorkflowFormTO getFormTO(final HistoricTaskInstance task) {
         final List<HistoricFormPropertyEntity> props = new ArrayList<>();
 
-        for (HistoricDetail historicDetail : historyService.createHistoricDetailQuery().taskId(task.getId()).list()) {
+        for (HistoricDetail historicDetail
+                : engine.getHistoryService().createHistoricDetailQuery().taskId(task.getId()).list()) {
 
             if (historicDetail instanceof HistoricFormPropertyEntity) {
                 props.add((HistoricFormPropertyEntity) historicDetail);
@@ -594,7 +580,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 task.getProcessInstanceId(), task.getId(), task.getFormKey(), props);
         BeanUtils.copyProperties(task, formTO);
 
-        final HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().
+        final HistoricActivityInstance historicActivityInstance = engine.getHistoryService().
+                createHistoricActivityInstanceQuery().
                 executionId(task.getExecutionId()).activityType("userTask").activityName(task.getName()).singleResult();
 
         if (historicActivityInstance != null) {
@@ -676,7 +663,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         final String authUser = AuthContextUtils.getUsername();
         if (adminUser.equals(authUser)) {
-            forms.addAll(getForms(taskService.createTaskQuery().
+            forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                     taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
         } else {
             User user = userDAO.find(authUser);
@@ -684,7 +671,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 throw new NotFoundException("Syncope User " + authUser);
             }
 
-            forms.addAll(getForms(taskService.createTaskQuery().
+            forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                     taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
                     taskCandidateOrAssigned(user.getKey().toString())));
 
@@ -693,7 +680,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
                 candidateGroups.add(groupId.toString());
             }
             if (!candidateGroups.isEmpty()) {
-                forms.addAll(getForms(taskService.createTaskQuery().
+                forms.addAll(getForms(engine.getTaskService().createTaskQuery().
                         taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
                         taskCandidateGroupIn(candidateGroups)));
             }
@@ -705,10 +692,10 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     @Override
     public List<WorkflowFormTO> getForms(final String workflowId, final String name) {
         List<WorkflowFormTO> forms = getForms(
-                taskService.createTaskQuery().processInstanceId(workflowId).taskName(name).
+                engine.getTaskService().createTaskQuery().processInstanceId(workflowId).taskName(name).
                 taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE));
 
-        forms.addAll(getForms(historyService.createHistoricTaskInstanceQuery().taskName(name).
+        forms.addAll(getForms(engine.getHistoryService().createHistoricTaskInstanceQuery().taskName(name).
                 taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
 
         return forms;
@@ -739,14 +726,14 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     public WorkflowFormTO getForm(final String workflowId) {
         Task task;
         try {
-            task = taskService.createTaskQuery().processInstanceId(workflowId).singleResult();
+            task = engine.getTaskService().createTaskQuery().processInstanceId(workflowId).singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While reading form for workflow instance " + workflowId, e);
         }
 
         TaskFormData formData;
         try {
-            formData = formService.getTaskFormData(task.getId());
+            formData = engine.getFormService().getTaskFormData(task.getId());
         } catch (ActivitiException e) {
             LOG.debug("No form found for task {}", task.getId(), e);
             formData = null;
@@ -763,14 +750,14 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     protected Pair<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
         Task task;
         try {
-            task = taskService.createTaskQuery().taskId(taskId).singleResult();
+            task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
         } catch (ActivitiException e) {
             throw new NotFoundException("Activiti Task " + taskId, e);
         }
 
         TaskFormData formData;
         try {
-            formData = formService.getTaskFormData(task.getId());
+            formData = engine.getFormService().getTaskFormData(task.getId());
         } catch (ActivitiException e) {
             throw new NotFoundException("Form for Activiti Task " + taskId, e);
         }
@@ -792,7 +779,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
 
         if (!adminUser.equals(authUser)) {
-            List<Task> tasksForUser = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(authUser).list();
+            List<Task> tasksForUser = engine.getTaskService().createTaskQuery().taskId(taskId).taskCandidateUser(
+                    authUser).list();
             if (tasksForUser.isEmpty()) {
                 throw new WorkflowException(
                         new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
@@ -801,8 +789,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         Task task;
         try {
-            taskService.setOwner(taskId, authUser);
-            task = taskService.createTaskQuery().taskId(taskId).singleResult();
+            engine.getTaskService().setOwner(taskId, authUser);
+            task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While reading task " + taskId, e);
         }
@@ -828,8 +816,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
         Set<String> preTasks = getPerformedTasks(user);
         try {
-            formService.submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
-            runtimeService.setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
+            engine.getFormService().submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
+            engine.getRuntimeService().setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
         } catch (ActivitiException e) {
             throwException(e, "While submitting form for task " + form.getTaskId());
         }
@@ -842,12 +830,12 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         User updated = userDAO.save(user);
 
         // see if there is any propagation to be done
-        PropagationByResource propByRes =
-                runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+        PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+                user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
 
         // fetch - if available - the encrypted password
         String clearPassword = null;
-        String encryptedPwd = runtimeService.getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
+        String encryptedPwd = engine.getRuntimeService().getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
         if (StringUtils.isNotBlank(encryptedPwd)) {
             clearPassword = decrypt(encryptedPwd);
         }
@@ -855,7 +843,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
         // supports approval chains
         saveForFormSubmit(user, clearPassword, propByRes);
 
-        UserMod userMod = runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
+        UserMod userMod = engine.getRuntimeService().getVariable(user.getWorkflowId(), USER_MOD, UserMod.class);
         if (userMod == null) {
             userMod = new UserMod();
             userMod.setKey(updated.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
new file mode 100644
index 0000000..83619c7
--- /dev/null
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.workflow.activiti.spring;
+
+import java.util.Collections;
+import java.util.Map;
+import org.activiti.engine.FormService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.ManagementService;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.ProcessEngineConfiguration;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+
+/**
+ * {@link ProcessEngine} delegating actual method invocation to the inner map of {@link ProcessEngine} instances,
+ * one for each Syncope domain.
+ */
+public class DomainProcessEngine implements ProcessEngine {
+
+    private final Map<String, ProcessEngine> engines;
+
+    public DomainProcessEngine(final Map<String, ProcessEngine> engines) {
+        this.engines = Collections.synchronizedMap(engines);
+    }
+
+    public Map<String, ProcessEngine> getEngines() {
+        return engines;
+    }
+
+    @Override
+    public String getName() {
+        return engines.get(AuthContextUtils.getDomain()).getName();
+    }
+
+    @Override
+    public void close() {
+        for (ProcessEngine engine : engines.values()) {
+            engine.close();
+        }
+    }
+
+    @Override
+    public RepositoryService getRepositoryService() {
+        return engines.get(AuthContextUtils.getDomain()).getRepositoryService();
+    }
+
+    @Override
+    public RuntimeService getRuntimeService() {
+        return engines.get(AuthContextUtils.getDomain()).getRuntimeService();
+    }
+
+    @Override
+    public FormService getFormService() {
+        return engines.get(AuthContextUtils.getDomain()).getFormService();
+    }
+
+    @Override
+    public TaskService getTaskService() {
+        return engines.get(AuthContextUtils.getDomain()).getTaskService();
+    }
+
+    @Override
+    public HistoryService getHistoryService() {
+        return engines.get(AuthContextUtils.getDomain()).getHistoryService();
+    }
+
+    @Override
+    public IdentityService getIdentityService() {
+        return engines.get(AuthContextUtils.getDomain()).getIdentityService();
+    }
+
+    @Override
+    public ManagementService getManagementService() {
+        return engines.get(AuthContextUtils.getDomain()).getManagementService();
+    }
+
+    @Override
+    public ProcessEngineConfiguration getProcessEngineConfiguration() {
+        return engines.get(AuthContextUtils.getDomain()).getProcessEngineConfiguration();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java
new file mode 100644
index 0000000..cf112bd
--- /dev/null
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngineFactoryBean.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.workflow.activiti.spring;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.DataSource;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.impl.cfg.SpringBeanFactoryProxyMap;
+import org.activiti.spring.SpringExpressionManager;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.transaction.PlatformTransactionManager;
+
+/**
+ * Spring factory for {@link DomainProcessEngine} which takes the provided {@link SpringProcessEngineConfiguration} as
+ * template for each of the configured Syncope domains.
+ */
+public class DomainProcessEngineFactoryBean
+        implements FactoryBean<DomainProcessEngine>, DisposableBean, ApplicationContextAware {
+
+    private ApplicationContext ctx;
+
+    private DomainProcessEngine engine;
+
+    @Override
+    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+        this.ctx = ctx;
+    }
+
+    @Override
+    public DomainProcessEngine getObject() throws Exception {
+        if (engine == null) {
+            Map<String, ProcessEngine> engines = new HashMap<>();
+
+            for (Map.Entry<String, DataSource> entry : ctx.getBeansOfType(DataSource.class).entrySet()) {
+                if (!entry.getKey().startsWith("local")) {
+                    String domain = StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName());
+                    DataSource dataSource = entry.getValue();
+                    PlatformTransactionManager transactionManager = ctx.getBean(
+                            domain + "TransactionManager", PlatformTransactionManager.class);
+                    Object entityManagerFactory = ctx.getBean(domain + "EntityManagerFactory");
+
+                    SpringProcessEngineConfiguration conf = ctx.getBean(SpringProcessEngineConfiguration.class);
+                    conf.setDataSource(dataSource);
+                    conf.setTransactionManager(transactionManager);
+                    conf.setTransactionsExternallyManaged(true);
+                    conf.setJpaEntityManagerFactory(entityManagerFactory);
+                    if (conf.getBeans() == null) {
+                        conf.setBeans(new SpringBeanFactoryProxyMap(ctx));
+                    }
+                    if (conf.getExpressionManager() == null) {
+                        conf.setExpressionManager(new SpringExpressionManager(ctx, conf.getBeans()));
+                    }
+
+                    engines.put(domain, conf.buildProcessEngine());
+                }
+            }
+
+            engine = new DomainProcessEngine(engines);
+        }
+
+        return engine;
+    }
+
+    @Override
+    public Class<DomainProcessEngine> getObjectType() {
+        return DomainProcessEngine.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        if (engine != null) {
+            engine.close();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
index 85a0ac0..ff898ad 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AbstractActivitiServiceTask.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.workflow.activiti.task;
 
-import org.activiti.engine.RuntimeService;
+import org.activiti.engine.ProcessEngine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,13 +31,10 @@ import org.springframework.transaction.annotation.Transactional;
 @Component
 public abstract class AbstractActivitiServiceTask {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractActivitiServiceTask.class);
 
     @Autowired
-    protected RuntimeService runtimeService;
+    protected ProcessEngine engine;
 
     @Transactional(rollbackFor = { Throwable.class })
     public void execute(final String executionId) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
index 370e6e3..51dfb50 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/AutoActivate.java
@@ -26,6 +26,6 @@ public class AutoActivate extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
index adf36ad..e911f98 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Create.java
@@ -37,15 +37,17 @@ public class Create extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
+        UserTO userTO = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
         Boolean storePassword =
-                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.STORE_PASSWORD, Boolean.class);
+                engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.STORE_PASSWORD, Boolean.class);
         // create and set workflow id
         User user = entityFactory.newEntity(User.class);
         dataBinder.create(user, userTO, storePassword == null ? true : storePassword);
         user.setWorkflowId(executionId);
 
         // report user as result
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
index d386388..7933751 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Delete.java
@@ -27,7 +27,8 @@ public class Delete extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
 
         // Do something with user...
         if (user != null) {
@@ -35,6 +36,6 @@ public class Delete extends AbstractActivitiServiceTask {
         }
 
         // remove user variable
-        runtimeService.removeVariable(executionId, ActivitiUserWorkflowAdapter.USER);
+        engine.getRuntimeService().removeVariable(executionId, ActivitiUserWorkflowAdapter.USER);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
index dcbcfd0..9ce6941 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/GenerateToken.java
@@ -32,12 +32,13 @@ public class GenerateToken extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
 
         user.generateToken(
                 confDAO.find("token.length", "256").getValues().get(0).getLongValue().intValue(),
                 confDAO.find("token.expireTime", "60").getValues().get(0).getLongValue().intValue());
 
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
index 3c886fe..54e7852 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Notify.java
@@ -40,9 +40,12 @@ public class Notify extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
-        UserTO userTO = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
-        String event = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT, String.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        UserTO userTO = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO, UserTO.class);
+        String event = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT, String.class);
 
         if (StringUtils.isNotBlank(event)) {
             notificationManager.createTasks(

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
index 2fc8097..10e9afe 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/PasswordReset.java
@@ -28,9 +28,12 @@ public class PasswordReset extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
-        String token = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN, String.class);
-        String password = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD, String.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        String token = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN, String.class);
+        String password = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD, String.class);
 
         if (!user.checkToken(token)) {
             throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user));
@@ -38,7 +41,7 @@ public class PasswordReset extends AbstractActivitiServiceTask {
 
         user.removeToken();
         user.setPassword(password, user.getCipherAlgorithm());
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
index 4da56c6..e4ee649 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/task/Update.java
@@ -35,9 +35,11 @@ public class Update extends AbstractActivitiServiceTask {
 
     @Override
     protected void doExecute(final String executionId) {
-        User user = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
+        User user = engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER, User.class);
         UserMod userMod =
-                runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class);
+                engine.getRuntimeService().
+                getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class);
 
         // update password internally only if required
         UserMod updatedMod = SerializationUtils.clone(userMod);
@@ -50,8 +52,8 @@ public class Update extends AbstractActivitiServiceTask {
         updatedMod.setPassword(updatedPwd);
 
         // report updated user and propagation by resource as result
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, updatedMod);
-        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER, user);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, updatedMod);
+        engine.getRuntimeService().setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
index 75f0c38..81058e1 100644
--- a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -35,13 +35,10 @@ under the License.
   <bean id="syncopeActivitiUserManager" class="org.apache.syncope.core.workflow.activiti.SyncopeUserManager"/>
   <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.core.workflow.activiti.SyncopeGroupManager"/>
 
-  <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
-    <property name="dataSource" ref="dataSource"/>
-    <property name="transactionManager" ref="transactionManager"/>
+  <bean class="org.activiti.spring.SpringProcessEngineConfiguration" scope="prototype">
     <property name="transactionsExternallyManaged" value="true"/>
     <property name="databaseSchemaUpdate" value="true"/>
 
-    <property name="jpaEntityManagerFactory" ref="entityManagerFactory"/>
     <property name="jpaHandleTransaction" value="true"/>
     <property name="jpaCloseEntityManager" value="false"/>
 
@@ -64,17 +61,7 @@ under the License.
     </property>
   </bean>
 
-  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
-    <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
-  </bean>
-
-  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
-  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
-  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
-  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
-  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/>
-  <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
-  <bean id="formService" factory-bean="processEngine" factory-method="getFormService"/>
+  <bean class="org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngineFactoryBean"/>
 
   <context:component-scan base-package="org.apache.syncope.core.workflow.activiti"/>
     

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
index 0d7c86a..fbf29c3 100644
--- a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
+++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java
@@ -90,15 +90,15 @@ public interface UserWorkflowAdapter extends WorkflowAdapter {
     /**
      * Suspend an user.
      *
-     * @param userKey user to be suspended
+     * @param key to be suspended
      * @return user just suspended
      */
-    WorkflowResult<Long> suspend(Long userKey);
+    WorkflowResult<Long> suspend(Long key);
 
     /**
      * Suspend an user.
      *
-     * @param user to be suspended
+     * @param user user to be suspended
      * @return user just suspended
      */
     WorkflowResult<Long> suspend(User user);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
index ef15ab0..3f0d61a 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
@@ -26,9 +26,10 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractAnyObjectWorkflowAdapter implements AnyObjectWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
index 97a8b1f..2b921ce 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractGroupWorkflowAdapter.java
@@ -26,9 +26,10 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractGroupWorkflowAdapter implements GroupWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
index fc75987..ecc1c01 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractUserWorkflowAdapter.java
@@ -29,9 +29,10 @@ import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.identityconnectors.common.Base64;
 import org.identityconnectors.common.security.EncryptorFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { Throwable.class })
 public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
index 78360a9..3d56daf 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
@@ -35,12 +35,10 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Simple implementation basically not involving any workflow engine.
  */
-@Transactional(rollbackFor = { Throwable.class })
 public class DefaultUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
     @Autowired

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index 4359e7b..97bb299 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import javax.sql.DataSource;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
 import org.apache.syncope.core.persistence.api.SyncopeLoader;
 import org.apache.syncope.core.persistence.api.entity.CamelEntityFactory;
 import org.apache.syncope.core.persistence.api.entity.CamelRoute;
@@ -60,7 +61,7 @@ public class CamelRouteLoader implements SyncopeLoader {
     private ResourceWithFallbackLoader anyObjectRoutesLoader;
 
     @Autowired
-    private DataSource dataSource;
+    private DomainsHolder domainsHolder;
 
     @Autowired
     private CamelEntityFactory entityFactory;
@@ -77,15 +78,20 @@ public class CamelRouteLoader implements SyncopeLoader {
     public void load() {
         synchronized (this) {
             if (!loaded) {
-                loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER);
-                loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
-                loadRoutes(anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
+                for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+                    loadRoutes(entry.getKey(), entry.getValue(),
+                            userRoutesLoader.getResource(), AnyTypeKind.USER);
+                    loadRoutes(entry.getKey(), entry.getValue(),
+                            groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
+                    loadRoutes(entry.getKey(), entry.getValue(),
+                            anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
+                }
                 loaded = true;
             }
         }
     }
 
-    private boolean loadRoutesFor(final AnyTypeKind anyTypeKind) {
+    private boolean loadRoutesFor(final DataSource dataSource, final AnyTypeKind anyTypeKind) {
         final String sql = String.format("SELECT * FROM %s WHERE ANYTYPEKIND = ?", CamelRoute.class.getSimpleName());
         final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
         final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { anyTypeKind.name() });
@@ -106,8 +112,10 @@ public class CamelRouteLoader implements SyncopeLoader {
         return writer.toString();
     }
 
-    private void loadRoutes(final Resource resource, final AnyTypeKind anyTypeKind) {
-        if (loadRoutesFor(anyTypeKind)) {
+    private void loadRoutes(
+            final String domain, final DataSource dataSource, final Resource resource, final AnyTypeKind anyTypeKind) {
+
+        if (loadRoutesFor(dataSource, anyTypeKind)) {
             String query = String.format("INSERT INTO %s(NAME, ANYTYPEKIND, CONTENT) VALUES (?, ?, ?)",
                     CamelRoute.class.getSimpleName());
             JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
@@ -132,12 +140,12 @@ public class CamelRouteLoader implements SyncopeLoader {
                     route.setContent(routeContent);
 
                     jdbcTemplate.update(query, new Object[] { routeId, anyTypeKind.name(), routeContent });
-                    LOG.info("Route successfully loaded: {}", routeId);
+                    LOG.info("[{}] Route successfully loaded: {}", domain, routeId);
                 }
             } catch (DataAccessException e) {
-                LOG.error("While trying to store queries {}", e);
+                LOG.error("[{}] While trying to store queries", domain, e);
             } catch (Exception e) {
-                LOG.error("Route load failed {}", e.getMessage());
+                LOG.error("[{}] Route load failed {}", domain, e.getMessage());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
----------------------------------------------------------------------
diff --git a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
index e9f2c72..8894992 100644
--- a/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
+++ b/ext/camel/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPACamelRouteDAO.java
@@ -32,13 +32,13 @@ public class JPACamelRouteDAO extends AbstractDAO<CamelRoute, String> implements
 
     @Override
     public CamelRoute find(final String key) {
-        return entityManager.find(JPACamelRoute.class, key);
+        return entityManager().find(JPACamelRoute.class, key);
     }
 
     @Transactional(readOnly = true)
     @Override
     public List<CamelRoute> find(final AnyTypeKind anyTypeKind) {
-        TypedQuery<CamelRoute> query = entityManager.createQuery(
+        TypedQuery<CamelRoute> query = entityManager().createQuery(
                 "SELECT e FROM " + JPACamelRoute.class.getSimpleName()
                 + " e WHERE e.anyTypeKind = :anyTypeKind", CamelRoute.class);
         query.setParameter("anyTypeKind", anyTypeKind);
@@ -49,21 +49,21 @@ public class JPACamelRouteDAO extends AbstractDAO<CamelRoute, String> implements
     @Transactional(readOnly = true)
     @Override
     public List<CamelRoute> findAll() {
-        TypedQuery<CamelRoute> query = entityManager.createQuery(
+        TypedQuery<CamelRoute> query = entityManager().createQuery(
                 "SELECT e FROM " + JPACamelRoute.class.getSimpleName() + " e ", CamelRoute.class);
         return query.getResultList();
     }
 
     @Override
     public CamelRoute save(final CamelRoute route) {
-        return entityManager.merge(route);
+        return entityManager().merge(route);
     }
 
     @Override
     public void delete(final String key) {
         CamelRoute route = find(key);
         if (route != null) {
-            entityManager.remove(route);
+            entityManager().remove(route);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
index ae29501..bb01cd3 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
@@ -143,6 +143,25 @@ public class CamelAnyObjectProvisioningManager
 
     @Override
     @SuppressWarnings("unchecked")
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:provisionAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("resources", resources);
+
+        sendMessage("direct:provisionAnyObject", key, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
     public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deprovisionAnyObjectPort");
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
index f97203a..bc0c854 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
@@ -163,13 +163,32 @@ public class CamelGroupProvisioningManager
 
     @Override
     @SuppressWarnings("unchecked")
-    public List<PropagationStatus> deprovision(final Long groupKey, final Collection<String> resources) {
+    public List<PropagationStatus> provision(final Long key, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:provisionGroupPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("resources", resources);
+
+        sendMessage("direct:provisionGroup", key, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+    
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<PropagationStatus> deprovision(final Long key, final Collection<String> resources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deprovisionGroupPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("resources", resources);
 
-        sendMessage("direct:deprovisionGroup", groupKey, props);
+        sendMessage("direct:deprovisionGroup", key, props);
 
         Exchange exchange = pollingConsumer.receive();
 


[05/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java
deleted file mode 100644
index 728ab41..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTaskJob.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.java.job;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicReference;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.task.Task;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.DataFormat;
-import org.apache.syncope.core.misc.ExceptionUtils2;
-import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-import org.quartz.UnableToInterruptJobException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Abstract job implementation that delegates to concrete implementation the actual job execution and provides some
- * base features.
- * <strong>Extending this class will not provide support transaction management.</strong><br/>
- * Extend <tt>AbstractTransactionalTaskJob</tt> for this purpose.
- *
- * @see AbstractTransactionalTaskJob
- */
-@DisallowConcurrentExecution
-public abstract class AbstractTaskJob implements TaskJob {
-
-    /**
-     * Task execution status.
-     */
-    public enum Status {
-
-        SUCCESS,
-        FAILURE
-
-    }
-
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractTaskJob.class);
-
-    /**
-     * Task DAO.
-     */
-    @Autowired
-    protected TaskDAO taskDAO;
-
-    /**
-     * Task execution DAO.
-     */
-    @Autowired
-    private TaskExecDAO taskExecDAO;
-
-    /**
-     * Configuration DAO.
-     */
-    @Autowired
-    private ConfDAO confDAO;
-
-    /**
-     * Notification manager.
-     */
-    @Autowired
-    private NotificationManager notificationManager;
-
-    /**
-     * Audit manager.
-     */
-    @Autowired
-    private AuditManager auditManager;
-
-    @Autowired
-    private EntityFactory entityFactory;
-
-    /**
-     * Id, set by the caller, for identifying the task to be executed.
-     */
-    protected Long taskId;
-
-    /**
-     * The actual task to be executed.
-     */
-    protected Task task;
-
-    /**
-     * The current running thread containing the task to be executed.
-     */
-    protected AtomicReference<Thread> runningThread = new AtomicReference<Thread>();
-
-    /**
-     * Task id setter.
-     *
-     * @param taskId to be set
-     */
-    @Override
-    public void setTaskId(final Long taskId) {
-        this.taskId = taskId;
-    }
-
-    @Override
-    public void execute(final JobExecutionContext context) throws JobExecutionException {
-        this.runningThread.set(Thread.currentThread());
-        task = taskDAO.find(taskId);
-        if (task == null) {
-            throw new JobExecutionException("Task " + taskId + " not found");
-        }
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setStartDate(new Date());
-        execution.setTask(task);
-
-        Result result;
-
-        try {
-            execution.setMessage(doExecute(context.getMergedJobDataMap().getBoolean(DRY_RUN_JOBDETAIL_KEY)));
-            execution.setStatus(Status.SUCCESS.name());
-            result = Result.SUCCESS;
-        } catch (JobExecutionException e) {
-            LOG.error("While executing task " + taskId, e);
-            result = Result.FAILURE;
-
-            execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
-            execution.setStatus(Status.FAILURE.name());
-        }
-        execution.setEndDate(new Date());
-
-        if (hasToBeRegistered(execution)) {
-            taskExecDAO.saveAndAdd(taskId, execution);
-        }
-        task = taskDAO.save(task);
-
-        notificationManager.createTasks(
-                AuditElements.EventCategoryType.TASK,
-                this.getClass().getSimpleName(),
-                null,
-                this.getClass().getSimpleName(), // searching for before object is too much expensive ...
-                result,
-                task,
-                execution);
-
-        auditManager.audit(
-                AuditElements.EventCategoryType.TASK,
-                task.getClass().getSimpleName(),
-                null,
-                null, // searching for before object is too much expensive ...
-                result,
-                task,
-                (Object[]) null);
-    }
-
-    /**
-     * The actual execution, delegated to child classes.
-     *
-     * @param dryRun whether to actually touch the data
-     * @return the task execution status to be set
-     * @throws JobExecutionException if anything goes wrong
-     */
-    protected abstract String doExecute(boolean dryRun) throws JobExecutionException;
-
-    /**
-     * Template method to determine whether this job's task execution has to be persisted or not.
-     *
-     * @param execution task execution
-     * @return wether to persist or not
-     */
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        return false;
-    }
-
-    @Override
-    public void interrupt() throws UnableToInterruptJobException {
-        Thread thread = this.runningThread.getAndSet(null);
-        if (thread == null) {
-            LOG.warn("Unable to retrieve the thread of the current job execution");
-        } else {
-            LOG.info("Interrupting job from thread {} at {} ", thread.getId(), DataFormat.format(new Date()));
-
-            long maxRetry = confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue();
-            for (int i = 0; i < maxRetry && thread.isAlive(); i++) {
-                thread.interrupt();
-            }
-            // if the thread is still alive, it should be available in the next stop
-            if (thread.isAlive()) {
-                this.runningThread.set(thread);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java
deleted file mode 100644
index b90c142..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractTransactionalTaskJob.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.java.job;
-
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Abstract job implementation for transactional execution.
- */
-public abstract class AbstractTransactionalTaskJob extends AbstractTaskJob {
-
-    @Transactional
-    @Override
-    public void execute(final JobExecutionContext context) throws JobExecutionException {
-        super.execute(context);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java
deleted file mode 100644
index e031905..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SampleJob.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.java.job;
-
-import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.quartz.JobExecutionException;
-
-/**
- * Sample implementation for execution a scheduled task.
- *
- * @see SchedTask
- */
-public class SampleJob extends AbstractTaskJob {
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        if (!(task instanceof SchedTask)) {
-            throw new JobExecutionException("Task " + taskId + " isn't a SchedTask");
-        }
-        final SchedTask schedTask = (SchedTask) this.task;
-
-        LOG.info("SampleJob {}running [SchedTask {}]", (dryRun
-                ? "dry "
-                : ""), schedTask.getKey());
-
-        return (dryRun
-                ? "DRY "
-                : "") + "RUNNING";
-    }
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
index fc3938e..925c6e6 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SpringBeanJobFactory.java
@@ -26,6 +26,10 @@ import org.springframework.beans.PropertyAccessorFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ConfigurableApplicationContext;
 
+/**
+ * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
+ * transactions work.
+ */
 public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.SpringBeanJobFactory {
 
     private String[] ignoredUnknownProperties;
@@ -33,7 +37,7 @@ public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.
     private SchedulerContext schedulerContext;
 
     @Override
-    public void setIgnoredUnknownProperties(final String[] ignoredUnknownProperties) {
+    public void setIgnoredUnknownProperties(final String... ignoredUnknownProperties) {
         String[] defensiveCopy = ignoredUnknownProperties.clone();
         super.setIgnoredUnknownProperties(defensiveCopy);
         this.ignoredUnknownProperties = defensiveCopy;
@@ -45,12 +49,6 @@ public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.
         this.schedulerContext = schedulerContext;
     }
 
-    /**
-     * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
-     * transactions work.
-     *
-     * {@inheritDoc}
-     */
     @Override
     protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
         final ApplicationContext ctx = ((ConfigurableApplicationContext) schedulerContext.get("applicationContext"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
new file mode 100644
index 0000000..2001e22
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.java.job;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.syncope.core.misc.DataFormat;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.InterruptableJob;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.UnableToInterruptJobException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+@DisallowConcurrentExecution
+public class TaskJob implements InterruptableJob {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TaskJob.class);
+
+    public static final String DRY_RUN_JOBDETAIL_KEY = "dryRun";
+
+    public static final String DELEGATE_CLASS_KEY = "delegateClass";
+
+    public static final String INTERRUPT_MAX_RETRIES_KEY = "interruptMaxRetries";
+
+    /**
+     * Task execution status.
+     */
+    public enum Status {
+
+        SUCCESS,
+        FAILURE
+
+    }
+
+    /**
+     * The current running thread containing the task to be executed.
+     */
+    private final AtomicReference<Thread> runningThread = new AtomicReference<>();
+
+    /**
+     * Key, set by the caller, for identifying the task to be executed.
+     */
+    private Long taskKey;
+
+    private long interruptMaxRetries = 1;
+
+    /**
+     * Task key setter.
+     *
+     * @param taskKey to be set
+     */
+    public void setTaskKey(final Long taskKey) {
+        this.taskKey = taskKey;
+    }
+
+    @Override
+    public void execute(final JobExecutionContext context) throws JobExecutionException {
+        this.runningThread.set(Thread.currentThread());
+        this.interruptMaxRetries = context.getMergedJobDataMap().getLong(INTERRUPT_MAX_RETRIES_KEY);
+
+        AuthContextUtils.setFakeAuth(context.getMergedJobDataMap().getString(JobInstanceLoader.DOMAIN));
+        try {
+            Class<?> delegateClass = ClassUtils.getClass(context.getMergedJobDataMap().getString(DELEGATE_CLASS_KEY));
+
+            ((SchedTaskJobDelegate) ApplicationContextProvider.getBeanFactory().
+                    createBean(delegateClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false)).
+                    execute(taskKey, context.getMergedJobDataMap().getBoolean(DRY_RUN_JOBDETAIL_KEY));
+        } catch (Exception e) {
+            throw new JobExecutionException(e);
+        } finally {
+            AuthContextUtils.clearFakeAuth();
+        }
+    }
+
+    @Override
+    public void interrupt() throws UnableToInterruptJobException {
+        Thread thread = this.runningThread.getAndSet(null);
+        if (thread == null) {
+            LOG.warn("Unable to retrieve the thread of the current job execution");
+        } else {
+            LOG.info("Interrupting job from thread {} at {} ", thread.getId(), DataFormat.format(new Date()));
+
+            if (interruptMaxRetries < 1) {
+                interruptMaxRetries = 1;
+            }
+            for (int i = 0; i < interruptMaxRetries && thread.isAlive(); i++) {
+                thread.interrupt();
+            }
+            // if the thread is still alive, it should be available in the next stop
+            if (thread.isAlive()) {
+                this.runningThread.set(thread);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index a73f5b9..1c704df 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -195,11 +195,11 @@ public class PropagationManagerImpl implements PropagationManager {
     }
 
     @Override
-    public List<PropagationTask> getUserUpdateTasks(final User user, final Boolean enable,
+    public List<PropagationTask> getUserUpdateTasks(final Long key, final Boolean enable,
             final Collection<String> noPropResourceNames) {
 
         return getUpdateTasks(
-                user, // user to be updated on external resources
+                userDAO.find(key), // user to be updated on external resources
                 null, // no password
                 false,
                 enable, // status to be propagated
@@ -236,7 +236,7 @@ public class PropagationManagerImpl implements PropagationManager {
         } else {
             // b. generate the propagation task list in two phases: first the ones containing password,
             // the the rest (with no password)
-            final PropagationByResource origPropByRes = new PropagationByResource();
+            PropagationByResource origPropByRes = new PropagationByResource();
             origPropByRes.merge(wfResult.getPropByRes());
 
             Set<String> pwdResourceNames = new HashSet<>(userMod.getPwdPropRequest().getResourceNames());

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
deleted file mode 100644
index 34ca299..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJob.java
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.java.sync;
-
-import static org.apache.syncope.common.lib.types.AnyTypeKind.USER;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Resource;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
-import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
-import org.apache.syncope.core.provisioning.java.job.AbstractTaskJob;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-
-/**
- * Job for executing synchronization tasks.
- *
- * @see AbstractTaskJob
- * @see org.apache.syncope.core.persistence.api.entity.task.SyncTask
- * @see org.apache.syncope.core.persistence.api.entity.task.PushTask
- */
-public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions>
-        extends AbstractTaskJob {
-
-    @Resource(name = "adminUser")
-    protected String adminUser;
-
-    /**
-     * ConnInstance loader.
-     */
-    @Autowired
-    protected ConnectorFactory connFactory;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
-
-    /**
-     * Resource DAO.
-     */
-    @Autowired
-    protected ExternalResourceDAO resourceDAO;
-
-    /**
-     * Policy DAO.
-     */
-    @Autowired
-    protected PolicyDAO policyDAO;
-
-    /**
-     * SyncJob actions.
-     */
-    protected List<A> actions;
-
-    public void setActions(final List<A> actions) {
-        this.actions = actions;
-    }
-
-    /**
-     * Create a textual report of the synchronization, based on the trace level.
-     *
-     * @param provResults Sync results
-     * @param syncTraceLevel Sync trace level
-     * @param dryRun dry run?
-     * @return report as string
-     */
-    protected String createReport(final Collection<ProvisioningResult> provResults, final TraceLevel syncTraceLevel,
-            final boolean dryRun) {
-
-        if (syncTraceLevel == TraceLevel.NONE) {
-            return null;
-        }
-
-        StringBuilder report = new StringBuilder();
-
-        if (dryRun) {
-            report.append("==>Dry run only, no modifications were made<==\n\n");
-        }
-
-        List<ProvisioningResult> uSuccCreate = new ArrayList<>();
-        List<ProvisioningResult> uFailCreate = new ArrayList<>();
-        List<ProvisioningResult> uSuccUpdate = new ArrayList<>();
-        List<ProvisioningResult> uFailUpdate = new ArrayList<>();
-        List<ProvisioningResult> uSuccDelete = new ArrayList<>();
-        List<ProvisioningResult> uFailDelete = new ArrayList<>();
-        List<ProvisioningResult> uSuccNone = new ArrayList<>();
-        List<ProvisioningResult> uIgnore = new ArrayList<>();
-        List<ProvisioningResult> gSuccCreate = new ArrayList<>();
-        List<ProvisioningResult> gFailCreate = new ArrayList<>();
-        List<ProvisioningResult> gSuccUpdate = new ArrayList<>();
-        List<ProvisioningResult> gFailUpdate = new ArrayList<>();
-        List<ProvisioningResult> gSuccDelete = new ArrayList<>();
-        List<ProvisioningResult> gFailDelete = new ArrayList<>();
-        List<ProvisioningResult> gSuccNone = new ArrayList<>();
-        List<ProvisioningResult> gIgnore = new ArrayList<>();
-        List<ProvisioningResult> aSuccCreate = new ArrayList<>();
-        List<ProvisioningResult> aFailCreate = new ArrayList<>();
-        List<ProvisioningResult> aSuccUpdate = new ArrayList<>();
-        List<ProvisioningResult> aFailUpdate = new ArrayList<>();
-        List<ProvisioningResult> aSuccDelete = new ArrayList<>();
-        List<ProvisioningResult> aFailDelete = new ArrayList<>();
-        List<ProvisioningResult> aSuccNone = new ArrayList<>();
-        List<ProvisioningResult> aIgnore = new ArrayList<>();
-
-        for (ProvisioningResult provResult : provResults) {
-            AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
-
-            switch (provResult.getStatus()) {
-                case SUCCESS:
-                    switch (provResult.getOperation()) {
-                        case CREATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccCreate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccCreate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccCreate.add(provResult);
-                            }
-                            break;
-
-                        case UPDATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccUpdate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccUpdate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccUpdate.add(provResult);
-                            }
-                            break;
-
-                        case DELETE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccDelete.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccDelete.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccDelete.add(provResult);
-                            }
-                            break;
-
-                        case NONE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uSuccNone.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gSuccNone.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aSuccNone.add(provResult);
-                            }
-                            break;
-
-                        default:
-                    }
-                    break;
-
-                case FAILURE:
-                    switch (provResult.getOperation()) {
-                        case CREATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailCreate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailCreate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailCreate.add(provResult);
-                            }
-                            break;
-
-                        case UPDATE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailUpdate.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailUpdate.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailUpdate.add(provResult);
-                            }
-                            break;
-
-                        case DELETE:
-                            switch (anyType.getKind()) {
-                                case USER:
-                                    uFailDelete.add(provResult);
-                                    break;
-
-                                case GROUP:
-                                    gFailDelete.add(provResult);
-                                    break;
-
-                                case ANY_OBJECT:
-                                default:
-                                    aFailDelete.add(provResult);
-                            }
-                            break;
-
-                        default:
-                    }
-                    break;
-
-                case IGNORE:
-                    switch (anyType.getKind()) {
-                        case USER:
-                            uIgnore.add(provResult);
-                            break;
-
-                        case GROUP:
-                            gIgnore.add(provResult);
-                            break;
-
-                        case ANY_OBJECT:
-                        default:
-                            aIgnore.add(provResult);
-                    }
-                    break;
-
-                default:
-            }
-        }
-
-        // Summary, also to be included for FAILURE and ALL, so create it anyway.
-        report.append("Users ").
-                append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
-                append('\n');
-        report.append("Groups ").
-                append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
-                append('\n');
-        report.append("Any objects ").
-                append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
-                append(' ').
-                append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
-                append(' ').
-                append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
-                append(' ').
-                append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
-
-        // Failures
-        if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
-            if (!uFailCreate.isEmpty()) {
-                report.append("\n\nUsers failed to create: ");
-                report.append(ProvisioningResult.produceReport(uFailCreate, syncTraceLevel));
-            }
-            if (!uFailUpdate.isEmpty()) {
-                report.append("\nUsers failed to update: ");
-                report.append(ProvisioningResult.produceReport(uFailUpdate, syncTraceLevel));
-            }
-            if (!uFailDelete.isEmpty()) {
-                report.append("\nUsers failed to delete: ");
-                report.append(ProvisioningResult.produceReport(uFailDelete, syncTraceLevel));
-            }
-
-            if (!gFailCreate.isEmpty()) {
-                report.append("\n\nGroups failed to create: ");
-                report.append(ProvisioningResult.produceReport(gFailCreate, syncTraceLevel));
-            }
-            if (!gFailUpdate.isEmpty()) {
-                report.append("\nGroups failed to update: ");
-                report.append(ProvisioningResult.produceReport(gFailUpdate, syncTraceLevel));
-            }
-            if (!gFailDelete.isEmpty()) {
-                report.append("\nGroups failed to delete: ");
-                report.append(ProvisioningResult.produceReport(gFailDelete, syncTraceLevel));
-            }
-
-            if (!aFailCreate.isEmpty()) {
-                report.append("\nAny objects failed to create: ");
-                report.append(ProvisioningResult.produceReport(aFailCreate, syncTraceLevel));
-            }
-            if (!aFailUpdate.isEmpty()) {
-                report.append("\nAny objects failed to update: ");
-                report.append(ProvisioningResult.produceReport(aFailUpdate, syncTraceLevel));
-            }
-            if (!aFailDelete.isEmpty()) {
-                report.append("\nAny objects failed to delete: ");
-                report.append(ProvisioningResult.produceReport(aFailDelete, syncTraceLevel));
-            }
-        }
-
-        // Succeeded, only if on 'ALL' level
-        if (syncTraceLevel == TraceLevel.ALL) {
-            report.append("\n\nUsers created:\n").
-                    append(ProvisioningResult.produceReport(uSuccCreate, syncTraceLevel)).
-                    append("\nUsers updated:\n").
-                    append(ProvisioningResult.produceReport(uSuccUpdate, syncTraceLevel)).
-                    append("\nUsers deleted:\n").
-                    append(ProvisioningResult.produceReport(uSuccDelete, syncTraceLevel)).
-                    append("\nUsers no operation:\n").
-                    append(ProvisioningResult.produceReport(uSuccNone, syncTraceLevel)).
-                    append("\nUsers ignored:\n").
-                    append(ProvisioningResult.produceReport(uIgnore, syncTraceLevel));
-            report.append("\n\nGroups created:\n").
-                    append(ProvisioningResult.produceReport(gSuccCreate, syncTraceLevel)).
-                    append("\nGroups updated:\n").
-                    append(ProvisioningResult.produceReport(gSuccUpdate, syncTraceLevel)).
-                    append("\nGroups deleted:\n").
-                    append(ProvisioningResult.produceReport(gSuccDelete, syncTraceLevel)).
-                    append("\nGroups no operation:\n").
-                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel)).
-                    append("\nGroups ignored:\n").
-                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel));
-            report.append("\n\nAny objects created:\n").
-                    append(ProvisioningResult.produceReport(aSuccCreate, syncTraceLevel)).
-                    append("\nAny objects updated:\n").
-                    append(ProvisioningResult.produceReport(aSuccUpdate, syncTraceLevel)).
-                    append("\nAny objects deleted:\n").
-                    append(ProvisioningResult.produceReport(aSuccDelete, syncTraceLevel)).
-                    append("\nAny objects no operation:\n").
-                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel)).
-                    append("\nAny objects ignored:\n").
-                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel));
-        }
-
-        return report.toString();
-    }
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        // PRE: grant all authorities (i.e. setup the SecurityContextHolder)
-        List<GrantedAuthority> authorities = CollectionUtils.collect(Entitlement.values(),
-                new Transformer<String, GrantedAuthority>() {
-
-                    @Override
-                    public GrantedAuthority transform(final String entitlement) {
-                        return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
-                    }
-                }, new ArrayList<GrantedAuthority>());
-
-        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
-                new User(adminUser, "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
-        auth.setDetails(new SyncopeAuthenticationDetails(taskDAO.getDomain(task)));
-        SecurityContextHolder.getContext().setAuthentication(auth);
-
-        try {
-            Class<T> clazz = getTaskClassReference();
-            if (!clazz.isAssignableFrom(task.getClass())) {
-                throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
-            }
-
-            T provisioningTask = clazz.cast(task);
-
-            Connector connector;
-            try {
-                connector = connFactory.getConnector(provisioningTask.getResource());
-            } catch (Exception e) {
-                String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
-                        provisioningTask.getResource(), provisioningTask.getResource().getConnector());
-                throw new JobExecutionException(msg, e);
-            }
-
-            boolean noMapping = true;
-            for (Provision provision : provisioningTask.getResource().getProvisions()) {
-                Mapping mapping = provision.getMapping();
-                if (mapping != null) {
-                    noMapping = false;
-                    if (mapping.getConnObjectKeyItem() == null) {
-                        throw new JobExecutionException(
-                                "Invalid ConnObjectKey mapping for provision " + provision);
-                    }
-                }
-            }
-            if (noMapping) {
-                return "No mapping configured for both users and groups: aborting...";
-            }
-
-            return executeWithSecurityContext(
-                    provisioningTask,
-                    connector,
-                    dryRun);
-        } catch (Throwable t) {
-            LOG.error("While executing provisioning job {}", getClass().getName(), t);
-            throw t;
-        } finally {
-            // POST: clean up the SecurityContextHolder
-            SecurityContextHolder.clearContext();
-        }
-    }
-
-    protected abstract String executeWithSecurityContext(
-            final T task,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException;
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        final ProvisioningTask provTask = (ProvisioningTask) task;
-
-        // True if either failed and failures have to be registered, or if ALL has to be registered.
-        return (Status.valueOf(execution.getStatus()) == Status.FAILURE
-                && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
-                || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
-    }
-
-    @SuppressWarnings("unchecked")
-    private Class<T> getTaskClassReference() {
-        return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
new file mode 100644
index 0000000..0c8deb2
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
@@ -0,0 +1,434 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.java.sync;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Resource;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask>
+        extends AbstractSchedTaskJobDelegate {
+
+    @Resource(name = "adminUser")
+    protected String adminUser;
+
+    /**
+     * ConnInstance loader.
+     */
+    @Autowired
+    protected ConnectorFactory connFactory;
+
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    /**
+     * Resource DAO.
+     */
+    @Autowired
+    protected ExternalResourceDAO resourceDAO;
+
+    /**
+     * Policy DAO.
+     */
+    @Autowired
+    protected PolicyDAO policyDAO;
+
+    /**
+     * Create a textual report of the synchronization, based on the trace level.
+     *
+     * @param provResults Sync results
+     * @param syncTraceLevel Sync trace level
+     * @param dryRun dry run?
+     * @return report as string
+     */
+    protected String createReport(final Collection<ProvisioningResult> provResults, final TraceLevel syncTraceLevel,
+            final boolean dryRun) {
+
+        if (syncTraceLevel == TraceLevel.NONE) {
+            return null;
+        }
+
+        StringBuilder report = new StringBuilder();
+
+        if (dryRun) {
+            report.append("==>Dry run only, no modifications were made<==\n\n");
+        }
+
+        List<ProvisioningResult> uSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> uFailCreate = new ArrayList<>();
+        List<ProvisioningResult> uSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> uFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> uSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> uFailDelete = new ArrayList<>();
+        List<ProvisioningResult> uSuccNone = new ArrayList<>();
+        List<ProvisioningResult> uIgnore = new ArrayList<>();
+        List<ProvisioningResult> gSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> gFailCreate = new ArrayList<>();
+        List<ProvisioningResult> gSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> gFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> gSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> gFailDelete = new ArrayList<>();
+        List<ProvisioningResult> gSuccNone = new ArrayList<>();
+        List<ProvisioningResult> gIgnore = new ArrayList<>();
+        List<ProvisioningResult> aSuccCreate = new ArrayList<>();
+        List<ProvisioningResult> aFailCreate = new ArrayList<>();
+        List<ProvisioningResult> aSuccUpdate = new ArrayList<>();
+        List<ProvisioningResult> aFailUpdate = new ArrayList<>();
+        List<ProvisioningResult> aSuccDelete = new ArrayList<>();
+        List<ProvisioningResult> aFailDelete = new ArrayList<>();
+        List<ProvisioningResult> aSuccNone = new ArrayList<>();
+        List<ProvisioningResult> aIgnore = new ArrayList<>();
+
+        for (ProvisioningResult provResult : provResults) {
+            AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
+
+            switch (provResult.getStatus()) {
+                case SUCCESS:
+                    switch (provResult.getOperation()) {
+                        case CREATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccCreate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccCreate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccCreate.add(provResult);
+                            }
+                            break;
+
+                        case UPDATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccUpdate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccUpdate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccUpdate.add(provResult);
+                            }
+                            break;
+
+                        case DELETE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccDelete.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccDelete.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccDelete.add(provResult);
+                            }
+                            break;
+
+                        case NONE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uSuccNone.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gSuccNone.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aSuccNone.add(provResult);
+                            }
+                            break;
+
+                        default:
+                    }
+                    break;
+
+                case FAILURE:
+                    switch (provResult.getOperation()) {
+                        case CREATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uFailCreate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gFailCreate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aFailCreate.add(provResult);
+                            }
+                            break;
+
+                        case UPDATE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uFailUpdate.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gFailUpdate.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aFailUpdate.add(provResult);
+                            }
+                            break;
+
+                        case DELETE:
+                            switch (anyType.getKind()) {
+                                case USER:
+                                    uFailDelete.add(provResult);
+                                    break;
+
+                                case GROUP:
+                                    gFailDelete.add(provResult);
+                                    break;
+
+                                case ANY_OBJECT:
+                                default:
+                                    aFailDelete.add(provResult);
+                            }
+                            break;
+
+                        default:
+                    }
+                    break;
+
+                case IGNORE:
+                    switch (anyType.getKind()) {
+                        case USER:
+                            uIgnore.add(provResult);
+                            break;
+
+                        case GROUP:
+                            gIgnore.add(provResult);
+                            break;
+
+                        case ANY_OBJECT:
+                        default:
+                            aIgnore.add(provResult);
+                    }
+                    break;
+
+                default:
+            }
+        }
+
+        // Summary, also to be included for FAILURE and ALL, so create it anyway.
+        report.append("Users ").
+                append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
+                append('\n');
+        report.append("Groups ").
+                append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
+                append('\n');
+        report.append("Any objects ").
+                append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
+                append(' ').
+                append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
+                append(' ').
+                append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
+                append(' ').
+                append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
+
+        // Failures
+        if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
+            if (!uFailCreate.isEmpty()) {
+                report.append("\n\nUsers failed to create: ");
+                report.append(ProvisioningResult.produceReport(uFailCreate, syncTraceLevel));
+            }
+            if (!uFailUpdate.isEmpty()) {
+                report.append("\nUsers failed to update: ");
+                report.append(ProvisioningResult.produceReport(uFailUpdate, syncTraceLevel));
+            }
+            if (!uFailDelete.isEmpty()) {
+                report.append("\nUsers failed to delete: ");
+                report.append(ProvisioningResult.produceReport(uFailDelete, syncTraceLevel));
+            }
+
+            if (!gFailCreate.isEmpty()) {
+                report.append("\n\nGroups failed to create: ");
+                report.append(ProvisioningResult.produceReport(gFailCreate, syncTraceLevel));
+            }
+            if (!gFailUpdate.isEmpty()) {
+                report.append("\nGroups failed to update: ");
+                report.append(ProvisioningResult.produceReport(gFailUpdate, syncTraceLevel));
+            }
+            if (!gFailDelete.isEmpty()) {
+                report.append("\nGroups failed to delete: ");
+                report.append(ProvisioningResult.produceReport(gFailDelete, syncTraceLevel));
+            }
+
+            if (!aFailCreate.isEmpty()) {
+                report.append("\nAny objects failed to create: ");
+                report.append(ProvisioningResult.produceReport(aFailCreate, syncTraceLevel));
+            }
+            if (!aFailUpdate.isEmpty()) {
+                report.append("\nAny objects failed to update: ");
+                report.append(ProvisioningResult.produceReport(aFailUpdate, syncTraceLevel));
+            }
+            if (!aFailDelete.isEmpty()) {
+                report.append("\nAny objects failed to delete: ");
+                report.append(ProvisioningResult.produceReport(aFailDelete, syncTraceLevel));
+            }
+        }
+
+        // Succeeded, only if on 'ALL' level
+        if (syncTraceLevel == TraceLevel.ALL) {
+            report.append("\n\nUsers created:\n").
+                    append(ProvisioningResult.produceReport(uSuccCreate, syncTraceLevel)).
+                    append("\nUsers updated:\n").
+                    append(ProvisioningResult.produceReport(uSuccUpdate, syncTraceLevel)).
+                    append("\nUsers deleted:\n").
+                    append(ProvisioningResult.produceReport(uSuccDelete, syncTraceLevel)).
+                    append("\nUsers no operation:\n").
+                    append(ProvisioningResult.produceReport(uSuccNone, syncTraceLevel)).
+                    append("\nUsers ignored:\n").
+                    append(ProvisioningResult.produceReport(uIgnore, syncTraceLevel));
+            report.append("\n\nGroups created:\n").
+                    append(ProvisioningResult.produceReport(gSuccCreate, syncTraceLevel)).
+                    append("\nGroups updated:\n").
+                    append(ProvisioningResult.produceReport(gSuccUpdate, syncTraceLevel)).
+                    append("\nGroups deleted:\n").
+                    append(ProvisioningResult.produceReport(gSuccDelete, syncTraceLevel)).
+                    append("\nGroups no operation:\n").
+                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel)).
+                    append("\nGroups ignored:\n").
+                    append(ProvisioningResult.produceReport(gSuccNone, syncTraceLevel));
+            report.append("\n\nAny objects created:\n").
+                    append(ProvisioningResult.produceReport(aSuccCreate, syncTraceLevel)).
+                    append("\nAny objects updated:\n").
+                    append(ProvisioningResult.produceReport(aSuccUpdate, syncTraceLevel)).
+                    append("\nAny objects deleted:\n").
+                    append(ProvisioningResult.produceReport(aSuccDelete, syncTraceLevel)).
+                    append("\nAny objects no operation:\n").
+                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel)).
+                    append("\nAny objects ignored:\n").
+                    append(ProvisioningResult.produceReport(aSuccNone, syncTraceLevel));
+        }
+
+        return report.toString();
+    }
+
+    @Override
+    protected String doExecute(final boolean dryRun) throws JobExecutionException {
+        try {
+            Class<T> clazz = getTaskClassReference();
+            if (!clazz.isAssignableFrom(task.getClass())) {
+                throw new JobExecutionException("Task " + task.getKey() + " isn't a ProvisioningTask");
+            }
+
+            T provisioningTask = clazz.cast(task);
+
+            Connector connector;
+            try {
+                connector = connFactory.getConnector(provisioningTask.getResource());
+            } catch (Exception e) {
+                String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
+                        provisioningTask.getResource(), provisioningTask.getResource().getConnector());
+                throw new JobExecutionException(msg, e);
+            }
+
+            boolean noMapping = true;
+            for (Provision provision : provisioningTask.getResource().getProvisions()) {
+                Mapping mapping = provision.getMapping();
+                if (mapping != null) {
+                    noMapping = false;
+                    if (mapping.getConnObjectKeyItem() == null) {
+                        throw new JobExecutionException(
+                                "Invalid ConnObjectKey mapping for provision " + provision);
+                    }
+                }
+            }
+            if (noMapping) {
+                return "No mapping configured for both users and groups: aborting...";
+            }
+
+            return doExecuteProvisioning(
+                    provisioningTask,
+                    connector,
+                    dryRun);
+        } catch (Throwable t) {
+            LOG.error("While executing provisioning job {}", getClass().getName(), t);
+            throw t;
+        }
+    }
+
+    protected abstract String doExecuteProvisioning(
+            final T task,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException;
+
+    @Override
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        final ProvisioningTask provTask = (ProvisioningTask) task;
+
+        // True if either failed and failures have to be registered, or if ALL has to be registered.
+        return (TaskJob.Status.valueOf(execution.getStatus()) == TaskJob.Status.FAILURE
+                && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
+                || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
+    }
+
+    @SuppressWarnings("unchecked")
+    private Class<T> getTaskClassReference() {
+        return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
index fd5a482..6be2167 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
@@ -50,6 +50,7 @@ import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
 import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.quartz.JobExecutionException;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
@@ -71,7 +72,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
     protected abstract ConnectorObject getRemoteObject(String connObjectKey, ObjectClass objectClass);
 
-    @Transactional
+    @Transactional(propagation = Propagation.REQUIRES_NEW)
     @Override
     public boolean handle(final long anyKey) {
         Any<?, ?, ?> any = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
index 6d8986a..b0b5a58 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
@@ -44,7 +44,9 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 import org.identityconnectors.framework.common.objects.SyncDeltaType;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 
+@Transactional(rollbackFor = Throwable.class)
 public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
         implements SyncopeSyncResultHandler {
 
@@ -614,9 +616,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
      * @param provision provisioning info
      * @throws JobExecutionException in case of synchronization failure.
      */
-    protected void doHandle(final SyncDelta delta, final Provision provision)
-            throws JobExecutionException {
-
+    protected void doHandle(final SyncDelta delta, final Provision provision) throws JobExecutionException {
         AnyUtils anyUtils = getAnyUtils();
 
         LOG.debug("Process {} for {} as {}",

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
index cf08d8d..49a38d3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
@@ -28,7 +28,6 @@ import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
 import org.apache.syncope.core.misc.AuditManager;
@@ -39,6 +38,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
new file mode 100644
index 0000000..ff6ff21
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.sync.PushActions;
+import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
+
+    private static final int PAGE_SIZE = 1000;
+
+    /**
+     * User DAO.
+     */
+    @Autowired
+    private UserDAO userDAO;
+
+    /**
+     * Search DAO.
+     */
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    /**
+     * Group DAO.
+     */
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+        AnyDAO<?> result;
+        switch (anyTypeKind) {
+            case USER:
+                result = userDAO;
+                break;
+
+            case GROUP:
+                result = groupDAO;
+                break;
+
+            case ANY_OBJECT:
+            default:
+                result = anyObjectDAO;
+        }
+
+        return result;
+    }
+
+    @Override
+    protected String doExecuteProvisioning(
+            final PushTask pushTask,
+            final Connector connector,
+            final boolean dryRun) throws JobExecutionException {
+
+        LOG.debug("Executing push on {}", pushTask.getResource());
+
+        List<PushActions> actions = new ArrayList<>();
+        for (String className : pushTask.getActionsClassNames()) {
+            try {
+                Class<?> actionsClass = Class.forName(className);
+
+                PushActions syncActions = (PushActions) ApplicationContextProvider.getBeanFactory().
+                        createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+                actions.add(syncActions);
+            } catch (Exception e) {
+                LOG.info("Class '{}' not found", className, e);
+            }
+        }
+
+        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+        profile.setDryRun(dryRun);
+        profile.setResAct(null);
+
+        AnyObjectPushResultHandler ahandler =
+                (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
+        UserPushResultHandler uhandler =
+                (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        uhandler.setProfile(profile);
+
+        GroupPushResultHandler ghandler =
+                (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
+                createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ghandler.setProfile(profile);
+
+        if (!profile.isDryRun()) {
+            for (PushActions action : actions) {
+                action.beforeAll(profile);
+            }
+        }
+
+        for (Provision provision : pushTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
+                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
+                String filter = pushTask.getFilter(provision.getAnyType()) == null
+                        ? null
+                        : pushTask.getFilter(provision.getAnyType()).get();
+
+                int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+                for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
+                    List<? extends Any<?, ?, ?>> localAnys = StringUtils.isBlank(filter)
+                            ? anyDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
+                            : searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                                    SearchCondConverter.convert(filter),
+                                    Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind());
+
+                    for (Any<?, ?, ?> any : localAnys) {
+                        SyncopePushResultHandler handler;
+                        switch (provision.getAnyType().getKind()) {
+                            case USER:
+                                handler = uhandler;
+                                break;
+
+                            case GROUP:
+                                handler = ghandler;
+                                break;
+
+                            case ANY_OBJECT:
+                            default:
+                                handler = ahandler;
+                        }
+
+                        try {
+                            handler.handle(any.getKey());
+                        } catch (Exception e) {
+                            LOG.warn("Failure pushing '{}' on '{}'", any, pushTask.getResource(), e);
+                            throw new JobExecutionException(
+                                    "While pushing " + any + " on " + pushTask.getResource(), e);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!profile.isDryRun()) {
+            for (PushActions action : actions) {
+                action.afterAll(profile);
+            }
+        }
+
+        String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
+        LOG.debug("Sync result: {}", result);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
deleted file mode 100644
index b658bc4..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobImpl.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.core.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-
-/**
- * Job for executing synchronization (towards external resource) tasks.
- *
- * @see AbstractProvisioningJob
- * @see PushTask
- * @see PushActions
- */
-public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions> implements PushJob {
-
-    private static final int PAGE_SIZE = 1000;
-
-    /**
-     * User DAO.
-     */
-    @Autowired
-    private UserDAO userDAO;
-
-    /**
-     * Search DAO.
-     */
-    @Autowired
-    private AnySearchDAO searchDAO;
-
-    /**
-     * Group DAO.
-     */
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
-        AnyDAO<?> result;
-        switch (anyTypeKind) {
-            case USER:
-                result = userDAO;
-                break;
-
-            case GROUP:
-                result = groupDAO;
-                break;
-
-            case ANY_OBJECT:
-            default:
-                result = anyObjectDAO;
-        }
-
-        return result;
-    }
-
-    @Override
-    protected String executeWithSecurityContext(
-            final PushTask pushTask,
-            final Connector connector,
-            final boolean dryRun) throws JobExecutionException {
-
-        LOG.debug("Executing push on {}", pushTask.getResource());
-
-        ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
-        if (actions != null) {
-            profile.getActions().addAll(actions);
-        }
-        profile.setDryRun(dryRun);
-        profile.setResAct(null);
-
-        AnyObjectPushResultHandler ahandler =
-                (AnyObjectPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ahandler.setProfile(profile);
-
-        UserPushResultHandler uhandler =
-                (UserPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        uhandler.setProfile(profile);
-
-        GroupPushResultHandler ghandler =
-                (GroupPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
-                createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        ghandler.setProfile(profile);
-
-        if (actions != null && !profile.isDryRun()) {
-            for (PushActions action : actions) {
-                action.beforeAll(profile);
-            }
-        }
-
-        for (Provision provision : pushTask.getResource().getProvisions()) {
-            if (provision.getMapping() != null) {
-                AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
-                String filter = pushTask.getFilter(provision.getAnyType()) == null
-                        ? null
-                        : pushTask.getFilter(provision.getAnyType()).get();
-
-                int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
-                for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
-                    List<? extends Any<?, ?, ?>> localAnys = StringUtils.isBlank(filter)
-                            ? anyDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, page, PAGE_SIZE)
-                            : searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
-                                    SearchCondConverter.convert(filter),
-                                    Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind());
-
-                    for (Any<?, ?, ?> any : localAnys) {
-                        SyncopePushResultHandler handler;
-                        switch (provision.getAnyType().getKind()) {
-                            case USER:
-                                handler = uhandler;
-                                break;
-
-                            case GROUP:
-                                handler = ghandler;
-                                break;
-
-                            case ANY_OBJECT:
-                            default:
-                                handler = ahandler;
-                        }
-
-                        try {
-                            handler.handle(any.getKey());
-                        } catch (Exception e) {
-                            LOG.warn("Failure pushing '{}' on '{}'", any, pushTask.getResource(), e);
-                            throw new JobExecutionException(
-                                    "While pushing " + any + " on " + pushTask.getResource(), e);
-                        }
-                    }
-                }
-            }
-        }
-
-        if (actions != null && !profile.isDryRun()) {
-            for (PushActions action : actions) {
-                action.afterAll(profile);
-            }
-        }
-
-        String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
-        LOG.debug("Sync result: {}", result);
-        return result;
-    }
-}


[02/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
index 8f0d9d2..8b5ad89 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -147,19 +147,19 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> activate(final StatusMod statusMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("token", statusMod.getToken());
-        props.put("user", user);
+        props.put("userKey", statusMod.getKey());
         props.put("statusMod", statusMod);
 
         if (statusMod.isOnSyncope()) {
-            sendMessage("direct:activateUser", user.getKey(), props);
+            sendMessage("direct:activateUser", statusMod.getKey(), props);
         } else {
             WorkflowResult<Long> updated =
-                    new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                    new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
             sendMessage("direct:userStatusPropagation", updated, props);
         }
 
@@ -174,18 +174,18 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> reactivate(final StatusMod statusMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("user", user);
+        props.put("userKey", statusMod.getKey());
         props.put("statusMod", statusMod);
 
         if (statusMod.isOnSyncope()) {
-            sendMessage("direct:reactivateUser", user.getKey(), props);
+            sendMessage("direct:reactivateUser", statusMod.getKey(), props);
         } else {
             WorkflowResult<Long> updated =
-                    new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                    new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
             sendMessage("direct:userStatusPropagation", updated, props);
         }
 
@@ -200,18 +200,18 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
-    public Pair<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+    public Pair<Long, List<PropagationStatus>> suspend(final StatusMod statusMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:statusPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("user", user);
+        props.put("userKey", statusMod.getKey());
         props.put("statusMod", statusMod);
 
         if (statusMod.isOnSyncope()) {
-            sendMessage("direct:suspendUser", user.getKey(), props);
+            sendMessage("direct:suspendUser", statusMod.getKey(), props);
         } else {
             WorkflowResult<Long> updated =
-                    new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+                    new WorkflowResult<>(statusMod.getKey(), null, statusMod.getType().name().toLowerCase());
             sendMessage("direct:userStatusPropagation", updated, props);
         }
 
@@ -242,6 +242,30 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
 
     @Override
     @SuppressWarnings("unchecked")
+    public List<PropagationStatus> provision(
+            final Long key, final boolean changePwd, final String password, final Collection<String> resources) {
+
+        PollingConsumer pollingConsumer = getConsumer("direct:provisionPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("key", key);
+        props.put("changePwd", changePwd);
+        props.put("password", password);
+        props.put("resources", resources);
+
+        sendMessage("direct:provisionUser", key, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
     public List<PropagationStatus> deprovision(final Long user, final Collection<String> resources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deprovisionPort");
 
@@ -268,7 +292,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         PollingConsumer pollingConsumer = getConsumer("direct:updateInSyncPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("key", key);
+        props.put("userKey", key);
         props.put("result", result);
         props.put("enabled", enabled);
         props.put("excludedResources", excludedResources);
@@ -301,7 +325,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
         Map<String, Object> props = new HashMap<>();
         props.put("propagate", propagate);
 
-        sendMessage("direct:innerSuspendUser", user, props);
+        sendMessage("direct:innerSuspendUser", user.getKey(), props);
 
         Exchange exchange = pollingConsumer.receive();
 
@@ -324,16 +348,15 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
-    public void confirmPasswordReset(final User user, final String token, final String password) {
+    public void confirmPasswordReset(final Long key, final String token, final String password) {
         PollingConsumer pollingConsumer = getConsumer("direct:confirmPwdResetPort");
 
         Map<String, Object> props = new HashMap<>();
-        props.put("user", user);
-        props.put("userKey", user.getKey());
+        props.put("userKey", key);
         props.put("token", token);
         props.put("password", password);
 
-        sendMessage("direct:confirmPwdReset", user, props);
+        sendMessage("direct:confirmPwdReset", key, props);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
index 2f2e41e..6316230 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
@@ -57,7 +57,7 @@ public class AnyObjectCreateProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getAnyObjectCreateTasks(created, any.getVirAttrs(), excludedResource);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
index d1c9243..5045ab7 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
@@ -69,7 +69,7 @@ public class AnyObjectDeleteProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
index c56ab90..5836a9f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
@@ -64,7 +64,7 @@ public class AnyObjectDeprovisionProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getAnyObjectDeleteTasks(anyObjectKey, new HashSet<>(resources), noPropResourceNames);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
new file mode 100644
index 0000000..ff9466d
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectProvisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectProvisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long key = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
index 2979e97..04009ef 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
@@ -76,7 +76,7 @@ public class AnyObjectUpdateProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
index 4ab62e3..0fb7058 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
@@ -57,7 +57,7 @@ public class GroupCreateProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getGroupCreateTasks(created, any.getVirAttrs(), excludedResource);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
index 8643f6a..00b71d4 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
@@ -90,7 +90,7 @@ public class GroupDeleteProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
index 5b21325..cd36bfb 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
@@ -40,7 +40,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class GroupDeprovisionProcessor implements Processor {
 
-    private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class);
+    private static final Logger LOG = LoggerFactory.getLogger(GroupDeprovisionProcessor.class);
 
     @Autowired
     protected PropagationManager propagationManager;
@@ -64,7 +64,7 @@ public class GroupDeprovisionProcessor implements Processor {
         List<PropagationTask> tasks =
                 propagationManager.getGroupDeleteTasks(groupKey, new HashSet<>(resources), noPropResourceNames);
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
new file mode 100644
index 0000000..23f47a7
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GroupProvisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GroupProvisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long key = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.addAll(ResourceOperation.UPDATE, resources);
+
+        WorkflowResult<Long> wfResult = new WorkflowResult<>(key, propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(wfResult, null, null, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
index 2aaec2a..1bdbb6c 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
@@ -76,7 +76,7 @@ public class GroupUpdateProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
index f0c6851..a586f09 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
@@ -26,7 +26,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
@@ -50,10 +49,10 @@ public class UserConfirmPwdResetProcessor implements Processor {
 
     @Override
     public void process(final Exchange exchange) {
-        User user = exchange.getProperty("user", User.class);
+        Long key = exchange.getProperty("userKey", Long.class);
 
         UserMod userMod = new UserMod();
-        userMod.setKey(user.getKey());
+        userMod.setKey(key);
         userMod.setPassword(exchange.getProperty("password", String.class));
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
@@ -61,7 +60,7 @@ public class UserConfirmPwdResetProcessor implements Processor {
                         new ImmutablePair<UserMod, Boolean>(userMod, null), null, "confirmPasswordReset"),
                 true, null);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
index 791a32a..ea06c9d 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
@@ -65,7 +65,7 @@ public class UserCreateProcessor implements Processor {
                     actual.getVirAttrs(),
                     excludedResources);
             PropagationReporter propagationReporter =
-                    ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                    ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
             try {
                 taskExecutor.execute(tasks, propagationReporter);
             } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
index 8d94d76..b6218a9 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
@@ -58,7 +58,7 @@ public class UserDeleteProcessor implements Processor {
         List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(userKey, excludedResource);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
index 3060569..642870a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
@@ -63,7 +63,7 @@ public class UserDeprovisionProcessor implements Processor {
                 new HashSet<>(resources),
                 CollectionUtils.removeAll(userDAO.findAllResourceNames(user), resources));
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propagationReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
new file mode 100644
index 0000000..f85c373
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.core.provisioning.camel.processor;
+
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserProvisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserProvisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected UserDAO userDAO;
+
+    @Override
+    public void process(final Exchange exchange) {
+        Long key = exchange.getIn().getBody(Long.class);
+        Boolean changePwd = exchange.getProperty("changePwd", Boolean.class);
+        String password = exchange.getProperty("password", String.class);
+        @SuppressWarnings("unchecked")
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        UserMod userMod = new UserMod();
+        userMod.setKey(key);
+        userMod.getResourcesToAdd().addAll(resources);
+
+        if (changePwd) {
+            StatusMod statusMod = new StatusMod();
+            statusMod.setOnSyncope(false);
+            statusMod.getResourceNames().addAll(resources);
+            userMod.setPwdPropRequest(statusMod);
+            userMod.setPassword(password);
+        }
+
+        PropagationByResource propByRes = new PropagationByResource();
+        for (String resource : resources) {
+            propByRes.add(ResourceOperation.UPDATE, resource);
+        }
+
+        WorkflowResult<Pair<UserMod, Boolean>> wfResult = new WorkflowResult<Pair<UserMod, Boolean>>(
+                ImmutablePair.of(userMod, (Boolean) null), propByRes, "update");
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(wfResult, changePwd, null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
index cf9d709..75ab027 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserSetStatusInSyncProcessor.java
@@ -44,7 +44,7 @@ public class UserSetStatusInSyncProcessor implements Processor {
         WorkflowResult<Map.Entry<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
 
         Boolean enabled = exchange.getProperty("enabled", Boolean.class);
-        Long key = exchange.getProperty("key", Long.class);
+        Long key = exchange.getProperty("userKey", Long.class);
 
         if (enabled != null) {
             User user = userDAO.find(key);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
index cb0bb82..cbc8fb7 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
@@ -28,7 +28,6 @@ import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
@@ -52,22 +51,22 @@ public class UserStatusPropagationProcessor implements Processor {
 
     @Autowired
     protected UserDAO userDAO;
-    
+
     @SuppressWarnings("unchecked")
     @Override
     public void process(final Exchange exchange) {
         WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
 
-        User user = exchange.getProperty("user", User.class);
+        Long key = exchange.getProperty("userKey", Long.class);
         StatusMod statusMod = exchange.getProperty("statusMod", StatusMod.class);
 
-        Collection<String> resourcesToBeExcluded =
-                CollectionUtils.removeAll(userDAO.findAllResourceNames(user), statusMod.getResourceNames());
+        Collection<String> resourcesToBeExcluded = CollectionUtils.removeAll(
+                userDAO.findAllResourceNames(userDAO.find(key)), statusMod.getResourceNames());
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                user, statusMod.getType() != StatusMod.ModType.SUSPEND, resourcesToBeExcluded);
+                key, statusMod.getType() != StatusMod.ModType.SUSPEND, resourcesToBeExcluded);
         PropagationReporter propReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         try {
             taskExecutor.execute(tasks, propReporter);
         } catch (PropagationException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
index 829999f..dcd271d 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
@@ -55,7 +55,7 @@ public class UserUpdateInSyncProcessor implements Processor {
         Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated, updated.getResult().getKey().
                 getPassword() != null, excludedResources);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
index e71a15a..1dc19f5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
@@ -74,7 +74,7 @@ public class UserUpdateProcessor implements Processor {
         }
 
         PropagationReporter propagationReporter =
-                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+                ApplicationContextProvider.getBeanFactory().getBean(PropagationReporter.class);
         if (!tasks.isEmpty()) {
             try {
                 taskExecutor.execute(tasks, propagationReporter);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
index de4df0b..9cbde16 100644
--- a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
@@ -112,6 +112,12 @@ under the License.
     </doTry>            
   </route>
         
+  <route id="provisionAnyObject">
+    <from uri="direct:provisionAnyObject"/>            
+    <process ref="anyObjectProvisionProcessor"/>
+    <to uri="direct:provisionAnyObjectPort"/>              
+  </route>
+
   <route id="deprovisionAnyObject">
     <from uri="direct:deprovisionAnyObject"/>            
     <process ref="anyObjectDeprovisionProcessor"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
index f897f90..ac64345 100644
--- a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
@@ -131,6 +131,12 @@ under the License.
     </doTry>            
   </route>
         
+  <route id="provisionGroup">
+    <from uri="direct:provisionGroup"/>            
+    <process ref="groupProvisionProcessor"/>
+    <to uri="direct:provisionGroupPort"/>              
+  </route>
+
   <route id="deprovisionGroup">
     <from uri="direct:deprovisionGroup"/>            
     <process ref="groupDeprovisionProcessor"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
index 06e68d1..aca6a46 100644
--- a/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/userRoutes.xml
@@ -185,7 +185,13 @@ under the License.
     <process ref="userStatusPropagationProcessor"/>
     <to uri="direct:statusPort"/> 
   </route>
-        
+    
+  <route id="provisionUser">
+    <from uri="direct:provisionUser"/>            
+    <process ref="userProvisionProcessor"/>
+    <to uri="direct:provisionPort"/>              
+  </route>
+                
   <route id="deprovisionUser">
     <from uri="direct:deprovisionUser"/>            
     <process ref="userDeprovisionProcessor"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 166a394..d7e27dc 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -261,7 +261,7 @@ under the License.
             </deployable>
             <deployable>
               <location>${project.build.directory}/${project.build.finalName}</location>
-              <pingURL>http://localhost:${cargo.servlet.port}/syncope/db.jsp</pingURL>
+              <pingURL>http://localhost:${cargo.servlet.port}/syncope/cacheStats.jsp</pingURL>
               <pingTimeout>60000</pingTimeout>
               <properties>
                 <context>syncope</context>
@@ -310,14 +310,18 @@ under the License.
         <filtering>true</filtering>
       </resource>
       <resource>
-        <directory>${basedir}/../../core/persistence-jpa/src/test/resources</directory>
+        <directory>${basedir}/../../core/persistence-jpa/src/main/resources</directory>
         <includes>
-          <include>content.xml</include>
           <include>persistence.properties</include>
         </includes>
         <filtering>true</filtering>
       </resource>
       <resource>
+        <directory>${basedir}/../../core/persistence-jpa/src/test/resources/domains</directory>
+        <targetPath>${project.build.directory}/classes/domains</targetPath>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
         <directory>${basedir}/../../core/misc/src/main/resources</directory>
         <includes>
           <include>security.properties</include>
@@ -803,7 +807,7 @@ under the License.
                 <transformationSet>
                   <dir>${project.build.directory}/classes</dir>
                   <includes>
-                    <include>content.xml</include>
+                    <include>domains/MasterContent.xml</include>
                   </includes>
                   <outputDir>${project.build.directory}/classes</outputDir>
                   <stylesheet>${basedir}/src/test/resources/addActivitiToContent.xsl</stylesheet>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java
deleted file mode 100644
index a8f7184..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJob.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.fit.core.reference;
-
-import java.util.Date;
-import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.java.job.AbstractTaskJob;
-import org.quartz.JobExecutionException;
-
-/**
- * Sample implementation for execution a scheduled task.
- *
- * @see SchedTask
- */
-public class TestSampleJob extends AbstractTaskJob {
-
-    @Override
-    protected String doExecute(final boolean dryRun) throws JobExecutionException {
-        if (!(task instanceof SchedTask)) {
-            throw new JobExecutionException("Task " + taskId + " isn't a SchedTask");
-        }
-
-        for (int i = 0; i < 10; i++) {
-            LOG.debug("TestSampleJob#doExecute round {} time {}", i, new Date().toString());
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ex) {
-                throw new JobExecutionException("Job interrupted");
-            }
-        }
-
-        final SchedTask schedTask = (SchedTask) this.task;
-
-        LOG.info("TestSampleJob {}running [SchedTask {}]", (dryRun
-                ? "dry "
-                : ""), schedTask.getKey());
-
-        return (dryRun
-                ? "DRY "
-                : "") + "RUNNING";
-    }
-
-    @Override
-    protected boolean hasToBeRegistered(final TaskExec execution) {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java
new file mode 100644
index 0000000..1c58a04
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.fit.core.reference;
+
+import java.util.Date;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
+import org.quartz.JobExecutionException;
+
+/**
+ * Sample implementation for execution a scheduled task.
+ *
+ * @see SchedTask
+ */
+public class TestSampleJobDelegate extends AbstractSchedTaskJobDelegate {
+
+    @Override
+    protected String doExecute(final boolean dryRun) throws JobExecutionException {
+        if (!(task instanceof SchedTask)) {
+            throw new JobExecutionException("Task " + task.getKey() + " isn't a SchedTask");
+        }
+
+        for (int i = 0; i < 10; i++) {
+            LOG.debug("TestSampleJob#doExecute round {} time {}", i, new Date().toString());
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ex) {
+                throw new JobExecutionException("Job interrupted");
+            }
+        }
+
+        final SchedTask schedTask = (SchedTask) this.task;
+
+        LOG.info("TestSampleJob {}running [SchedTask {}]", (dryRun
+                ? "dry "
+                : ""), schedTask.getKey());
+
+        return (dryRun
+                ? "DRY "
+                : "") + "RUNNING";
+    }
+
+    @Override
+    protected boolean hasToBeRegistered(final TaskExec execution) {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/resources/all/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/provisioning.properties b/fit/core-reference/src/main/resources/all/provisioning.properties
index 4d0ecaf..015ca72 100644
--- a/fit/core-reference/src/main/resources/all/provisioning.properties
+++ b/fit/core-reference/src/main/resources/all/provisioning.properties
@@ -18,4 +18,8 @@ camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
-virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
\ No newline at end of file
+virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+
+quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+quartz.sql=tables_h2.sql
+quartz.scheduler.idleWaitTime=5000

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/resources/coreContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/coreContext.xml b/fit/core-reference/src/main/resources/coreContext.xml
index bbc4c4f..ecdb57d 100644
--- a/fit/core-reference/src/main/resources/coreContext.xml
+++ b/fit/core-reference/src/main/resources/coreContext.xml
@@ -29,6 +29,7 @@ under the License.
     <property name="locations">
       <list>
         <value>file:${conf.directory}/persistence.properties</value>
+        <value>file:${conf.directory}/domains/*.properties</value>
         <value>file:${conf.directory}/security.properties</value>
         <value>file:${conf.directory}/connid.properties</value>
         <value>file:${conf.directory}/mail.properties</value>
@@ -42,6 +43,7 @@ under the License.
     <property name="locations">
       <list>
         <value>classpath:persistence.properties</value>
+        <value>classpath:domains/*.properties</value>
         <value>classpath:security.properties</value>
         <value>classpath:connid.properties</value>
         <value>classpath:mail.properties</value>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/log4j2.xml b/fit/core-reference/src/main/resources/log4j2.xml
index 46d15f5..b50d9cb 100644
--- a/fit/core-reference/src/main/resources/log4j2.xml
+++ b/fit/core-reference/src/main/resources/log4j2.xml
@@ -21,8 +21,8 @@ under the License.
 
   <appenders>
     
-    <RollingRandomAccessFile name="main" fileName="${log.directory}/server.log"
-                             filePattern="${log.directory}/server-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="main" fileName="${log.directory}/core.log"
+                             filePattern="${log.directory}/core-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -33,8 +33,8 @@ under the License.
       </Policies>
     </RollingRandomAccessFile>
 
-    <RollingRandomAccessFile name="persistence" fileName="${log.directory}/server-persistence.log"
-                             filePattern="${log.directory}/server-persistence-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="persistence" fileName="${log.directory}/core-persistence.log"
+                             filePattern="${log.directory}/core-persistence-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -45,8 +45,8 @@ under the License.
       </Policies>
     </RollingRandomAccessFile>
 
-    <RollingRandomAccessFile name="rest" fileName="${log.directory}/server-rest.log"
-                             filePattern="${log.directory}/server-rest-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="rest" fileName="${log.directory}/core-rest.log"
+                             filePattern="${log.directory}/core-rest-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -57,8 +57,8 @@ under the License.
       </Policies>
     </RollingRandomAccessFile>
 
-    <RollingRandomAccessFile name="connid" fileName="${log.directory}/server-connid.log"
-                             filePattern="${log.directory}/server-connid-%d{yyyy-MM-dd}.log.gz"
+    <RollingRandomAccessFile name="connid" fileName="${log.directory}/core-connid.log"
+                             filePattern="${log.directory}/core-connid-%d{yyyy-MM-dd}.log.gz"
                              immediateFlush="false" append="true">
       <PatternLayout>
         <pattern>%d{HH:mm:ss.SSS} %-5level %msg%n</pattern>
@@ -68,17 +68,7 @@ under the License.
         <SizeBasedTriggeringPolicy size="250 MB"/>
       </Policies>
     </RollingRandomAccessFile>
-
-    <!-- Audit -->    
-    <Jdbc name="audit" tableName="SYNCOPEAUDIT">
-      <ConnectionFactory class="org.apache.syncope.core.logic.audit.AuditConnectionFactory" method="getConnection"/>
-      <Column name="EVENT_DATE" isEventTimestamp="true"/>
-      <Column name="LOGGER_LEVEL" pattern="%level" isUnicode="false"/>
-      <Column name="LOGGER" pattern="%logger" isUnicode="false"/>
-      <Column name="MESSAGE" pattern="%message" isUnicode="false"/>
-      <Column name="THROWABLE" pattern="%ex{full}" isUnicode="false"/>
-    </Jdbc>
-
+    
   </appenders>
   
   <loggers>
@@ -122,13 +112,12 @@ under the License.
     <asyncLogger name="org.springframework" additivity="false" level="INFO">
       <appender-ref ref="main"/>
     </asyncLogger>
+    <asyncLogger name="org.quartz" additivity="false" level="INFO">
+      <appender-ref ref="main"/>
+    </asyncLogger>
     <asyncLogger name="org.apache.camel" additivity="false" level="ERROR">
       <appender-ref ref="main"/>
     </asyncLogger>
-         
-    <logger name="syncope.audit" additivity="false" level="DEBUG">
-      <appender-ref ref="audit"/>
-    </logger>
     
     <root level="INFO">
       <appender-ref ref="main"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/provisioning.properties b/fit/core-reference/src/main/resources/provisioning.properties
index af1dd4b..a67787f 100644
--- a/fit/core-reference/src/main/resources/provisioning.properties
+++ b/fit/core-reference/src/main/resources/provisioning.properties
@@ -18,3 +18,7 @@ userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserPro
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+
+quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+quartz.sql=tables_h2.sql
+quartz.scheduler.idleWaitTime=5000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/main/webapp/cacheStats.jsp
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/cacheStats.jsp b/fit/core-reference/src/main/webapp/cacheStats.jsp
index 4e4bf1b..ba380c5 100644
--- a/fit/core-reference/src/main/webapp/cacheStats.jsp
+++ b/fit/core-reference/src/main/webapp/cacheStats.jsp
@@ -16,6 +16,7 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 --%>
+<%@page import="org.springframework.beans.factory.support.DefaultListableBeanFactory"%>
 <%@page import="org.apache.syncope.common.lib.SyncopeConstants"%>
 <%@page import="org.apache.syncope.core.misc.spring.ApplicationContextProvider"%>
 <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
@@ -72,9 +73,9 @@ under the License.
   <body>
     <p/>
     <%
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
+        DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
 
-        EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
+        EntityManagerFactory emf = beanFactory.getBean("MasterEntityManagerFactory", EntityManagerFactory.class);
         OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
 
         QueryStatistics<QueryKey> queryStatistics =

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
index 9fdc1e4..58b1004 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.getUUIDString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index a756401..9d810b6 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -258,17 +258,17 @@ public class AuthenticationITCase extends AbstractITCase {
         assertEquals(0, getFailedLogins(userService4, userId));
     }
 
-    @Test
+    //@Test
     public void checkUserSuspension() {
         UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
         userTO.setRealm("/odd");
         userTO.getRoles().add(2L);
 
         userTO = createUser(userTO);
-        long userId = userTO.getKey();
+        long userKey = userTO.getKey();
         assertNotNull(userTO);
 
-        assertEquals(0, getFailedLogins(userService, userId));
+        assertEquals(0, getFailedLogins(userService, userKey));
 
         // authentications failed ...
         SyncopeClient badPwdClient = clientFactory.create(userTO.getUsername(), "wrongpwd1");
@@ -276,7 +276,7 @@ public class AuthenticationITCase extends AbstractITCase {
         assertReadFails(badPwdClient);
         assertReadFails(badPwdClient);
 
-        assertEquals(3, getFailedLogins(userService, userId));
+        assertEquals(3, getFailedLogins(userService, userKey));
 
         // last authentication before suspension
         assertReadFails(badPwdClient);
@@ -352,7 +352,7 @@ public class AuthenticationITCase extends AbstractITCase {
         assertNotNull(user);
 
         // 2. unlink the resource from the created user
-        assertNotNull(userService.bulkDeassociation(user.getKey(),
+        assertNotNull(userService.deassociate(user.getKey(),
                 ResourceDeassociationActionType.UNLINK,
                 CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceKey.class)).
                 readEntity(BulkActionResult.class));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
index 1a086e2..1904baf 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
@@ -46,7 +45,7 @@ public class CamelRouteITCase extends AbstractITCase {
 
         List<CamelRouteTO> userRoutes = camelRouteService.list(AnyTypeKind.USER);
         assertNotNull(userRoutes);
-        assertEquals(15, userRoutes.size());
+        assertEquals(16, userRoutes.size());
         for (CamelRouteTO route : userRoutes) {
             assertNotNull(route.getContent());
         }
@@ -58,7 +57,7 @@ public class CamelRouteITCase extends AbstractITCase {
 
         List<CamelRouteTO> groupRoutes = camelRouteService.list(AnyTypeKind.GROUP);
         assertNotNull(groupRoutes);
-        assertEquals(7, groupRoutes.size());
+        assertEquals(8, groupRoutes.size());
         for (CamelRouteTO route : groupRoutes) {
             assertNotNull(route.getContent());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
index 60842b9..583e3d9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -686,7 +686,7 @@ public class ConnectorITCase extends AbstractITCase {
     @Test
     public void bulkAction() {
         final BulkAction bulkAction = new BulkAction();
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
 
         ConnInstanceTO conn = connectorService.read(101L);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
index ae823e1..924a24b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ExceptionMapperITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
@@ -105,7 +104,7 @@ public class ExceptionMapperITCase extends AbstractITCase {
             fail();
         } catch (Exception e) {
             String message = ERROR_MESSAGES.getProperty("errMessage.UniqueConstraintViolation");
-            assertEquals(e.getMessage(), "DataIntegrityViolation [" + message + "]");
+            assertEquals("EntityExists [" + message + "]", e.getMessage());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index 855f25b..7fece69 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@ -60,7 +60,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
@@ -323,7 +323,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -352,7 +352,7 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.LINK, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -373,7 +373,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -407,8 +407,8 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.ASSIGN, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(),
+                ResourceAssociationAction.ASSIGN, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -424,7 +424,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
@@ -458,8 +458,8 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(),
+                ResourceAssociationAction.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -485,8 +485,8 @@ public class GroupITCase extends AbstractITCase {
 
         ResourceAssociationMod associationMod = new ResourceAssociationMod();
         associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION, associationMod).
+        assertNotNull(groupService.associate(actual.getKey(),
+                ResourceAssociationAction.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -494,7 +494,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
-        assertNotNull(groupService.bulkDeassociation(actual.getKey(),
+        assertNotNull(groupService.deassociate(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
                 CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
index 2ed8449..40fe8a1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
@@ -197,7 +197,7 @@ public class LoggerITCase extends AbstractITCase {
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
             if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "SampleJob".equals(eventCategoryTO.getCategory())) {
+                    && "TestSampleJobDelegate".equals(eventCategoryTO.getCategory())) {
                 found = true;
             }
         }
@@ -206,7 +206,7 @@ public class LoggerITCase extends AbstractITCase {
         found = false;
         for (EventCategoryTO eventCategoryTO : events) {
             if (EventCategoryType.TASK == eventCategoryTO.getType()
-                    && "SyncJob".equals(eventCategoryTO.getCategory())) {
+                    && "SyncJobDelegate".equals(eventCategoryTO.getCategory())) {
                 found = true;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
index 66185f5..56abdb8 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
@@ -141,7 +141,7 @@ public class PropagationTaskITCase extends AbstractTaskITCase {
         assertFalse(after.isEmpty());
 
         BulkAction bulkAction = new BulkAction();
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
 
         for (PropagationTaskTO taskTO : after) {
             bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index 9a169c3..ca9d8a4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.fit.core.reference;
 
-import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -109,7 +108,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         task = taskService.read(actual.getKey());
         assertNotNull(task);
         assertEquals(task.getKey(), actual.getKey());
-        assertEquals(task.getJobClassName(), actual.getJobClassName());
+        assertEquals(task.getJobDelegateClassName(), actual.getJobDelegateClassName());
         assertEquals(task.getFilters().get(AnyTypeKind.USER.name()),
                 actual.getFilters().get(AnyTypeKind.USER.name()));
         assertEquals(task.getFilters().get(AnyTypeKind.GROUP.name()),
@@ -194,7 +193,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
         assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
 
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
         assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
         assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
index c0e1790..6242d96 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ResourceITCase.java
@@ -481,7 +481,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(resourceService.read("forBulk2"));
 
         final BulkAction bulkAction = new BulkAction();
-        bulkAction.setOperation(BulkAction.Type.DELETE);
+        bulkAction.setType(BulkAction.Type.DELETE);
 
         bulkAction.getTargets().add(String.valueOf("forBulk1"));
         bulkAction.getTargets().add(String.valueOf("forBulk2"));

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
index b65aa72..30425f9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
@@ -38,7 +38,6 @@ import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.lib.types.JobStatusType;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -86,7 +85,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         SchedTaskTO task = new SchedTaskTO();
         task.setName("issueSYNCOPE144");
         task.setDescription("issueSYNCOPE144 Description");
-        task.setJobClassName(SyncJob.class.getName());
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
 
         Response response = taskService.create(task);
         SchedTaskTO actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
@@ -117,7 +116,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         SchedTaskTO task = new SchedTaskTO();
         task.setName("issueSYNCOPE660");
         task.setDescription("issueSYNCOPE660 Description");
-        task.setJobClassName(TestSampleJob.class.getName());
+        task.setJobDelegateClassName(TestSampleJobDelegate.class.getName());
 
         Response response = taskService.create(task);
         task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);


[15/15] syncope git commit: [SYNCOPE-652] Still several things to refine, but it starts taking shape

Posted by il...@apache.org.
[SYNCOPE-652] Still several things to refine, but it starts taking shape


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/34a1c214
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/34a1c214
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/34a1c214

Branch: refs/heads/SYNCOPE-652
Commit: 34a1c21479aa79d2577f6d703c788a19f5f8d1c2
Parents: eec12cd
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Sun Aug 2 07:44:52 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Sun Aug 2 07:44:52 2015 +0200

----------------------------------------------------------------------
 .travis.yml                                     |    4 +-
 .../console/pages/BulkActionModalPage.java      |   12 +-
 .../client/console/rest/GroupRestClient.java    |   14 +-
 .../client/console/rest/UserRestClient.java     |   14 +-
 .../client/console/pages/Configuration.java     |    2 -
 .../syncope/common/lib/to/BulkAction.java       |   10 +-
 .../syncope/common/lib/to/SchedTaskTO.java      |   10 +-
 .../common/lib/types/AbstractPolicySpec.java    |   19 +
 .../syncope/common/lib/types/AuditElements.java |    8 +
 .../syncope/common/lib/types/LoggerType.java    |    5 +-
 .../lib/types/ResourceAssociationAction.java    |   39 +
 .../types/ResourceAssociationActionType.java    |   39 -
 .../common/rest/api/CollectionWrapper.java      |    8 +-
 .../common/rest/api/service/AnyService.java     |    8 +-
 core/logic/pom.xml                              |   22 +
 .../syncope/core/logic/AnyObjectLogic.java      |   57 +-
 .../syncope/core/logic/ConfigurationLogic.java  |    3 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   58 +-
 .../apache/syncope/core/logic/LoggerLogic.java  |   24 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |    2 +-
 .../apache/syncope/core/logic/TaskLogic.java    |   76 +-
 .../apache/syncope/core/logic/UserLogic.java    |   67 +-
 .../logic/audit/AuditConnectionFactory.java     |  159 ---
 .../init/ImplementationClassNamesLoader.java    |   18 +-
 .../core/logic/init/JobInstanceLoaderImpl.java  |  181 ++-
 .../syncope/core/logic/init/LoggerLoader.java   |   64 +-
 .../core/logic/init/LogicInitializer.java       |    3 +
 .../logic/notification/NotificationJob.java     |  237 +---
 .../notification/NotificationJobDelegate.java   |  258 ++++
 .../syncope/core/logic/report/ReportJob.java    |  158 +--
 .../core/logic/report/ReportJobDelegate.java    |  181 +++
 .../apache/syncope/core/logic/AbstractTest.java |    4 +-
 .../apache/syncope/core/logic/MappingTest.java  |    2 +
 .../syncope/core/logic/NotificationTest.java    |    6 +-
 core/logic/src/test/resources/logicTest.xml     |    6 +-
 .../apache/syncope/core/misc/AuditManager.java  |   23 +-
 .../apache/syncope/core/misc/MappingUtils.java  |   26 +-
 .../core/misc/policy/AccountPolicyEnforcer.java |   15 +-
 .../misc/policy/PasswordPolicyEnforcer.java     |    4 +-
 .../core/misc/policy/PolicyEnforcer.java        |   10 +-
 .../core/misc/policy/PolicyEvaluator.java       |    5 +-
 .../core/misc/security/AuthContextUtils.java    |   27 +
 .../core/misc/security/PasswordGenerator.java   |   11 +-
 .../security/SyncopeAuthenticationProvider.java |   10 +-
 .../misc/security/SyncopeGrantedAuthority.java  |    7 +
 .../misc/spring/ApplicationContextProvider.java |   12 +-
 .../core/persistence/api/DomainsHolder.java     |   27 +
 .../api/content/ContentExporter.java            |    2 +-
 .../syncope/core/persistence/api/dao/DAO.java   |    2 -
 .../persistence/api/entity/task/SchedTask.java  |    4 +-
 core/persistence-jpa/pom.xml                    |    5 +
 .../jpa/content/AbstractContentDealer.java      |   57 +-
 .../jpa/content/XMLContentExporter.java         |   36 +-
 .../jpa/content/XMLContentLoader.java           |  113 +-
 .../persistence/jpa/dao/AbstractAnyDAO.java     |   17 +-
 .../core/persistence/jpa/dao/AbstractDAO.java   |   33 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |    8 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |    6 +-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |    8 +-
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java |   10 +-
 .../core/persistence/jpa/dao/JPAConfDAO.java    |    8 +-
 .../persistence/jpa/dao/JPAConnInstanceDAO.java |    8 +-
 .../core/persistence/jpa/dao/JPADerAttrDAO.java |    8 +-
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |   12 +-
 .../core/persistence/jpa/dao/JPADomainDAO.java  |    8 +-
 .../jpa/dao/JPAExternalResourceDAO.java         |   24 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java   |   16 +-
 .../core/persistence/jpa/dao/JPALoggerDAO.java  |    8 +-
 .../persistence/jpa/dao/JPANotificationDAO.java |    8 +-
 .../persistence/jpa/dao/JPAPlainAttrDAO.java    |    4 +-
 .../jpa/dao/JPAPlainAttrValueDAO.java           |    8 +-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPAPolicyDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPARealmDAO.java   |   14 +-
 .../jpa/dao/JPARelationshipTypeDAO.java         |   14 +-
 .../core/persistence/jpa/dao/JPAReportDAO.java  |   13 +-
 .../persistence/jpa/dao/JPAReportExecDAO.java   |   10 +-
 .../core/persistence/jpa/dao/JPARoleDAO.java    |   12 +-
 .../jpa/dao/JPASecurityQuestionDAO.java         |    8 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    |   15 +-
 .../persistence/jpa/dao/JPATaskExecDAO.java     |   10 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java    |  181 ++-
 .../core/persistence/jpa/dao/JPAVirAttrDAO.java |    8 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |   12 +-
 .../persistence/jpa/entity/group/JPAGroup.java  |    2 +-
 .../entity/task/AbstractProvisioningTask.java   |    6 +-
 .../jpa/entity/task/JPAPushTask.java            |    3 +-
 .../jpa/entity/task/JPASchedTask.java           |   11 +-
 .../jpa/entity/task/JPASyncTask.java            |    3 +-
 .../persistence/jpa/entity/user/JPAUser.java    |   10 +-
 .../spring/CommonEntityManagerFactoryConf.java  |  107 ++
 .../spring/DomainEntityManagerFactoryBean.java  |   45 +
 .../spring/DomainTransactionInterceptor.java    |   70 ++
 .../jpa/spring/SpringComponentReplacer.java     |   42 +
 .../entity/EntityValidationListener.java        |    2 +-
 .../entity/ProvisioningTaskValidator.java       |   14 +-
 .../validation/entity/SchedTaskValidator.java   |   44 +-
 .../jpa/validation/entity/UserCheck.java        |   41 -
 .../jpa/validation/entity/UserValidator.java    |  199 ---
 .../src/main/resources/audit/audit.sql          |    4 +-
 .../src/main/resources/content.xml              |  117 --
 .../src/main/resources/domains.xml              |   56 +
 .../main/resources/domains/Master.properties    |   28 +
 .../main/resources/domains/MasterContent.xml    |  124 ++
 .../src/main/resources/domains/MasterDomain.xml |  125 ++
 .../src/main/resources/persistence.properties   |   13 -
 .../src/main/resources/persistenceContext.xml   |   93 +-
 .../resources/persistenceContextEMFactory.xml   |   68 --
 .../src/main/resources/quartz/tables_h2.sql     |  266 ----
 .../main/resources/quartz/tables_mariadb.sql    |  206 ----
 .../src/main/resources/quartz/tables_mysql.sql  |  206 ----
 .../resources/quartz/tables_mysql_innodb.sql    |  221 ----
 .../src/main/resources/quartz/tables_oracle.sql |  208 ----
 .../main/resources/quartz/tables_postgres.sql   |  204 ----
 .../main/resources/quartz/tables_sqlServer.sql  |  296 -----
 .../core/persistence/jpa/AbstractTest.java      |   16 +
 .../persistence/jpa/inner/MultitenancyTest.java |  111 ++
 .../core/persistence/jpa/inner/UserTest.java    |    4 +-
 .../persistence/jpa/outer/AnyTypeClassTest.java |    4 -
 .../core/persistence/jpa/outer/GroupTest.java   |   11 +-
 .../persistence/jpa/outer/ResourceTest.java     |    5 +-
 .../core/persistence/jpa/outer/RoleTest.java    |    8 +-
 .../resources/META-INF/persistence-enhance.xml  |    2 +-
 .../src/test/resources/content.xml              | 1138 ------------------
 .../test/resources/domains/Master.properties    |   28 +
 .../test/resources/domains/MasterContent.xml    | 1131 +++++++++++++++++
 .../src/test/resources/domains/Two.properties   |   28 +
 .../src/test/resources/domains/TwoContent.xml   |  124 ++
 .../src/test/resources/domains/TwoDomain.xml    |  125 ++
 .../src/test/resources/persistence.properties   |   31 -
 .../src/test/resources/persistenceTest.xml      |    1 +
 .../api/AnyObjectProvisioningManager.java       |    5 +
 .../api/GroupProvisioningManager.java           |    3 +
 .../api/UserProvisioningManager.java            |   11 +-
 .../provisioning/api/job/JobInstanceLoader.java |   12 +-
 .../core/provisioning/api/job/JobNamer.java     |   10 +-
 .../provisioning/api/job/ProvisioningJob.java   |   28 -
 .../core/provisioning/api/job/PushJob.java      |   26 -
 .../api/job/SchedTaskJobDelegate.java           |   26 +
 .../core/provisioning/api/job/SyncJob.java      |   26 -
 .../core/provisioning/api/job/TaskJob.java      |   43 -
 .../api/propagation/PropagationManager.java     |    5 +-
 core/provisioning-java/pom.xml                  |    7 +
 .../provisioning/java/ConnectorFacadeProxy.java |    2 +-
 .../provisioning/java/ConnectorManager.java     |    2 +-
 .../DefaultAnyObjectProvisioningManager.java    |   46 +-
 .../java/DefaultGroupProvisioningManager.java   |   62 +-
 .../java/DefaultUserProvisioningManager.java    |  120 +-
 .../provisioning/java/UserSuspenderImpl.java    |    2 +-
 .../java/data/AbstractAnyDataBinder.java        |   18 +-
 .../java/data/AnyObjectDataBinderImpl.java      |    2 -
 .../java/data/ConfigurationDataBinderImpl.java  |    2 -
 .../java/data/TaskDataBinderImpl.java           |    8 +-
 .../java/job/AbstractSchedTaskJobDelegate.java  |  144 +++
 .../provisioning/java/job/AbstractTaskJob.java  |  216 ----
 .../java/job/AbstractTransactionalTaskJob.java  |   35 -
 .../core/provisioning/java/job/SampleJob.java   |   52 -
 .../java/job/SpringBeanJobFactory.java          |   12 +-
 .../core/provisioning/java/job/TaskJob.java     |  119 ++
 .../propagation/PropagationManagerImpl.java     |    6 +-
 .../java/sync/AbstractProvisioningJob.java      |  480 --------
 .../sync/AbstractProvisioningJobDelegate.java   |  434 +++++++
 .../java/sync/AbstractPushResultHandler.java    |    3 +-
 .../java/sync/AbstractSyncResultHandler.java    |    6 +-
 .../java/sync/AbstractSyncopeResultHandler.java |    2 +-
 .../provisioning/java/sync/PushJobDelegate.java |  192 +++
 .../provisioning/java/sync/PushJobImpl.java     |  189 ---
 .../provisioning/java/sync/SyncJobDelegate.java |  221 ++++
 .../provisioning/java/sync/SyncJobImpl.java     |  212 ----
 .../core/provisioning/java/sync/SyncUtils.java  |    2 +
 .../java/sync/UserSyncResultHandlerImpl.java    |    7 +-
 .../src/main/resources/provisioning.properties  |    3 +
 .../src/main/resources/provisioningContext.xml  |   27 +-
 .../src/main/resources/quartz/tables_h2.sql     |  266 ++++
 .../main/resources/quartz/tables_mariadb.sql    |  206 ++++
 .../src/main/resources/quartz/tables_mysql.sql  |  206 ++++
 .../resources/quartz/tables_mysql_innodb.sql    |  221 ++++
 .../src/main/resources/quartz/tables_oracle.sql |  208 ++++
 .../main/resources/quartz/tables_postgres.sql   |  204 ++++
 .../main/resources/quartz/tables_sqlServer.sql  |  296 +++++
 .../core/provisioning/java/AbstractTest.java    |    2 +
 .../provisioning/java/ConnectorManagerTest.java |    2 +-
 .../core/provisioning/java/TestInitializer.java |   37 +
 .../src/test/resources/provisioningTest.xml     |    7 +-
 .../rest/cxf/service/AbstractAnyService.java    |   14 +-
 .../rest/cxf/service/ConnectorServiceImpl.java  |    2 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |    2 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |    2 +-
 .../activiti/ActivitiDefinitionLoader.java      |   67 +-
 .../workflow/activiti/ActivitiImportUtils.java  |   35 +-
 .../activiti/ActivitiUserWorkflowAdapter.java   |  134 +--
 .../activiti/spring/DomainProcessEngine.java    |  102 ++
 .../spring/DomainProcessEngineFactoryBean.java  |  104 ++
 .../task/AbstractActivitiServiceTask.java       |    7 +-
 .../workflow/activiti/task/AutoActivate.java    |    2 +-
 .../core/workflow/activiti/task/Create.java     |    8 +-
 .../core/workflow/activiti/task/Delete.java     |    5 +-
 .../workflow/activiti/task/GenerateToken.java   |    5 +-
 .../core/workflow/activiti/task/Notify.java     |    9 +-
 .../workflow/activiti/task/PasswordReset.java   |   11 +-
 .../core/workflow/activiti/task/Update.java     |   12 +-
 .../main/resources/workflowActivitiContext.xml  |   17 +-
 .../core/workflow/api/UserWorkflowAdapter.java  |    6 +-
 .../java/AbstractAnyObjectWorkflowAdapter.java  |    3 +-
 .../java/AbstractGroupWorkflowAdapter.java      |    3 +-
 .../java/AbstractUserWorkflowAdapter.java       |    3 +-
 .../java/DefaultUserWorkflowAdapter.java        |    2 -
 .../core/logic/init/CamelRouteLoader.java       |   28 +-
 .../persistence/jpa/dao/JPACamelRouteDAO.java   |   10 +-
 .../CamelAnyObjectProvisioningManager.java      |   19 +
 .../camel/CamelGroupProvisioningManager.java    |   23 +-
 .../camel/CamelUserProvisioningManager.java     |   59 +-
 .../processor/AnyObjectCreateProcessor.java     |    2 +-
 .../processor/AnyObjectDeleteProcessor.java     |    2 +-
 .../AnyObjectDeprovisionProcessor.java          |    2 +-
 .../processor/AnyObjectProvisionProcessor.java  |   77 ++
 .../processor/AnyObjectUpdateProcessor.java     |    2 +-
 .../camel/processor/GroupCreateProcessor.java   |    2 +-
 .../camel/processor/GroupDeleteProcessor.java   |    2 +-
 .../processor/GroupDeprovisionProcessor.java    |    4 +-
 .../processor/GroupProvisionProcessor.java      |   77 ++
 .../camel/processor/GroupUpdateProcessor.java   |    2 +-
 .../processor/UserConfirmPwdResetProcessor.java |    7 +-
 .../camel/processor/UserCreateProcessor.java    |    2 +-
 .../camel/processor/UserDeleteProcessor.java    |    2 +-
 .../processor/UserDeprovisionProcessor.java     |    2 +-
 .../camel/processor/UserProvisionProcessor.java |   98 ++
 .../processor/UserSetStatusInSyncProcessor.java |    2 +-
 .../UserStatusPropagationProcessor.java         |   13 +-
 .../processor/UserUpdateInSyncProcessor.java    |    2 +-
 .../camel/processor/UserUpdateProcessor.java    |    2 +-
 .../src/main/resources/anyObjectRoutes.xml      |    6 +
 .../src/main/resources/groupRoutes.xml          |    6 +
 .../src/main/resources/userRoutes.xml           |    8 +-
 fit/core-reference/pom.xml                      |   12 +-
 .../fit/core/reference/TestSampleJob.java       |   64 -
 .../core/reference/TestSampleJobDelegate.java   |   64 +
 .../main/resources/all/provisioning.properties  |    6 +-
 .../src/main/resources/coreContext.xml          |    2 +
 .../src/main/resources/log4j2.xml               |   35 +-
 .../src/main/resources/provisioning.properties  |    4 +
 .../src/main/webapp/cacheStats.jsp              |    5 +-
 .../fit/core/reference/AnyTypeITCase.java       |    1 -
 .../core/reference/AuthenticationITCase.java    |   10 +-
 .../fit/core/reference/CamelRouteITCase.java    |    5 +-
 .../fit/core/reference/ConnectorITCase.java     |    2 +-
 .../core/reference/ExceptionMapperITCase.java   |    3 +-
 .../syncope/fit/core/reference/GroupITCase.java |   24 +-
 .../fit/core/reference/LoggerITCase.java        |    4 +-
 .../core/reference/PropagationTaskITCase.java   |    2 +-
 .../fit/core/reference/PushTaskITCase.java      |    5 +-
 .../fit/core/reference/ResourceITCase.java      |    2 +-
 .../fit/core/reference/SchedTaskITCase.java     |    5 +-
 .../fit/core/reference/SyncTaskITCase.java      |   26 +-
 .../syncope/fit/core/reference/UserITCase.java  |   54 +-
 255 files changed, 7689 insertions(+), 6435 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index e17fd2c..0e9cf4b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,13 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+sudo: false
 language: java
 jdk:
   - openjdk7
 # default install is mvn install --quiet -DskipTests=true
 install: mvn --show-version --quiet -P all,skipTests
 #invoker.streamLogs: we cannot access to log files through Travis web ui, so display everything in the console
-#script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
-script: mvn --show-version --quiet -PskipTests -Dinvoker.streamLogs=true
+script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
 notifications:
   webhooks: http://rovere.tirasa.net/cgi-bin/travis.cgi

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
index 5567094..ace19c8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
@@ -100,19 +100,19 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
 
             switch (action) {
                 case DELETE:
-                    bulkAction.setOperation(BulkAction.Type.DELETE);
+                    bulkAction.setType(BulkAction.Type.DELETE);
                     break;
                 case SUSPEND:
-                    bulkAction.setOperation(BulkAction.Type.SUSPEND);
+                    bulkAction.setType(BulkAction.Type.SUSPEND);
                     break;
                 case REACTIVATE:
-                    bulkAction.setOperation(BulkAction.Type.REACTIVATE);
+                    bulkAction.setType(BulkAction.Type.REACTIVATE);
                     break;
                 case EXECUTE:
-                    bulkAction.setOperation(BulkAction.Type.EXECUTE);
+                    bulkAction.setType(BulkAction.Type.EXECUTE);
                     break;
                 case DRYRUN:
-                    bulkAction.setOperation(BulkAction.Type.DRYRUN);
+                    bulkAction.setType(BulkAction.Type.DRYRUN);
                     break;
                 default:
                     LOG.error("Bulk action type not supported");
@@ -132,7 +132,7 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
                     } catch (NoSuchMethodException | SecurityException | IllegalAccessException 
                             | IllegalArgumentException | InvocationTargetException e) {
                         error(getString(Constants.ERROR)
-                                + ": Operation " + bulkAction.getOperation() + " not supported");
+                                + ": Operation " + bulkAction.getType() + " not supported");
                         feedbackPanel.refresh(target);
                     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
index 512e08f..4644fc0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/GroupRestClient.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -123,7 +123,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
     public void unlink(final String etag, final long groupKey, final List<StatusBean> statuses) {
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNLINK,
+            service.deassociate(groupKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(GroupService.class);
@@ -137,7 +137,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             ResourceAssociationMod associationMod = new ResourceAssociationMod();
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
-            service.bulkAssociation(groupKey, ResourceAssociationActionType.LINK, associationMod);
+            service.associate(groupKey, ResourceAssociationAction.LINK, associationMod);
 
             resetClient(GroupService.class);
         }
@@ -147,7 +147,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.DEPROVISION,
+            result = service.deassociate(groupKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -165,7 +165,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
 
-            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.PROVISION, associationMod).
+            result = service.associate(groupKey, ResourceAssociationAction.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
@@ -176,7 +176,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNASSIGN,
+            result = service.deassociate(groupKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -194,7 +194,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
 
-            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.ASSIGN, associationMod).
+            result = service.associate(groupKey, ResourceAssociationAction.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
 
             resetClient(GroupService.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
index 338851d..5c5c062 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserRestClient.java
@@ -32,7 +32,7 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -150,7 +150,7 @@ public class UserRestClient extends AbstractAnyRestClient {
     public void unlink(final String etag, final long userKey, final List<StatusBean> statuses) {
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNLINK,
+            service.deassociate(userKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(UserService.class);
@@ -164,7 +164,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             ResourceAssociationMod associationMod = new ResourceAssociationMod();
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
-            service.bulkAssociation(userKey, ResourceAssociationActionType.LINK, associationMod);
+            service.associate(userKey, ResourceAssociationAction.LINK, associationMod);
 
             resetClient(UserService.class);
         }
@@ -174,7 +174,7 @@ public class UserRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.DEPROVISION,
+            result = service.deassociate(userKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -196,7 +196,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userKey, ResourceAssociationActionType.PROVISION, associationMod).
+            result = service.associate(userKey, ResourceAssociationAction.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }
@@ -207,7 +207,7 @@ public class UserRestClient extends AbstractAnyRestClient {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNASSIGN,
+            result = service.deassociate(userKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -229,7 +229,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userKey, ResourceAssociationActionType.ASSIGN, associationMod).
+            result = service.associate(userKey, ResourceAssociationAction.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
----------------------------------------------------------------------
diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
index 9f8c734..bb6fcdf 100644
--- a/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
+++ b/client/old_console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.pages;
 
-import static org.apache.syncope.client.console.pages.AbstractBasePage.LOG;
-
 import java.io.File;
 import java.io.Serializable;
 import java.util.ArrayList;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
index a514dcb..5b46616 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkAction.java
@@ -46,19 +46,19 @@ public class BulkAction extends AbstractBaseBean {
 
     }
 
-    private Type operation;
+    private Type type;
 
     /**
      * Serialized identifiers.
      */
     private final List<String> targets = new ArrayList<>();
 
-    public Type getOperation() {
-        return operation;
+    public Type getType() {
+        return type;
     }
 
-    public void setOperation(final Type operation) {
-        this.operation = operation;
+    public void setType(final Type type) {
+        this.type = type;
     }
 
     @XmlElementWrapper(name = "targets")

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
index abea52d..08e4c53 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
@@ -33,7 +33,7 @@ public class SchedTaskTO extends AbstractTaskTO {
 
     private String cronExpression;
 
-    private String jobClassName;
+    private String jobDelegateClassName;
 
     private String name;
 
@@ -51,12 +51,12 @@ public class SchedTaskTO extends AbstractTaskTO {
         this.cronExpression = cronExpression;
     }
 
-    public String getJobClassName() {
-        return jobClassName;
+    public String getJobDelegateClassName() {
+        return jobDelegateClassName;
     }
 
-    public void setJobClassName(final String jobClassName) {
-        this.jobClassName = jobClassName;
+    public void setJobDelegateClassName(final String jobDelegateClassName) {
+        this.jobDelegateClassName = jobDelegateClassName;
     }
 
     @SuppressWarnings("CPD-START")

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
index 5f2fd1e..e1e7333 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
@@ -24,6 +24,10 @@ import java.util.List;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.common.lib.annotation.SchemaList;
 
 @XmlType
@@ -80,4 +84,19 @@ public abstract class AbstractPolicySpec implements PolicySpec {
         return suffixesNotPermitted;
     }
 
+    @Override
+    public boolean equals(final Object obj) {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
index 323ea09..c3d4af5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditElements.java
@@ -26,6 +26,10 @@ public final class AuditElements implements Serializable {
 
     private static final long serialVersionUID = -4385059255522273254L;
 
+    public static final String AUTHENTICATION_CATEGORY = "Authentication";
+
+    public static final String LOGIN_EVENT = "login";
+
     @XmlEnum
     public enum EventCategoryType {
 
@@ -55,4 +59,8 @@ public final class AuditElements implements Serializable {
         FAILURE
 
     }
+
+    private AuditElements() {
+        // private constructor for static utility class
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
index f77ed81..f129a7d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/LoggerType.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.common.lib.types;
 
 import javax.xml.bind.annotation.XmlEnum;
+import org.apache.commons.lang3.StringUtils;
 
 @XmlEnum
 public enum LoggerType {
@@ -26,7 +27,7 @@ public enum LoggerType {
     /**
      * This type describes a common logger used to handle system and application events.
      */
-    LOG(""),
+    LOG(StringUtils.EMPTY),
     /**
      * Audit logger only focus on security related events, usually logging how did what and when.
      * In case of a security incident audit loggers should allow an administrator to recall all
@@ -34,7 +35,7 @@ public enum LoggerType {
      */
     AUDIT("syncope.audit");
 
-    private String prefix;
+    private final String prefix;
 
     LoggerType(final String prefix) {
         this.prefix = prefix;

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java
new file mode 100644
index 0000000..efbe0ef
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationAction.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum ResourceAssociationAction {
+
+    /**
+     * Link user/group/any object on Syncope and external resource(s) without any propagation.
+     */
+    LINK,
+    /**
+     * Send user/group/any object data to external resource(s).
+     */
+    PROVISION,
+    /**
+     * Assign (link + provision) external resource(s) to user/group/any object.
+     */
+    ASSIGN
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java
deleted file mode 100644
index 3d7955d..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ResourceAssociationActionType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.syncope.common.lib.types;
-
-import javax.xml.bind.annotation.XmlEnum;
-
-@XmlEnum
-public enum ResourceAssociationActionType {
-
-    /**
-     * Add association between user/group on Syncope and external resource(s) without any propagation.
-     */
-    LINK,
-    /**
-     * Add user/group into external resource(s).
-     */
-    PROVISION,
-    /**
-     * Assign (link + provision) external resource(s) with user/group.
-     */
-    ASSIGN
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
index 94bf21f..3cdf1fa 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
@@ -57,9 +57,9 @@ public final class CollectionWrapper {
 
     public static List<AuditLoggerName> wrapLogger(final Collection<LoggerTO> logger) {
         List<AuditLoggerName> respons = new ArrayList<>();
-        for (LoggerTO l : logger) {
+        for (LoggerTO loggerTO : logger) {
             try {
-                respons.add(AuditLoggerName.fromLoggerName(l.getKey()));
+                respons.add(AuditLoggerName.fromLoggerName(loggerTO.getKey()));
             } catch (Exception ignore) {
                 // ignore
             }
@@ -69,9 +69,9 @@ public final class CollectionWrapper {
 
     public static List<LoggerTO> unwrapLogger(final Collection<AuditLoggerName> auditNames) {
         List<LoggerTO> respons = new ArrayList<>();
-        for (AuditLoggerName l : auditNames) {
+        for (AuditLoggerName name : auditNames) {
             LoggerTO loggerTO = new LoggerTO();
-            loggerTO.setKey(l.toLoggerName());
+            loggerTO.setKey(name.toLoggerName());
             loggerTO.setLevel(LoggerLevel.DEBUG);
             respons.add(loggerTO);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
index 93167cb..1c0fda2 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -39,7 +39,7 @@ import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
@@ -150,7 +150,7 @@ public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSS
     @Path("{key}/deassociate/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(
+    Response deassociate(
             @NotNull @PathParam("key") Long key,
             @NotNull @PathParam("type") ResourceDeassociationActionType type,
             @NotNull List<ResourceKey> resourceNames);
@@ -171,9 +171,9 @@ public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSS
     @Path("{key}/associate/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(
+    Response associate(
             @NotNull @PathParam("key") Long key,
-            @NotNull @PathParam("type") ResourceAssociationActionType type,
+            @NotNull @PathParam("type") ResourceAssociationAction type,
             @NotNull ResourceAssociationMod associationMod);
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/pom.xml
----------------------------------------------------------------------
diff --git a/core/logic/pom.xml b/core/logic/pom.xml
index 60ba05f..7ce109f 100644
--- a/core/logic/pom.xml
+++ b/core/logic/pom.xml
@@ -153,6 +153,13 @@ under the License.
         <filtering>true</filtering>
       </testResource>
       <testResource>
+        <directory>${basedir}/../persistence-jpa/src/main/resources</directory>
+        <includes>
+          <include>persistence.properties</include>
+        </includes>
+        <filtering>true</filtering>
+      </testResource>
+      <testResource>
         <directory>${basedir}/../persistence-jpa/src/test/resources</directory>
         <filtering>true</filtering>
       </testResource>
@@ -161,6 +168,21 @@ under the License.
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <inherited>true</inherited>
+        <executions>
+          <execution>
+            <id>set-bundles</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
       </plugin>
     </plugins>

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 05db8b5..38927ce 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -55,7 +55,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
@@ -96,7 +95,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("isAuthenticated()")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int count(final List<String> realms) {
         return anyObjectDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms));
@@ -133,7 +132,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
@@ -142,7 +141,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<AnyObjectTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
@@ -239,29 +238,26 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO unlink(final Long anyObjectKey, final Collection<String> resources) {
         AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToRemove().addAll(resources);
-        final Long updatedResult = provisioningManager.unlink(anyObjectMod);
 
-        return binder.getAnyObjectTO(updatedResult);
+        return binder.getAnyObjectTO(provisioningManager.unlink(anyObjectMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO link(final Long anyObjectKey, final Collection<String> resources) {
         AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToAdd().addAll(resources);
+
         return binder.getAnyObjectTO(provisioningManager.link(anyObjectMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO unassign(final Long anyObjectKey, final Collection<String> resources) {
         AnyObjectMod anyObjectMod = new AnyObjectMod();
@@ -271,44 +267,41 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public AnyObjectTO assign(final Long anyObjectKey, final Collection<String> resources,
-            final boolean changePwd, final String password) {
+    public AnyObjectTO assign(
+            final Long key,
+            final Collection<String> resources,
+            final boolean changepwd,
+            final String password) {
 
-        AnyObjectMod userMod = new AnyObjectMod();
-        userMod.setKey(anyObjectKey);
-        userMod.getResourcesToAdd().addAll(resources);
-        return update(userMod);
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(key);
+        anyObjectMod.getResourcesToAdd().addAll(resources);
+
+        return update(anyObjectMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public AnyObjectTO deprovision(final Long anyObjectKey, final Collection<String> resources) {
-        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+    public AnyObjectTO deprovision(final Long key, final Collection<String> resources) {
+        List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
-        List<PropagationStatus> statuses = provisioningManager.deprovision(anyObjectKey, resources);
-
-        AnyObjectTO updatedTO = binder.getAnyObjectTO(anyObject, true);
+        AnyObjectTO updatedTO = binder.getAnyObjectTO(key);
         updatedTO.getPropagationStatusTOs().addAll(statuses);
         return updatedTO;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public AnyObjectTO provision(final Long anyObjectKey, final Collection<String> resources,
-            final boolean changePwd, final String password) {
-
-        AnyObjectTO original = binder.getAnyObjectTO(anyObjectKey);
+    public AnyObjectTO provision(
+            final Long key,
+            final Collection<String> resources,
+            final boolean changePwd,
+            final String password) {
 
-        //trick: assign and retrieve propagation statuses ...
-        original.getPropagationStatusTOs().addAll(
-                assign(anyObjectKey, resources, changePwd, password).getPropagationStatusTOs());
+        AnyObjectTO original = binder.getAnyObjectTO(key);
+        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
 
-        // .... rollback.
-        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
         return original;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
index 7d28c88..1598498 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConfTO;
 import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.persistence.api.content.ContentExporter;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -97,7 +98,7 @@ public class ConfigurationLogic extends AbstractTransactionalLogic<ConfTO> {
     @Transactional(readOnly = true)
     public void export(final OutputStream os) {
         try {
-            exporter.export(os, uwfAdapter.getPrefix(), gwfAdapter.getPrefix());
+            exporter.export(AuthContextUtils.getDomain(), os, uwfAdapter.getPrefix(), gwfAdapter.getPrefix());
             LOG.debug("Database content successfully exported");
         } catch (Exception e) {
             LOG.error("While exporting database content", e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index f476210..33b0447 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -56,7 +56,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
@@ -114,7 +113,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("isAuthenticated()")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int count(final List<String> realms) {
         return groupDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms));
@@ -140,7 +139,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
@@ -149,7 +148,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<GroupTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
@@ -256,75 +255,70 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO unlink(final Long groupKey, final Collection<String> resources) {
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupKey);
         groupMod.getResourcesToRemove().addAll(resources);
-        final Long updatedResult = provisioningManager.unlink(groupMod);
 
-        return binder.getGroupTO(updatedResult);
+        return binder.getGroupTO(provisioningManager.unlink(groupMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO link(final Long groupKey, final Collection<String> resources) {
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupKey);
         groupMod.getResourcesToAdd().addAll(resources);
+
         return binder.getGroupTO(provisioningManager.link(groupMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO unassign(final Long groupKey, final Collection<String> resources) {
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(groupKey);
         groupMod.getResourcesToRemove().addAll(resources);
         return update(groupMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO assign(
-            final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) {
+            final Long key,
+            final Collection<String> resources,
+            final boolean changepwd,
+            final String password) {
 
-        final GroupMod userMod = new GroupMod();
-        userMod.setKey(groupKey);
-        userMod.getResourcesToAdd().addAll(resources);
-        return update(userMod);
+        GroupMod groupMod = new GroupMod();
+        groupMod.setKey(key);
+        groupMod.getResourcesToAdd().addAll(resources);
+
+        return update(groupMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
-    public GroupTO deprovision(final Long groupKey, final Collection<String> resources) {
-        final Group group = groupDAO.authFind(groupKey);
-
-        List<PropagationStatus> statuses = provisioningManager.deprovision(groupKey, resources);
+    public GroupTO deprovision(final Long key, final Collection<String> resources) {
+        List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
-        GroupTO updatedTO = binder.getGroupTO(group, true);
+        GroupTO updatedTO = binder.getGroupTO(key);
         updatedTO.getPropagationStatusTOs().addAll(statuses);
         return updatedTO;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public GroupTO provision(
-            final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) {
-        GroupTO original = binder.getGroupTO(groupKey);
+            final Long key,
+            final Collection<String> resources,
+            final boolean changePwd,
+            final String password) {
 
-        //trick: assign and retrieve propagation statuses ...
-        original.getPropagationStatusTOs().addAll(
-                assign(groupKey, resources, changePwd, password).getPropagationStatusTOs());
+        GroupTO original = binder.getGroupTO(key);
+        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, resources));
 
-        // .... rollback.
-        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
         return original;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index 4b5aac8..d407dba 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -46,6 +46,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
@@ -55,8 +56,9 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.Logger;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -255,10 +257,10 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
                 }
             }
 
-            //SYNCOPE-608
+            // SYNCOPE-608
             EventCategoryTO authenticationControllerEvents = new EventCategoryTO();
-            authenticationControllerEvents.setCategory("AuthenticationController");
-            authenticationControllerEvents.getEvents().add("login");
+            authenticationControllerEvents.setCategory(AuditElements.AUTHENTICATION_CATEGORY);
+            authenticationControllerEvents.getEvents().add(AuditElements.LOGIN_EVENT);
             events.add(authenticationControllerEvents);
 
             events.add(new EventCategoryTO(EventCategoryType.PROPAGATION));
@@ -305,15 +307,17 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
 
             for (SchedTask task : taskDAO.<SchedTask>findAll(TaskType.SCHEDULED)) {
                 EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
-                eventCategoryTO.setCategory(Class.forName(task.getJobClassName()).getSimpleName());
+                eventCategoryTO.setCategory(Class.forName(task.getJobDelegateClassName()).getSimpleName());
                 events.add(eventCategoryTO);
             }
 
-            for (SyncTask task : taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION)) {
-                EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
-                eventCategoryTO.setCategory(Class.forName(task.getJobClassName()).getSimpleName());
-                events.add(eventCategoryTO);
-            }
+            EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
+            eventCategoryTO.setCategory(SyncJobDelegate.class.getSimpleName());
+            events.add(eventCategoryTO);
+
+            eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
+            eventCategoryTO.setCategory(PushJobDelegate.class.getSimpleName());
+            events.add(eventCategoryTO);
         } catch (Exception e) {
             LOG.error("Failure retrieving audit/notification events", e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index bc8fb0f..8dd20a8 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -131,7 +131,7 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
         syncopeTO.getReportlets().addAll(
                 classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET));
         syncopeTO.getTaskJobs().addAll(
-                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOB));
+                classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOBDELEGATE));
         syncopeTO.getPropagationActions().addAll(
                 classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PROPAGATION_ACTIONS));
         syncopeTO.getSyncActions().addAll(

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 82dc8d1..9c119f3 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
@@ -51,15 +52,15 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
-import org.apache.syncope.core.logic.notification.NotificationJob;
+import org.apache.syncope.core.logic.notification.NotificationJobDelegate;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
 import org.quartz.JobDataMap;
 import org.quartz.JobKey;
 import org.quartz.Scheduler;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 
@@ -73,21 +74,21 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     private TaskExecDAO taskExecDAO;
 
     @Autowired
+    private ConfDAO confDAO;
+
+    @Autowired
     private TaskDataBinder binder;
 
     @Autowired
     private PropagationTaskExecutor taskExecutor;
 
     @Autowired
-    private NotificationJob notificationJob;
+    private NotificationJobDelegate notificationJobDelegate;
 
     @Autowired
     private JobInstanceLoader jobInstanceLoader;
 
     @Autowired
-    private SchedulerFactoryBean scheduler;
-
-    @Autowired
     private TaskUtilsFactory taskUtilsFactory;
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_CREATE + "')")
@@ -98,7 +99,9 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
         task = taskDAO.save(task);
 
         try {
-            jobInstanceLoader.registerJob(task, task.getJobClassName(), task.getCronExpression());
+            jobInstanceLoader.registerJob(
+                    task,
+                    confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue());
         } catch (Exception e) {
             LOG.error("While registering quartz job for task " + task.getKey(), e);
 
@@ -128,7 +131,9 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
         task = taskDAO.save(task);
 
         try {
-            jobInstanceLoader.registerJob(task, task.getJobClassName(), task.getCronExpression());
+            jobInstanceLoader.registerJob(
+                    task,
+                    confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue());
         } catch (Exception e) {
             LOG.error("While registering quartz job for task " + task.getKey(), e);
 
@@ -163,28 +168,28 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_READ + "')")
-    public <T extends AbstractTaskTO> T read(final Long taskId) {
-        Task task = taskDAO.find(taskId);
+    public <T extends AbstractTaskTO> T read(final Long taskKey) {
+        Task task = taskDAO.find(taskKey);
         if (task == null) {
-            throw new NotFoundException("Task " + taskId);
+            throw new NotFoundException("Task " + taskKey);
         }
         return binder.getTaskTO(task, taskUtilsFactory.getInstance(task));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_READ + "')")
-    public TaskExecTO readExecution(final Long executionId) {
-        TaskExec taskExec = taskExecDAO.find(executionId);
+    public TaskExecTO readExecution(final Long execKey) {
+        TaskExec taskExec = taskExecDAO.find(execKey);
         if (taskExec == null) {
-            throw new NotFoundException("Task execution " + executionId);
+            throw new NotFoundException("Task execution " + execKey);
         }
         return binder.getTaskExecTO(taskExec);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_EXECUTE + "')")
-    public TaskExecTO execute(final Long taskId, final boolean dryRun) {
-        Task task = taskDAO.find(taskId);
+    public TaskExecTO execute(final Long taskKey, final boolean dryRun) {
+        Task task = taskDAO.find(taskKey);
         if (task == null) {
-            throw new NotFoundException("Task " + taskId);
+            throw new NotFoundException("Task " + taskKey);
         }
         TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
@@ -196,7 +201,7 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
                 break;
 
             case NOTIFICATION:
-                final TaskExec notExec = notificationJob.executeSingle((NotificationTask) task);
+                final TaskExec notExec = notificationJobDelegate.executeSingle((NotificationTask) task);
                 result = binder.getTaskExecTO(notExec);
                 break;
 
@@ -204,15 +209,14 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
             case SYNCHRONIZATION:
             case PUSH:
                 try {
-                    jobInstanceLoader.registerJob(task,
-                            ((SchedTask) task).getJobClassName(),
-                            ((SchedTask) task).getCronExpression());
-
-                    JobDataMap map = new JobDataMap();
-                    map.put(TaskJob.DRY_RUN_JOBDETAIL_KEY, dryRun);
+                    Map<String, Object> jobDataMap = jobInstanceLoader.registerJob(
+                            (SchedTask) task,
+                            confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue());
 
+                    jobDataMap.put(TaskJob.DRY_RUN_JOBDETAIL_KEY, dryRun);
                     scheduler.getScheduler().triggerJob(
-                            new JobKey(JobNamer.getJobName(task), Scheduler.DEFAULT_GROUP), map);
+                            new JobKey(JobNamer.getJobName(task), Scheduler.DEFAULT_GROUP),
+                            new JobDataMap(jobDataMap));
                 } catch (Exception e) {
                     LOG.error("While executing task {}", task, e);
 
@@ -222,7 +226,7 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
                 }
 
                 result = new TaskExecTO();
-                result.setTask(taskId);
+                result.setTask(taskKey);
                 result.setStartDate(new Date());
                 result.setStatus("JOB_FIRED");
                 result.setMessage("Job fired; waiting for results...");
@@ -235,10 +239,10 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_READ + "')")
-    public TaskExecTO report(final Long executionId, final PropagationTaskExecStatus status, final String message) {
-        TaskExec exec = taskExecDAO.find(executionId);
+    public TaskExecTO report(final Long execKey, final PropagationTaskExecStatus status, final String message) {
+        TaskExec exec = taskExecDAO.find(execKey);
         if (exec == null) {
-            throw new NotFoundException("Task execution " + executionId);
+            throw new NotFoundException("Task execution " + execKey);
         }
 
         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPropagationTaskExecReport);
@@ -277,10 +281,10 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_DELETE + "')")
-    public <T extends AbstractTaskTO> T delete(final Long taskId) {
-        Task task = taskDAO.find(taskId);
+    public <T extends AbstractTaskTO> T delete(final Long taskKey) {
+        Task task = taskDAO.find(taskKey);
         if (task == null) {
-            throw new NotFoundException("Task " + taskId);
+            throw new NotFoundException("Task " + taskKey);
         }
         TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
@@ -298,10 +302,10 @@ public class TaskLogic extends AbstractJobLogic<AbstractTaskTO> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.TASK_DELETE + "')")
-    public TaskExecTO deleteExecution(final Long executionId) {
-        TaskExec taskExec = taskExecDAO.find(executionId);
+    public TaskExecTO deleteExecution(final Long execKey) {
+        TaskExec taskExec = taskExecDAO.find(execKey);
         if (taskExec == null) {
-            throw new NotFoundException("Task execution " + executionId);
+            throw new NotFoundException("Task execution " + execKey);
         }
 
         TaskExecTO taskExecutionToDelete = binder.getTaskExecTO(taskExec);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 3aec28c..28e7401 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -60,7 +60,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
@@ -100,17 +99,19 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     protected SyncopeLogic syncopeLogic;
 
     @PreAuthorize("hasRole('" + Entitlement.USER_READ + "')")
+    @Transactional(readOnly = true)
     public String getUsername(final Long key) {
         return binder.getUserTO(key).getUsername();
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_READ + "')")
+    @Transactional(readOnly = true)
     public Long getKey(final String username) {
         return binder.getUserTO(username).getKey();
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_LIST + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int count(final List<String> realms) {
         return userDAO.count(
@@ -118,7 +119,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_LIST + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<UserTO> list(
             final int page, final int size, final List<OrderByClause> orderBy,
@@ -152,7 +153,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public int searchCount(final SearchCond searchCondition, final List<String> realms) {
         return searchDAO.count(
@@ -161,7 +162,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_SEARCH + "')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    @Transactional(readOnly = true)
     @Override
     public List<UserTO> search(final SearchCond searchCondition, final int page, final int size,
             final List<OrderByClause> orderBy, final List<String> realms, final boolean details) {
@@ -242,22 +243,21 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
         return updatedTO;
     }
 
-    protected Map.Entry<Long, List<PropagationStatus>> setStatusOnWfAdapter(final User user,
-            final StatusMod statusMod) {
+    protected Map.Entry<Long, List<PropagationStatus>> setStatusOnWfAdapter(final StatusMod statusMod) {
         Map.Entry<Long, List<PropagationStatus>> updated;
 
         switch (statusMod.getType()) {
             case SUSPEND:
-                updated = provisioningManager.suspend(user, statusMod);
+                updated = provisioningManager.suspend(statusMod);
                 break;
 
             case REACTIVATE:
-                updated = provisioningManager.reactivate(user, statusMod);
+                updated = provisioningManager.reactivate(statusMod);
                 break;
 
             case ACTIVATE:
             default:
-                updated = provisioningManager.activate(user, statusMod);
+                updated = provisioningManager.activate(statusMod);
                 break;
 
         }
@@ -266,11 +266,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     public UserTO status(final StatusMod statusMod) {
-        User user = userDAO.authFind(statusMod.getKey());
-
-        Map.Entry<Long, List<PropagationStatus>> updated = setStatusOnWfAdapter(user, statusMod);
+        Map.Entry<Long, List<PropagationStatus>> updated = setStatusOnWfAdapter(statusMod);
         final UserTO savedTO = binder.getUserTO(updated.getKey());
         savedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return savedTO;
@@ -304,7 +301,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
         if (user == null) {
             throw new NotFoundException("User with token " + token);
         }
-        provisioningManager.confirmPasswordReset(user, token, password);
+        provisioningManager.confirmPasswordReset(user.getKey(), token, password);
     }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + Entitlement.ANONYMOUS + "'))")
@@ -332,9 +329,8 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
 
         List<PropagationStatus> statuses = provisioningManager.delete(key);
 
-        final UserTO deletedTO;
-        User deleted = userDAO.find(key);
-        if (deleted == null) {
+        UserTO deletedTO;
+        if (userDAO.find(key) == null) {
             deletedTO = new UserTO();
             deletedTO.setKey(key);
         } else {
@@ -346,39 +342,35 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO unlink(final Long key, final Collection<String> resources) {
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToRemove().addAll(resources);
-        Long updatedKey = provisioningManager.unlink(userMod);
 
-        return binder.getUserTO(updatedKey);
+        return binder.getUserTO(provisioningManager.unlink(userMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO link(final Long key, final Collection<String> resources) {
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToAdd().addAll(resources);
+
         return binder.getUserTO(provisioningManager.link(userMod));
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO unassign(final Long key, final Collection<String> resources) {
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToRemove().addAll(resources);
         return update(userMod);
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO assign(
             final Long key,
@@ -386,7 +378,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
             final boolean changepwd,
             final String password) {
 
-        final UserMod userMod = new UserMod();
+        UserMod userMod = new UserMod();
         userMod.setKey(key);
         userMod.getResourcesToAdd().addAll(resources);
 
@@ -402,20 +394,16 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(rollbackFor = { Throwable.class })
     @Override
     public UserTO deprovision(final Long key, final Collection<String> resources) {
-        User user = userDAO.authFind(key);
-
         List<PropagationStatus> statuses = provisioningManager.deprovision(key, resources);
 
-        final UserTO updatedUserTO = binder.getUserTO(user, true);
-        updatedUserTO.getPropagationStatusTOs().addAll(statuses);
-        return updatedUserTO;
+        UserTO updatedTO = binder.getUserTO(key);
+        updatedTO.getPropagationStatusTOs().addAll(statuses);
+        return updatedTO;
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
-    @Transactional(readOnly = true)
     @Override
     public UserTO provision(
             final Long key,
@@ -423,14 +411,9 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
             final boolean changePwd,
             final String password) {
 
-        final UserTO original = binder.getUserTO(key);
-
-        //trick: assign and retrieve propagation statuses ...
-        original.getPropagationStatusTOs().addAll(
-                assign(key, resources, changePwd, password).getPropagationStatusTOs());
+        UserTO original = binder.getUserTO(key);
+        original.getPropagationStatusTOs().addAll(provisioningManager.provision(key, changePwd, password, resources));
 
-        // .... rollback.
-        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
         return original;
     }