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/06/05 17:11:52 UTC

[17/21] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 73a7896..6a67ccf 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -51,6 +51,7 @@ import org.apache.syncope.core.misc.ExceptionUtils2;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
@@ -72,9 +73,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public abstract class AbstractPropagationTaskExecutor implements PropagationTaskExecutor {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationTaskExecutor.class);
 
     /**
@@ -299,9 +297,11 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             Any<?, ?, ?> any = getAny(task);
             Collection<String> resources = any instanceof User
                     ? userDAO.findAllResourceNames((User) any)
-                    : any instanceof Group
-                            ? ((Group) any).getResourceNames()
-                            : Collections.<String>emptySet();
+                    : any instanceof AnyObject
+                            ? anyObjectDAO.findAllResourceNames((AnyObject) any)
+                            : any instanceof Group
+                                    ? ((Group) any).getResourceNames()
+                                    : Collections.<String>emptySet();
             if (!resources.contains(task.getResource().getKey())) {
                 LOG.debug("Delete {} on {}", beforeObj.getUid(), task.getResource().getKey());
 
@@ -339,13 +339,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         Connector connector = null;
         Result result;
         try {
-            Any<?, ?, ?> any = getAny(task);
-            provision = task.getResource().getProvision(any.getType());
-            if (provision == null) {
-                throw new IllegalArgumentException("No provision found for " + any.getType() + " on " + task.
-                        getResource());
-            }
-
+            provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName()));
             connector = connFactory.getConnector(task.getResource());
 
             // Try to read remote object BEFORE any actual operation

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 6d795d8..6dbd0eb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -46,7 +46,7 @@ import org.springframework.transaction.annotation.Transactional;
  * Simple action for propagating group memberships to LDAP groups, when the same resource is configured for both users
  * and groups.
  *
- * @see org.apache.syncope.core.sync.impl.LDAPMembershipSyncActions
+ * @see org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions
  */
 public class LDAPMembershipPropagationActions extends DefaultPropagationActions {
 
@@ -85,7 +85,7 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
 
                         JexlContext jexlContext = new MapContext();
                         JexlUtils.addFieldsToContext(group, jexlContext);
-                        JexlUtils.addAttrsToContext(group.getPlainAttrs(), jexlContext);
+                        JexlUtils.addPlainAttrsToContext(group.getPlainAttrs(), jexlContext);
                         JexlUtils.addDerAttrsToContext(group.getDerAttrs(), group.getPlainAttrs(), jexlContext);
 
                         String groupConnObjectLinkLink =

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 8f52059..2649623 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
@@ -30,7 +30,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
@@ -45,7 +44,6 @@ 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.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.java.VirAttrHandler;
 import org.apache.syncope.core.misc.ConnObjectUtils;
 import org.apache.syncope.core.misc.MappingUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
@@ -57,6 +55,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -71,9 +70,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public class PropagationManagerImpl implements PropagationManager {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class);
 
     protected AnyObjectDAO anyObjectDAO;
@@ -129,7 +125,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
         AnyObject anyObject = anyObjectDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(anyObject, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+            virAttrHandler.fillVirtual(anyObject, vAttrs);
         }
 
         return getCreateTaskIds(anyObject, null, null, propByRes, noPropResourceNames);
@@ -146,7 +142,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
         User user = userDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(user, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.USER));
+            virAttrHandler.fillVirtual(user, vAttrs);
         }
         return getCreateTaskIds(user, password, enable, propByRes, noPropResourceNames);
     }
@@ -169,7 +165,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
         Group group = groupDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(group, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
+            virAttrHandler.fillVirtual(group, vAttrs);
         }
 
         return getCreateTaskIds(group, null, null, propByRes, noPropResourceNames);
@@ -287,11 +283,13 @@ public class PropagationManagerImpl implements PropagationManager {
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
             final PropagationByResource propByRes, final Collection<String> noPropResourceNames) {
 
-        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(any, vAttrsToBeRemoved == null
-                ? Collections.<String>emptySet()
-                : vAttrsToBeRemoved, vAttrsToBeUpdated == null
+        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(
+                any,
+                vAttrsToBeRemoved == null
+                        ? Collections.<String>emptySet()
+                        : vAttrsToBeRemoved, vAttrsToBeUpdated == null
                         ? Collections.<AttrMod>emptySet()
-                        : vAttrsToBeUpdated, anyUtilsFactory.getInstance(any));
+                        : vAttrsToBeUpdated);
 
         if (propByRes == null || propByRes.isEmpty()) {
             localPropByRes.addAll(ResourceOperation.UPDATE, any.getResourceNames());
@@ -419,7 +417,7 @@ public class PropagationManagerImpl implements PropagationManager {
         if (!propByRes.get(ResourceOperation.CREATE).isEmpty()
                 && vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
 
-            connObjectUtils.retrieveVirAttrValues(any);
+            virAttrHandler.retrieveVirAttrValues(any);
 
             // update vAttrsToBeUpdated as well
             for (VirAttr<?> virAttr : any.getVirAttrs()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 4f7b744..8f80ac0 100644
--- 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
@@ -302,7 +302,8 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 append(' ').
                 append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
                 append(' ').
-                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size());
+                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(' ').

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 275f648..fd5a482 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
@@ -116,14 +116,13 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         Object output = null;
         Result resultStatus = null;
-        ConnectorObject beforeObj = null;
         String operation = null;
 
-        // Try to read remote object (user / group) BEFORE any actual operation
+        // Try to read remote object BEFORE any actual operation
         Provision provision = profile.getTask().getResource().getProvision(any.getType());
         String connObjecKey = MappingUtils.getConnObjectKeyValue(any, provision);
 
-        beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
+        ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
 
         Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
 
@@ -186,7 +185,6 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                         default:
                         // do nothing
                     }
-
                 } else {
                     operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
                     result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 1ead6a7..6d8986a 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
@@ -109,7 +109,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
         anyTO.getResources().add(profile.getTask().getResource().getKey());
 
-        final ProvisioningResult result = new ProvisioningResult();
+        ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
@@ -149,7 +149,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
-        final ProvisioningResult result = new ProvisioningResult();
+        ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
@@ -270,7 +270,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                             workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyMod);
                         }
 
-                        final AnyTO updated = doUpdate(before, anyMod, workingDelta, result);
+                        AnyTO updated = doUpdate(before, anyMod, workingDelta, result);
 
                         for (SyncActions action : profile.getActions()) {
                             action.after(this.getProfile(), workingDelta, updated, result);
@@ -335,13 +335,13 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             Object output;
             Result resultStatus;
 
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.DELETE);
             result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(id);
 
-            final AnyTO before = getAnyTO(id);
+            AnyTO before = getAnyTO(id);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
@@ -427,8 +427,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
         final List<ProvisioningResult> updResults = new ArrayList<>();
 
-        for (Long id : anys) {
-            LOG.debug("About to unassign resource {}", id);
+        for (Long key : anys) {
+            LOG.debug("About to unassign resource {}", key);
 
             Object output;
             Result resultStatus;
@@ -437,13 +437,13 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             result.setOperation(ResourceOperation.NONE);
             result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
-            result.setKey(id);
+            result.setKey(key);
 
-            final AnyTO before = getAnyTO(id);
+            AnyTO before = getAnyTO(key);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), id));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
             }
 
             if (!profile.isDryRun()) {
@@ -471,7 +471,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         }
 
                         resultStatus = Result.SUCCESS;
-                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), id);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
@@ -527,11 +527,10 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             Object output;
             Result resultStatus = Result.FAILURE;
 
-            AnyTO before = null;
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
 
             try {
-                before = getAnyTO(id);
+                AnyTO before = getAnyTO(id);
 
                 result.setKey(id);
                 result.setName(getName(before));
@@ -590,7 +589,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
 
         final List<ProvisioningResult> ignoreResults = new ArrayList<>();
-        final ProvisioningResult result = new ProvisioningResult();
+        ProvisioningResult result = new ProvisioningResult();
 
         result.setKey(null);
         result.setName(delta.getObject().getUid().getUidValue());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fccecc4..cf08d8d 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
@@ -49,10 +49,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions>
         implements SyncopeResultHandler<T, A> {
 
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeResultHandler.class);
 
     @Autowired
     protected AnyObjectDAO anyObjectDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
index b6d5ccb..860e10b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
@@ -36,7 +36,7 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 
 public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implements GroupSyncResultHandler {
 
-    protected Map<Long, String> groupOwnerMap = new HashMap<>();
+    protected final Map<Long, String> groupOwnerMap = new HashMap<>();
 
     @Override
     public Map<Long, String> getGroupOwnerMap() {
@@ -107,7 +107,7 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
         // moved after group provisioning manager
         String groupOwner = null;
         for (AttrMod attrMod : groupMod.getPlainAttrsToUpdate()) {
-            if (attrMod.getSchema().isEmpty()) {
+            if (attrMod.getSchema().isEmpty() && !attrMod.getValuesToBeAdded().isEmpty()) {
                 groupOwner = attrMod.getValuesToBeAdded().iterator().next();
             }
         }
@@ -115,7 +115,7 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
             groupOwnerMap.put(updated.getKey(), groupOwner);
         }
 
-        final GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
+        GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
 
         result.setName(getName(after));
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
index fb2f9a4..873232f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
@@ -46,6 +46,7 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.misc.AuditManager;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
@@ -63,7 +64,7 @@ import org.springframework.beans.factory.annotation.Autowired;
  * Simple action for synchronizing LDAP groups memberships to Syncope group memberships, when the same resource is
  * configured for both users and groups.
  *
- * @see org.apache.syncope.core.propagation.impl.LDAPMembershipPropagationActions
+ * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions
  */
 public class LDAPMembershipSyncActions extends DefaultSyncActions {
 
@@ -73,6 +74,9 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
     protected AnyTypeDAO anyTypeDAO;
 
     @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
     protected GroupDAO groupDAO;
 
     @Autowired
@@ -182,7 +186,7 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
         Attribute membAttr = delta.getObject().getAttributeByName(groupMemberName);
         // if not found, perform an additional read on the underlying connector for the same connector object
         if (membAttr == null) {
-            final OperationOptionsBuilder oob = new OperationOptionsBuilder();
+            OperationOptionsBuilder oob = new OperationOptionsBuilder();
             oob.setAttributesToGet(groupMemberName);
             membAttr = connector.getObjectAttribute(ObjectClass.GROUP, delta.getUid(), oob.build(), groupMemberName);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index b13213a..b658bc4 100644
--- 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
@@ -27,7 +27,6 @@ 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.persistence.api.entity.user.User;
 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;
@@ -39,7 +38,9 @@ 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;
@@ -111,15 +112,20 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
         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 rhandler =
+        GroupPushResultHandler ghandler =
                 (GroupPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
                 createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        rhandler.setProfile(profile);
+        ghandler.setProfile(profile);
 
         if (actions != null && !profile.isDryRun()) {
             for (PushActions action : actions) {
@@ -138,16 +144,32 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
                 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.<User>search(SyncopeConstants.FULL_ADMIN_REALMS,
+                            : 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 {
-                            uhandler.handle(any.getKey());
+                            handler.handle(any.getKey());
                         } catch (Exception e) {
-                            LOG.warn("Failure pushing user '{}' on '{}'", any, pushTask.getResource(), e);
-                            throw new JobExecutionException("While pushing users on connector", e);
+                            LOG.warn("Failure pushing '{}' on '{}'", any, pushTask.getResource(), e);
+                            throw new JobExecutionException(
+                                    "While pushing " + any + " on " + pushTask.getResource(), e);
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 1e19d02..479d342 100644
--- 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
@@ -60,8 +60,8 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
     @Autowired
     protected SyncUtils syncUtils;
 
-    protected void setGroupOwners(final GroupSyncResultHandler rhandler) {
-        for (Map.Entry<Long, String> entry : rhandler.getGroupOwnerMap().entrySet()) {
+    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
+        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
             GroupMod groupMod = new GroupMod();
             groupMod.setKey(entry.getKey());
 
@@ -72,15 +72,15 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
                 Long userKey = syncUtils.findMatchingAnyKey(
                         anyTypeDAO.findUser(),
                         entry.getValue(),
-                        rhandler.getProfile().getTask().getResource(),
-                        rhandler.getProfile().getConnector());
+                        ghandler.getProfile().getTask().getResource(),
+                        ghandler.getProfile().getConnector());
 
                 if (userKey == null) {
                     Long groupKey = syncUtils.findMatchingAnyKey(
                             anyTypeDAO.findGroup(),
                             entry.getValue(),
-                            rhandler.getProfile().getTask().getResource(),
-                            rhandler.getProfile().getConnector());
+                            ghandler.getProfile().getTask().getResource(),
+                            ghandler.getProfile().getConnector());
 
                     if (groupKey != null) {
                         groupMod.setGroupOwner(new ReferenceMod(groupKey));

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 8982824..b748345 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
@@ -32,9 +32,7 @@ import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValid
 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.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 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.AnyCond;
@@ -69,52 +67,40 @@ import org.springframework.stereotype.Component;
 @Component
 public class SyncUtils {
 
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
-
-    /**
-     * Policy DAO.
-     */
-    @Autowired
-    protected PolicyDAO policyDAO;
+    private static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
 
     /**
      * Schema DAO.
      */
     @Autowired
-    protected PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
+    private PlainSchemaDAO plainSchemaDAO;
 
     /**
      * Any Object DAO.
      */
     @Autowired
-    protected AnyObjectDAO anyObjectDAO;
+    private AnyObjectDAO anyObjectDAO;
 
     /**
      * User DAO.
      */
     @Autowired
-    protected UserDAO userDAO;
+    private UserDAO userDAO;
 
     /**
      * Group DAO.
      */
     @Autowired
-    protected GroupDAO groupDAO;
+    private GroupDAO groupDAO;
 
     /**
      * Search DAO.
      */
     @Autowired
-    protected AnySearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     @Autowired
-    protected AnyUtilsFactory anyUtilsFactory;
+    private AnyUtilsFactory anyUtilsFactory;
 
     public Long findMatchingAnyKey(
             final AnyType anyType,
@@ -180,7 +166,8 @@ public class SyncUtils {
         switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-                final PlainAttrValue value = anyUtils.newPlainAttrValue();
+            case AnyPlainSchema:
+                PlainAttrValue value = anyUtils.newPlainAttrValue();
 
                 PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
                 if (schema == null) {
@@ -203,21 +190,24 @@ public class SyncUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
+            case AnyDerivedSchema:
                 anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), uid);
                 for (Any<?, ?, ?> any : anys) {
                     result.add(any.getKey());
                 }
                 break;
 
-            case Username:
-                User user = userDAO.find(uid);
-                if (user != null) {
-                    result.add(user.getKey());
+            case UserId:
+            case GroupId:
+            case AnyId:
+                Any<?, ?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(uid));
+                if (any != null) {
+                    result.add(any.getKey());
                 }
                 break;
 
-            case UserId:
-                user = userDAO.find(Long.parseLong(uid));
+            case Username:
+                User user = userDAO.find(uid);
                 if (user != null) {
                     result.add(user.getKey());
                 }
@@ -230,13 +220,6 @@ public class SyncUtils {
                 }
                 break;
 
-            case GroupId:
-                group = groupDAO.find(Long.parseLong(uid));
-                if (group != null) {
-                    result.add(group.getKey());
-                }
-                break;
-
             default:
                 LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
         }
@@ -354,7 +337,7 @@ public class SyncUtils {
     }
 
     /**
-     * Find users / groups based on mapped uid value (or previous uid value, if updated).
+     * Find any objects based on mapped uid value (or previous uid value, if updated).
      *
      * @param uid for finding by connObjectKey
      * @param connObj for finding by attribute value
@@ -381,9 +364,10 @@ public class SyncUtils {
             altSearchSchemas = getAltSearchSchemas(provision, syncPolicySpec);
         }
 
-        return syncRule == null ? altSearchSchemas == null || altSearchSchemas.isEmpty()
-                ? findByConnObjectKeyItem(uid, provision, anyUtils)
-                : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils)
+        return syncRule == null
+                ? altSearchSchemas == null || altSearchSchemas.isEmpty()
+                        ? findByConnObjectKeyItem(uid, provision, anyUtils)
+                        : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils)
                 : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
index 039337f..f2eb839 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderTest.java
@@ -79,7 +79,7 @@ public class ResourceDataBinderTest extends AbstractTest {
 
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey("resource-issue42");
-        resourceTO.setConnectorId(100L);
+        resourceTO.setConnector(100L);
         resourceTO.setPropagationMode(PropagationMode.ONE_PHASE);
         resourceTO.setEnforceMandatoryCondition(true);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index f031c92..18f6101 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -51,6 +51,7 @@ import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValid
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.dao.MalformedPathException;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UnallowedSchemaException;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.identityconnectors.framework.common.exceptions.ConfigurationException;
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
@@ -114,6 +115,8 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception>, R
                     header(HttpHeaders.WWW_AUTHENTICATE, BASIC_REALM_UNAUTHORIZED);
         } else if (ex instanceof UnauthorizedException) {
             builder = builder(ClientExceptionType.Unauthorized, ExceptionUtils.getRootCauseMessage(ex));
+        } else if (ex instanceof UnallowedSchemaException) {
+            builder = builder(ClientExceptionType.UnallowedSchemas, ExceptionUtils.getRootCauseMessage(ex));
         } else if (ex instanceof EntityExistsException || ex instanceof DuplicateException) {
             builder = builder(ClientExceptionType.EntityExists, getJPAMessage(ex));
         } else if (ex instanceof DataIntegrityViolationException || ex instanceof JpaSystemException) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
new file mode 100644
index 0000000..47cdde2
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.core.logic.AnyTypeClassLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyTypeClassServiceImpl extends AbstractServiceImpl implements AnyTypeClassService {
+
+    @Autowired
+    private AnyTypeClassLogic logic;
+
+    @Override
+    public List<AnyTypeClassTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public AnyTypeClassTO read(final String key) {
+        return logic.read(key);
+    }
+
+    @Override
+    public Response create(final AnyTypeClassTO anyTypeTO) {
+        AnyTypeClassTO created = logic.create(anyTypeTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final String key, final AnyTypeClassTO anyTypeTO) {
+        anyTypeTO.setKey(key);
+        logic.update(anyTypeTO);
+    }
+
+    @Override
+    public void delete(final String key) {
+        logic.delete(key);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
new file mode 100644
index 0000000..9b289d5
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.core.logic.AnyTypeLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyTypeServiceImpl extends AbstractServiceImpl implements AnyTypeService {
+
+    @Autowired
+    private AnyTypeLogic logic;
+
+    @Override
+    public List<AnyTypeTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public AnyTypeTO read(final String key) {
+        return logic.read(key);
+    }
+
+    @Override
+    public Response create(final AnyTypeTO anyTypeTO) {
+        AnyTypeTO created = logic.create(anyTypeTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final String key, final AnyTypeTO anyTypeTO) {
+        anyTypeTO.setKey(key);
+        logic.update(anyTypeTO);
+    }
+
+    @Override
+    public void delete(final String key) {
+        logic.delete(key);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 618b245..9f6099c 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
@@ -135,12 +135,13 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
         BulkActionResult result = new BulkActionResult();
 
         if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String id : bulkAction.getTargets()) {
+            for (String key : bulkAction.getTargets()) {
                 try {
-                    result.add(logic.delete(Long.valueOf(id)).getKey(), BulkActionResult.Status.SUCCESS);
+                    result.getResults().put(
+                            String.valueOf(logic.delete(Long.valueOf(key)).getKey()), BulkActionResult.Status.SUCCESS);
                 } catch (Exception e) {
-                    LOG.error("Error performing delete for connector {}", id, e);
-                    result.add(id, BulkActionResult.Status.FAILURE);
+                    LOG.error("Error performing delete for connector {}", key, e);
+                    result.getResults().put(key, BulkActionResult.Status.FAILURE);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
index c8e42a1..5c640f0 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
@@ -155,21 +155,23 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
                 updated = logic.read(groupKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceDeassociationActionType.UNLINK) {
             for (ResourceName resourceName : resourceNames) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -198,21 +200,23 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
                 updated = logic.read(groupKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceAssociationActionType.LINK) {
             for (ResourceName resourceName : resourceNames) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -222,10 +226,12 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
         if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
             for (String groupKey : bulkAction.getTargets()) {
                 try {
-                    result.add(logic.delete(Long.valueOf(groupKey)).getKey(), BulkActionResult.Status.SUCCESS);
+                    result.getResults().put(
+                            String.valueOf(logic.delete(Long.valueOf(groupKey)).getKey()),
+                            BulkActionResult.Status.SUCCESS);
                 } catch (Exception e) {
                     LOG.error("Error performing delete for group {}", groupKey, e);
-                    result.add(groupKey, BulkActionResult.Status.FAILURE);
+                    result.getResults().put(groupKey, BulkActionResult.Status.FAILURE);
                 }
             }
         } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 7ace502..28b834b 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
@@ -107,7 +107,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
                         ? groupLogic
                         : anyObjectLogic;
 
-        BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         for (AnyKey key : keys) {
             Set<String> resources = Collections.singleton(resourceKey);
@@ -128,14 +128,14 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
                     default:
                 }
 
-                res.add(key, BulkActionResult.Status.SUCCESS);
+                result.getResults().put(String.valueOf(key.getElement()), BulkActionResult.Status.SUCCESS);
             } catch (Exception e) {
                 LOG.warn("While executing {} on {} {}", type, anyTypeKey, key.getElement(), e);
-                res.add(key, BulkActionResult.Status.FAILURE);
+                result.getResults().put(String.valueOf(key.getElement()), BulkActionResult.Status.FAILURE);
             }
         }
 
-        return res;
+        return result;
     }
 
     @Override
@@ -145,10 +145,10 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
         if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
             for (String name : bulkAction.getTargets()) {
                 try {
-                    result.add(logic.delete(name).getKey(), BulkActionResult.Status.SUCCESS);
+                    result.getResults().put(logic.delete(name).getKey(), BulkActionResult.Status.SUCCESS);
                 } catch (Exception e) {
                     LOG.error("Error performing delete for resource {}", name, e);
-                    result.add(name, BulkActionResult.Status.FAILURE);
+                    result.getResults().put(name, BulkActionResult.Status.FAILURE);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 9da72aa..d42ed6a 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
@@ -129,10 +129,12 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
             case DELETE:
                 for (String taskKey : bulkAction.getTargets()) {
                     try {
-                        result.add(logic.delete(Long.valueOf(taskKey)).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.delete(Long.valueOf(taskKey)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing delete for task {}", taskKey, e);
-                        result.add(taskKey, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -141,10 +143,10 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
                 for (String taskKey : bulkAction.getTargets()) {
                     try {
                         logic.execute(Long.valueOf(taskKey), true);
-                        result.add(taskKey, BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(taskKey, BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing dryrun for task {}", taskKey, e);
-                        result.add(taskKey, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -153,10 +155,10 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
                 for (String taskKey : bulkAction.getTargets()) {
                     try {
                         logic.execute(Long.valueOf(taskKey), false);
-                        result.add(taskKey, BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(taskKey, BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing execute for task {}", taskKey, e);
-                        result.add(taskKey, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index 919cb0a..83f09a4 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -60,7 +60,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     }
 
     @Override
-    public Response getUserId(final String username) {
+    public Response getUserKey(final String username) {
         return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
                 header(RESTHeaders.USER_ID, logic.getKey(username)).
                 build();
@@ -179,21 +179,23 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                 updated = logic.read(userKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceDeassociationActionType.UNLINK) {
             for (ResourceName resourceName : resourceNames) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(
+                        resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -232,21 +234,23 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                 updated = logic.read(userKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceAssociationActionType.LINK) {
             for (ResourceName resourceName : associationMod.getTargetResources()) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -257,10 +261,12 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
             case DELETE:
                 for (String key : bulkAction.getTargets()) {
                     try {
-                        result.add(logic.delete(Long.valueOf(key)).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing delete for user {}", key, e);
-                        result.add(key, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -271,10 +277,11 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                     statusMod.setKey(Long.valueOf(key));
                     statusMod.setType(StatusMod.ModType.SUSPEND);
                     try {
-                        result.add(logic.status(statusMod).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing suspend for user {}", key, e);
-                        result.add(key, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -285,10 +292,11 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                     statusMod.setKey(Long.valueOf(key));
                     statusMod.setType(StatusMod.ModType.REACTIVATE);
                     try {
-                        result.add(logic.status(statusMod).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing reactivate for user {}", key, e);
-                        result.add(key, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 938081f..2e00cb9 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
@@ -84,15 +84,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
- * Activiti {
- *
- * @see http://www.activiti.org/} based implementation.
+ * Activiti {@link http://www.activiti.org/} based implementation.
  */
 public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ActivitiUserWorkflowAdapter.class);
 
     private static final String[] PROPERTY_IGNORE_PROPS = { "type" };
@@ -258,7 +253,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     public WorkflowResult<Pair<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
             final Boolean enabled, final boolean storePassword) {
 
-        final Map<String, Object> variables = new HashMap<>();
+        Map<String, Object> variables = new HashMap<>();
         variables.put(WF_EXECUTOR, AuthContextUtils.getAuthenticatedUsername());
         variables.put(USER_TO, userTO);
         variables.put(ENABLED, enabled);
@@ -271,8 +266,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             throwException(e, "While starting " + WF_PROCESS_ID + " instance");
         }
 
-        User user =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
+        User user = runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
 
         Boolean updatedEnabled =
                 runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.java
new file mode 100644
index 0000000..f598410
--- /dev/null
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.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.core.workflow.activiti;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.springframework.transaction.annotation.Transactional;
+
+public class ActivitiUtils {
+
+    @Transactional(readOnly = true)
+    public boolean isUserIngroup(final User user, final Long groupKey) {
+        return CollectionUtils.exists(user.getMemberships(), new Predicate<UMembership>() {
+
+            @Override
+            public boolean evaluate(final UMembership membership) {
+                return groupKey != null && groupKey.equals(membership.getRightEnd().getKey());
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
index 2b568b1..658795c 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
@@ -75,8 +75,8 @@ public class SyncopeUserManager implements UserIdentityManager, SyncopeSession {
         org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.find(userKey);
         if (user != null) {
             result = new ArrayList<>();
-            for (Long groupId : userDAO.findAllGroupKeys(user)) {
-                result.add(new GroupEntity(groupId.toString()));
+            for (Long groupKey : userDAO.findAllGroupKeys(user)) {
+                result.add(new GroupEntity(groupKey.toString()));
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 d5e9b02..75f0c38 100644
--- a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -30,6 +30,8 @@ under the License.
     <property name="fallback" value="classpath:userWorkflow.bpmn20.xml"/>
   </bean>
 
+  <bean id="activitiUtils" class="org.apache.syncope.core.workflow.activiti.ActivitiUtils"/>
+
   <bean id="syncopeActivitiUserManager" class="org.apache.syncope.core.workflow.activiti.SyncopeUserManager"/>
   <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.core.workflow.activiti.SyncopeGroupManager"/>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 7a2f455..2aaec2a 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
@@ -18,14 +18,18 @@
  */
 package org.apache.syncope.core.provisioning.camel.processor;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 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;
@@ -47,15 +51,30 @@ public class GroupUpdateProcessor implements Processor {
     @Autowired
     protected PropagationTaskExecutor taskExecutor;
 
+    @Autowired
+    protected VirAttrHandler virtAttrHandler;
+
     @SuppressWarnings("unchecked")
     @Override
     public void process(final Exchange exchange) {
         WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
-        GroupMod anyMod = exchange.getProperty("anyMod", GroupMod.class);
+        GroupMod groupMod = exchange.getProperty("anyMod", GroupMod.class);
         Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 
         List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
-                anyMod.getVirAttrsToRemove(), anyMod.getVirAttrsToUpdate(), excludedResources);
+                groupMod.getVirAttrsToRemove(), groupMod.getVirAttrsToUpdate(), excludedResources);
+        if (tasks.isEmpty()) {
+            // SYNCOPE-459: take care of user virtual attributes ...
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+                    updated.getResult(),
+                    AnyTypeKind.GROUP,
+                    groupMod.getVirAttrsToRemove(),
+                    groupMod.getVirAttrsToUpdate());
+            tasks.addAll(!propByResVirAttr.isEmpty()
+                    ? propagationManager.getGroupUpdateTasks(updated, null, null, null)
+                    : Collections.<PropagationTask>emptyList());
+        }
+
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 355080b..e71a15a 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
@@ -25,15 +25,16 @@ 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.UserMod;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 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.apache.syncope.core.provisioning.java.VirAttrHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -57,15 +58,16 @@ public class UserUpdateProcessor implements Processor {
     @SuppressWarnings("unchecked")
     public void process(final Exchange exchange) {
         WorkflowResult<Pair<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
-        UserMod actual = exchange.getProperty("actual", UserMod.class);
+        UserMod userMod = exchange.getProperty("actual", UserMod.class);
 
         List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated);
         if (tasks.isEmpty()) {
             // SYNCOPE-459: take care of user virtual attributes ...
-            final PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
                     updated.getResult().getKey().getKey(),
-                    actual.getVirAttrsToRemove(),
-                    actual.getVirAttrsToUpdate());
+                    AnyTypeKind.USER,
+                    userMod.getVirAttrsToRemove(),
+                    userMod.getVirAttrsToUpdate());
             tasks.addAll(!propByResVirAttr.isEmpty()
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 5061502..4d0ecaf 100644
--- a/fit/core-reference/src/main/resources/all/provisioning.properties
+++ b/fit/core-reference/src/main/resources/all/provisioning.properties
@@ -18,4 +18,4 @@ 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
+virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml b/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
index 9a6ee5b..df292b8 100644
--- a/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
+++ b/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
@@ -34,10 +34,14 @@ under the License.
     <sequenceFlow id="flow2" sourceRef="create" targetRef="createGW"/>
     <exclusiveGateway id="createGW"/>
     <sequenceFlow id="createAsAnonymous2Approval" sourceRef="createGW" targetRef="createApproval">
-      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == 'anonymous' || user.getStaticGroupKeys().contains(9)}]]></conditionExpression>
+      <conditionExpression xsi:type="tFormalExpression">
+        <![CDATA[${wfExecutor == 'anonymous' || activitiUtils.isUserIngroup(user, 9)}]]>
+      </conditionExpression>
     </sequenceFlow>
     <sequenceFlow id="create2Activate" sourceRef="createGW" targetRef="enableGW">
-      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!user.getStaticGroupKeys().contains(9)}]]></conditionExpression>
+      <conditionExpression xsi:type="tFormalExpression">
+        <![CDATA[${!activitiUtils.isUserIngroup(user, 9)}]]>
+      </conditionExpression>
     </sequenceFlow>
     <userTask id="createApproval" name="Create approval" activiti:candidateGroups="7" activiti:formKey="createApproval">
       <extensionElements>
@@ -56,7 +60,9 @@ under the License.
     </sequenceFlow>
     <exclusiveGateway id="enableGW"/>
     <sequenceFlow id="createApprovalGW2OptIn" sourceRef="enableGW" targetRef="generateToken">
-      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${user.getStaticGroupKeys().contains(11)}]]></conditionExpression>
+      <conditionExpression xsi:type="tFormalExpression">
+        <![CDATA[${activitiUtils.isUserIngroup(user, 11)}]]>
+      </conditionExpression>
     </sequenceFlow>
     <sequenceFlow id="createApprovalGW2Activate" sourceRef="enableGW" targetRef="activate">
       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled == null}]]></conditionExpression>

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
index 3984c5e..97fc9d0 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java
@@ -48,6 +48,8 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
 import org.apache.syncope.common.rest.api.service.ConfigurationService;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
@@ -147,6 +149,10 @@ public abstract class AbstractITCase {
 
     protected static SyncopeService syncopeService;
 
+    protected static AnyTypeClassService anyTypeClassService;
+
+    protected static AnyTypeService anyTypeService;
+
     protected static RealmService realmService;
 
     protected static RoleService roleService;
@@ -217,6 +223,8 @@ public abstract class AbstractITCase {
         adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
 
         syncopeService = adminClient.getService(SyncopeService.class);
+        anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
+        anyTypeService = adminClient.getService(AnyTypeService.class);
         realmService = adminClient.getService(RealmService.class);
         roleService = adminClient.getService(RoleService.class);
         userService = adminClient.getService(UserService.class);
@@ -272,7 +280,7 @@ public abstract class AbstractITCase {
 
     protected UserTO readUser(final String username) {
         return userService.read(Long.valueOf(
-                userService.getUserId(username).getHeaderString(RESTHeaders.USER_ID)));
+                userService.getUserKey(username).getHeaderString(RESTHeaders.USER_ID)));
     }
 
     protected UserTO updateUser(final UserMod userMod) {
@@ -361,7 +369,7 @@ public abstract class AbstractITCase {
             throws NamingException {
         ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
         final Map<String, ConnConfProperty> ldapConnConf =
-                connectorService.read(ldapRes.getConnectorId()).getConfigurationMap();
+                connectorService.read(ldapRes.getConnector()).getConfigurationMap();
 
         Properties env = new Properties();
         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");