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/11 16:16:56 UTC

[06/70] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/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 d21afc5..400b72e 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
@@ -26,29 +26,19 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+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;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 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.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -59,6 +49,14 @@ 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;
+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.AnyUtils;
+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.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -78,6 +76,8 @@ public class PropagationManagerImpl implements PropagationManager {
      */
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class);
 
+    protected AnyObjectDAO anyObjectDAO;
+
     /**
      * User DAO.
      */
@@ -106,39 +106,38 @@ public class PropagationManagerImpl implements PropagationManager {
     protected ConnObjectUtils connObjectUtils;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
     @Autowired
     protected VirAttrHandler virAttrHandler;
 
     @Override
+    public List<PropagationTask> getAnyObjectCreateTasks(
+            final Long key,
+            final Collection<AttrTO> vAttrs,
+            final PropagationByResource propByRes,
+            final List<String> noPropResourceNames) {
+
+        AnyObject anyObject = anyObjectDAO.authFind(key);
+        if (vAttrs != null && !vAttrs.isEmpty()) {
+            virAttrHandler.fillVirtual(anyObject, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        }
+
+        return getCreateTaskIds(anyObject, null, null, propByRes, noPropResourceNames);
+    }
+
+    @Override
     public List<PropagationTask> getUserCreateTasks(
             final Long key,
             final Boolean enable,
             final PropagationByResource propByRes,
             final String password,
             final Collection<AttrTO> vAttrs,
-            final Collection<MembershipTO> membershipTOs,
             final Collection<String> noPropResourceNames) {
 
-        User user = userDAO.authFetch(key);
+        User user = userDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(user, vAttrs, attrUtilsFactory.getInstance(AttributableType.USER));
-        }
-        for (final Membership membership : user.getMemberships()) {
-            if (membership.getVirAttrs() != null && !membership.getVirAttrs().isEmpty()) {
-                MembershipTO membershipTO = CollectionUtils.find(membershipTOs, new Predicate<MembershipTO>() {
-
-                    @Override
-                    public boolean evaluate(final MembershipTO membershipTO) {
-                        return membershipTO.getGroupKey() == membership.getGroup().getKey();
-                    }
-                });
-                if (membershipTO != null) {
-                    virAttrHandler.fillVirtual(membership,
-                            membershipTO.getVirAttrs(), attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP));
-                }
-            }
+            virAttrHandler.fillVirtual(user, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.USER));
         }
         return getCreateTaskIds(user, password, enable, propByRes, noPropResourceNames);
     }
@@ -176,15 +175,15 @@ public class PropagationManagerImpl implements PropagationManager {
             final PropagationByResource propByRes,
             final Collection<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(key);
+        Group group = groupDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(group, vAttrs, attrUtilsFactory.getInstance(AttributableType.GROUP));
+            virAttrHandler.fillVirtual(group, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
         }
 
         return getCreateTaskIds(group, null, null, propByRes, noPropResourceNames);
     }
 
-    protected List<PropagationTask> getCreateTaskIds(final Subject<?, ?, ?> subject,
+    protected List<PropagationTask> getCreateTaskIds(final Any<?, ?, ?> any,
             final String password, final Boolean enable,
             final PropagationByResource propByRes,
             final Collection<String> noPropResourceNames) {
@@ -197,7 +196,7 @@ public class PropagationManagerImpl implements PropagationManager {
             propByRes.get(ResourceOperation.CREATE).removeAll(noPropResourceNames);
         }
 
-        return createTasks(subject, password, true, null, null, null, null, enable, false, propByRes);
+        return createTasks(any, password, true, null, null, enable, false, propByRes);
     }
 
     /**
@@ -220,8 +219,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 Collections.<String>emptySet(), // no virtual attributes to be managed
                 Collections.<AttrMod>emptySet(), // no virtual attributes to be managed
                 null, // no propagation by resources
-                noPropResourceNames,
-                Collections.<MembershipMod>emptySet());
+                noPropResourceNames);
     }
 
     /**
@@ -236,7 +234,7 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getUserUpdateTasks(final WorkflowResult<Pair<UserMod, Boolean>> wfResult,
             final boolean changePwd, final Collection<String> noPropResourceNames) {
 
-        User user = userDAO.authFetch(wfResult.getResult().getKey().getKey());
+        User user = userDAO.authFind(wfResult.getResult().getKey().getKey());
         return getUpdateTasks(user,
                 wfResult.getResult().getKey().getPassword(),
                 changePwd,
@@ -244,8 +242,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 wfResult.getResult().getKey().getVirAttrsToRemove(),
                 wfResult.getResult().getKey().getVirAttrsToUpdate(),
                 wfResult.getPropByRes(),
-                noPropResourceNames,
-                wfResult.getResult().getKey().getMembershipsToAdd());
+                noPropResourceNames);
     }
 
     @Override
@@ -264,7 +261,7 @@ public class PropagationManagerImpl implements PropagationManager {
             origPropByRes.merge(wfResult.getPropByRes());
 
             Set<String> pwdResourceNames = new HashSet<>(userMod.getPwdPropRequest().getResourceNames());
-            Collection<String> currentResourceNames = userDAO.findAllResourceNames(userDAO.authFetch(userMod.getKey()));
+            Collection<String> currentResourceNames = userDAO.findAllResourceNames(userDAO.authFind(userMod.getKey()));
             pwdResourceNames.retainAll(currentResourceNames);
             PropagationByResource pwdPropByRes = new PropagationByResource();
             pwdPropByRes.addAll(ResourceOperation.UPDATE, pwdResourceNames);
@@ -292,55 +289,25 @@ public class PropagationManagerImpl implements PropagationManager {
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
             final Set<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(wfResult.getResult());
+        Group group = groupDAO.authFind(wfResult.getResult());
         return getUpdateTasks(group, null, false, null,
-                vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames,
-                Collections.<MembershipMod>emptySet());
+                vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames);
     }
 
     @Override
-    public List<PropagationTask> getUpdateTasks(final Subject<?, ?, ?> subject,
+    public List<PropagationTask> getUpdateTasks(final Any<?, ?, ?> any,
             final String password, final boolean changePwd, final Boolean enable,
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
-            final PropagationByResource propByRes, final Collection<String> noPropResourceNames,
-            final Set<MembershipMod> membershipsToAdd) {
+            final PropagationByResource propByRes, final Collection<String> noPropResourceNames) {
 
-        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(subject, vAttrsToBeRemoved == null
+        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(any, vAttrsToBeRemoved == null
                 ? Collections.<String>emptySet()
                 : vAttrsToBeRemoved, vAttrsToBeUpdated == null
                         ? Collections.<AttrMod>emptySet()
-                        : vAttrsToBeUpdated, attrUtilsFactory.getInstance(subject));
-
-        // SYNCOPE-458 fill membership virtual attributes
-        Collection<String> resourceNames;
-        if (subject instanceof User) {
-            User user = (User) subject;
-            resourceNames = userDAO.findAllResourceNames(user);
-            for (final Membership membership : user.getMemberships()) {
-                if (membership.getVirAttrs() != null && !membership.getVirAttrs().isEmpty()) {
-                    MembershipMod membMod = CollectionUtils.find(membershipsToAdd, new Predicate<MembershipMod>() {
-
-                        @Override
-                        public boolean evaluate(final MembershipMod membershipMod) {
-                            return membershipMod.getGroup() == membership.getGroup().getKey();
-                        }
-                    });
-                    if (membMod != null) {
-                        virAttrHandler.fillVirtual(membership, membMod.getVirAttrsToRemove() == null
-                                ? Collections.<String>emptySet()
-                                : membMod.getVirAttrsToRemove(),
-                                membMod.getVirAttrsToUpdate() == null ? Collections.<AttrMod>emptySet()
-                                        : membMod.getVirAttrsToUpdate(), attrUtilsFactory.getInstance(
-                                        AttributableType.MEMBERSHIP));
-                    }
-                }
-            }
-        } else {
-            resourceNames = subject.getResourceNames();
-        }
+                        : vAttrsToBeUpdated, anyUtilsFactory.getInstance(any));
 
         if (propByRes == null || propByRes.isEmpty()) {
-            localPropByRes.addAll(ResourceOperation.UPDATE, resourceNames);
+            localPropByRes.addAll(ResourceOperation.UPDATE, any.getResourceNames());
         } else {
             localPropByRes.merge(propByRes);
         }
@@ -357,29 +324,26 @@ public class PropagationManagerImpl implements PropagationManager {
             }
         }
 
-        // SYNCOPE-458 fill membership virtual attributes to be updated map
-        Map<String, AttrMod> membVAttrsToBeUpdatedMap = new HashMap<>();
-        for (MembershipMod membershipMod : membershipsToAdd) {
-            for (AttrMod attrMod : membershipMod.getVirAttrsToUpdate()) {
-                membVAttrsToBeUpdatedMap.put(attrMod.getSchema(), attrMod);
-            }
-        }
+        return createTasks(
+                any, password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdatedMap, enable, false, localPropByRes);
+    }
 
-        // SYNCOPE-458 fill membership virtual attributes to be removed set
-        final Set<String> membVAttrsToBeRemoved = new HashSet<>();
-        for (MembershipMod membershipMod : membershipsToAdd) {
-            membVAttrsToBeRemoved.addAll(membershipMod.getVirAttrsToRemove());
-        }
+    @Override
+    public List<PropagationTask> getAnyObjectDeleteTasks(final Long anyObjectKey, final String noPropResourceName) {
+        return getAnyObjectDeleteTasks(anyObjectKey, Collections.<String>singleton(noPropResourceName));
+    }
+
+    @Override
+    public List<PropagationTask> getAnyObjectDeleteTasks(
+            final Long anyObjectKey, final Collection<String> noPropResourceNames) {
 
-        return createTasks(subject, password, changePwd,
-                vAttrsToBeRemoved, vAttrsToBeUpdatedMap, membVAttrsToBeRemoved, membVAttrsToBeUpdatedMap, enable, false,
-                localPropByRes);
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        return getDeleteTaskIds(anyObject, anyObject.getResourceNames(), noPropResourceNames);
     }
 
     @Override
     public List<PropagationTask> getUserDeleteTasks(final Long userKey, final Collection<String> noPropResourceNames) {
-
-        User user = userDAO.authFetch(userKey);
+        User user = userDAO.authFind(userKey);
         return getDeleteTaskIds(user, userDAO.findAllResourceNames(user), noPropResourceNames);
     }
 
@@ -387,25 +351,23 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getUserDeleteTasks(
             final Long userKey, final Set<String> resourceNames, final Collection<String> noPropResourceNames) {
 
-        User user = userDAO.authFetch(userKey);
+        User user = userDAO.authFind(userKey);
         return getDeleteTaskIds(user, resourceNames, noPropResourceNames);
     }
 
     @Override
     public List<PropagationTask> getUserDeleteTasks(final WorkflowResult<Long> wfResult) {
-        User user = userDAO.authFetch(wfResult.getResult());
-        return createTasks(user, null, false, null, null, null, null, false, true, wfResult.getPropByRes());
+        User user = userDAO.authFind(wfResult.getResult());
+        return createTasks(user, null, false, null, null, false, true, wfResult.getPropByRes());
     }
 
     @Override
     public List<PropagationTask> getGroupDeleteTasks(final Long groupKey) {
-
         return getGroupDeleteTasks(groupKey, Collections.<String>emptySet());
     }
 
     @Override
     public List<PropagationTask> getGroupDeleteTasks(final Long groupKey, final String noPropResourceName) {
-
         return getGroupDeleteTasks(groupKey, Collections.<String>singleton(noPropResourceName));
     }
 
@@ -413,7 +375,7 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getGroupDeleteTasks(
             final Long groupKey, final Collection<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
         return getDeleteTaskIds(group, group.getResourceNames(), noPropResourceNames);
     }
 
@@ -421,12 +383,12 @@ public class PropagationManagerImpl implements PropagationManager {
     public List<PropagationTask> getGroupDeleteTasks(
             final Long groupKey, final Set<String> resourceNames, final Collection<String> noPropResourceNames) {
 
-        Group group = groupDAO.authFetch(groupKey);
+        Group group = groupDAO.authFind(groupKey);
         return getDeleteTaskIds(group, resourceNames, noPropResourceNames);
     }
 
     protected List<PropagationTask> getDeleteTaskIds(
-            final Subject<?, ?, ?> subject,
+            final Any<?, ?, ?> any,
             final Collection<String> resourceNames,
             final Collection<String> noPropResourceNames) {
 
@@ -435,41 +397,38 @@ public class PropagationManagerImpl implements PropagationManager {
         if (noPropResourceNames != null && !noPropResourceNames.isEmpty()) {
             propByRes.get(ResourceOperation.DELETE).removeAll(noPropResourceNames);
         }
-        return createTasks(subject, null, false, null, null, null, null, false, true, propByRes);
+        return createTasks(any, null, false, null, null, false, true, propByRes);
     }
 
     /**
      * Create propagation tasks.
      *
-     * @param subject user / group to be provisioned
+     * @param any user / group to be provisioned
      * @param password cleartext password to be provisioned
      * @param changePwd whether password should be included for propagation attributes or not
      * @param vAttrsToBeRemoved virtual attributes to be removed
      * @param vAttrsToBeUpdated virtual attributes to be added
-     * @param membVAttrsToBeRemoved membership virtual attributes to be removed
-     * @param membVAttrsToBeUpdatedMap membership virtual attributes to be added
      * @param enable whether user must be enabled or not
      * @param deleteOnResource whether user / group must be deleted anyway from external resource or not
      * @param propByRes operation to be performed per resource
      * @return list of propagation tasks created
      */
-    protected List<PropagationTask> createTasks(final Subject<?, ?, ?> subject,
+    protected List<PropagationTask> createTasks(final Any<?, ?, ?> any,
             final String password, final boolean changePwd,
             final Set<String> vAttrsToBeRemoved, final Map<String, AttrMod> vAttrsToBeUpdated,
-            final Set<String> membVAttrsToBeRemoved, final Map<String, AttrMod> membVAttrsToBeUpdatedMap,
             final Boolean enable, final boolean deleteOnResource, final PropagationByResource propByRes) {
 
-        LOG.debug("Provisioning subject {}:\n{}", subject, propByRes);
+        LOG.debug("Provisioning any {}:\n{}", any, propByRes);
 
-        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(subject);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
 
         if (!propByRes.get(ResourceOperation.CREATE).isEmpty()
                 && vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
 
-            connObjectUtils.retrieveVirAttrValues(subject, attrUtils);
+            connObjectUtils.retrieveVirAttrValues(any);
 
             // update vAttrsToBeUpdated as well
-            for (VirAttr virAttr : subject.getVirAttrs()) {
+            for (VirAttr<?> virAttr : any.getVirAttrs()) {
                 final String schema = virAttr.getSchema().getKey();
 
                 final AttrMod attributeMod = new AttrMod();
@@ -488,36 +447,39 @@ public class PropagationManagerImpl implements PropagationManager {
 
         for (ResourceOperation operation : ResourceOperation.values()) {
             for (String resourceName : propByRes.get(operation)) {
-                final ExternalResource resource = resourceDAO.find(resourceName);
+                ExternalResource resource = resourceDAO.find(resourceName);
+                Provision provision = resource == null ? null : resource.getProvision(any.getType());
                 if (resource == null) {
                     LOG.error("Invalid resource name specified: {}, ignoring...", resourceName);
-                } else if (attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION).isEmpty()) {
+                } else if (provision == null) {
+                    LOG.error("No provision specified on resource {} for type {}, ignoring...",
+                            resource, any.getType());
+                } else if (anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION).isEmpty()) {
                     LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}",
-                            attrUtils.getType(), resource);
+                            any.getType(), resource);
                 } else {
                     PropagationTask task = entityFactory.newEntity(PropagationTask.class);
                     task.setResource(resource);
-                    task.setObjectClassName(connObjectUtils.fromSubject(subject).getObjectClassValue());
-                    task.setSubjectType(attrUtils.getType());
+                    task.setObjectClassName(resource.getProvision(any.getType()).getObjectClass().getObjectClassValue());
+                    task.setAnyTypeKind(anyUtils.getAnyTypeKind());
                     if (!deleteOnResource) {
-                        task.setSubjectKey(subject.getKey());
+                        task.setAnyKey(any.getKey());
                     }
                     task.setPropagationOperation(operation);
                     task.setPropagationMode(resource.getPropagationMode());
-                    task.setOldAccountId(propByRes.getOldAccountId(resource.getKey()));
+                    task.setOldConnObjectKey(propByRes.getOldAccountId(resource.getKey()));
 
-                    Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttributes(attrUtils, subject,
-                            password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, membVAttrsToBeRemoved,
-                            membVAttrsToBeUpdatedMap, enable, resource);
-                    task.setAccountId(preparedAttrs.getKey());
+                    Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttributes(anyUtils, any,
+                            password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, enable, provision);
+                    task.setConnObjectKey(preparedAttrs.getKey());
 
                     // Check if any of mandatory attributes (in the mapping) is missing or not received any value: 
                     // if so, add special attributes that will be evaluated by PropagationTaskExecutor
                     List<String> mandatoryMissing = new ArrayList<>();
                     List<String> mandatoryNullOrEmpty = new ArrayList<>();
-                    for (MappingItem item : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
-                        if (!item.isAccountid()
-                                && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), subject)) {
+                    for (MappingItem item : anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+                        if (!item.isConnObjectKey()
+                                && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) {
 
                             Attribute attr = AttributeUtil.find(item.getExtAttrName(), preparedAttrs.getValue());
                             if (attr == null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/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 9373249..2c04f26 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
@@ -18,6 +18,8 @@
  */
 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;
@@ -28,12 +30,14 @@ 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.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.group.GMapping;
+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.persistence.api.entity.user.UMapping;
 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;
@@ -63,6 +67,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
     @Autowired
     protected ConnectorFactory connFactory;
 
+    @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
     /**
      * Resource DAO.
      */
@@ -121,13 +128,23 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
         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 (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccCreate.add(provResult);
                                     break;
@@ -136,12 +153,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccCreate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccCreate.add(provResult);
                             }
                             break;
 
                         case UPDATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccUpdate.add(provResult);
                                     break;
@@ -150,12 +169,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccUpdate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccUpdate.add(provResult);
                             }
                             break;
 
                         case DELETE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccDelete.add(provResult);
                                     break;
@@ -164,12 +185,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccDelete.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccDelete.add(provResult);
                             }
                             break;
 
                         case NONE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uSuccNone.add(provResult);
                                     break;
@@ -178,7 +201,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gSuccNone.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aSuccNone.add(provResult);
                             }
                             break;
 
@@ -189,7 +214,7 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 case FAILURE:
                     switch (provResult.getOperation()) {
                         case CREATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uFailCreate.add(provResult);
                                     break;
@@ -198,12 +223,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gFailCreate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aFailCreate.add(provResult);
                             }
                             break;
 
                         case UPDATE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uFailUpdate.add(provResult);
                                     break;
@@ -212,12 +239,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gFailUpdate.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aFailUpdate.add(provResult);
                             }
                             break;
 
                         case DELETE:
-                            switch (provResult.getSubjectType()) {
+                            switch (anyType.getKind()) {
                                 case USER:
                                     uFailDelete.add(provResult);
                                     break;
@@ -226,7 +255,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                                     gFailDelete.add(provResult);
                                     break;
 
+                                case ANY_OBJECT:
                                 default:
+                                    aFailDelete.add(provResult);
                             }
                             break;
 
@@ -235,7 +266,7 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     break;
 
                 case IGNORE:
-                    switch (provResult.getSubjectType()) {
+                    switch (anyType.getKind()) {
                         case USER:
                             uIgnore.add(provResult);
                             break;
@@ -244,7 +275,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                             gIgnore.add(provResult);
                             break;
 
+                        case ANY_OBJECT:
                         default:
+                            aIgnore.add(provResult);
                     }
                     break;
 
@@ -270,6 +303,14 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
                 append(' ').
                 append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size());
+        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) {
@@ -298,6 +339,19 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 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
@@ -322,6 +376,16 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     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();
@@ -339,49 +403,48 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                     }
                 }, new ArrayList<GrantedAuthority>());
 
-        final UserDetails userDetails = new User("admin", "FAKE_PASSWORD", authorities);
+        UserDetails userDetails = new User("admin", "FAKE_PASSWORD", authorities);
 
         SecurityContextHolder.getContext().setAuthentication(
                 new UsernamePasswordAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities));
 
         try {
-            final Class<T> clazz = getTaskClassReference();
+            Class<T> clazz = getTaskClassReference();
             if (!clazz.isAssignableFrom(task.getClass())) {
                 throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
             }
 
-            final T syncTask = clazz.cast(this.task);
+            T _task = clazz.cast(this.task);
 
-            final Connector connector;
+            Connector connector;
             try {
-                connector = connFactory.getConnector(syncTask.getResource());
+                connector = connFactory.getConnector(_task.getResource());
             } catch (Exception e) {
                 final String msg = String.
                         format("Connector instance bean for resource %s and connInstance %s not found",
-                                syncTask.getResource(), syncTask.getResource().getConnector());
+                                _task.getResource(), _task.getResource().getConnector());
 
                 throw new JobExecutionException(msg, e);
             }
 
-            final UMapping uMapping = syncTask.getResource().getUmapping();
-            if (uMapping != null && uMapping.getAccountIdItem() == null) {
-                throw new JobExecutionException(
-                        "Invalid user account id mapping for resource " + syncTask.getResource());
-            }
-            final GMapping rMapping = syncTask.getResource().getGmapping();
-            if (rMapping != null && rMapping.getAccountIdItem() == null) {
-                throw new JobExecutionException(
-                        "Invalid group account id mapping for resource " + syncTask.getResource());
+            boolean noMapping = true;
+            for (Provision provision : _task.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 (uMapping == null && rMapping == null) {
+            if (noMapping) {
                 return "No mapping configured for both users and groups: aborting...";
             }
 
             return executeWithSecurityContext(
-                    syncTask,
+                    _task,
                     connector,
-                    uMapping,
-                    rMapping,
                     dryRun);
         } catch (Throwable t) {
             LOG.error("While executing provisioning job {}", getClass().getName(), t);
@@ -395,8 +458,6 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
     protected abstract String executeWithSecurityContext(
             final T task,
             final Connector connector,
-            final UMapping uMapping,
-            final GMapping rMapping,
             final boolean dryRun) throws JobExecutionException;
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/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 e15f526..275f648 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
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Set;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.IntMappingType;
@@ -33,57 +32,59 @@ import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 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.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+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.Mapping;
+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.sync.IgnoreProvisionException;
 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.Transactional;
 
 public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
         implements SyncopePushResultHandler {
 
-    protected abstract String getName(Subject<?, ?, ?> subject);
+    protected abstract String getName(Any<?, ?, ?> any);
 
-    protected abstract Mapping<?> getMapping();
+    protected abstract Any<?, ?, ?> getAny(long key);
 
-    protected abstract Subject<?, ?, ?> getSubject(long key);
+    protected abstract Any<?, ?, ?> deprovision(Any<?, ?, ?> sbj);
 
-    protected abstract Subject<?, ?, ?> deprovision(Subject<?, ?, ?> sbj);
+    protected abstract Any<?, ?, ?> provision(Any<?, ?, ?> sbj, Boolean enabled);
 
-    protected abstract Subject<?, ?, ?> provision(Subject<?, ?, ?> sbj, Boolean enabled);
+    protected abstract Any<?, ?, ?> link(Any<?, ?, ?> sbj, Boolean unlink);
 
-    protected abstract Subject<?, ?, ?> link(Subject<?, ?, ?> sbj, Boolean unlink);
+    protected abstract Any<?, ?, ?> unassign(Any<?, ?, ?> sbj);
 
-    protected abstract Subject<?, ?, ?> unassign(Subject<?, ?, ?> sbj);
+    protected abstract Any<?, ?, ?> assign(Any<?, ?, ?> sbj, Boolean enabled);
 
-    protected abstract Subject<?, ?, ?> assign(Subject<?, ?, ?> sbj, Boolean enabled);
-
-    protected abstract ConnectorObject getRemoteObject(String accountId);
+    protected abstract ConnectorObject getRemoteObject(String connObjectKey, ObjectClass objectClass);
 
     @Transactional
     @Override
-    public boolean handle(final long subjectKey) {
+    public boolean handle(final long anyKey) {
+        Any<?, ?, ?> any = null;
         try {
-            doHandle(subjectKey);
+            any = getAny(anyKey);
+            doHandle(any);
             return true;
         } catch (IgnoreProvisionException e) {
             ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.NONE);
-            result.setSubjectType(getAttributableUtils().getType());
+            result.setAnyType(any == null ? null : any.getType().getKey());
             result.setStatus(ProvisioningResult.Status.IGNORE);
-            result.setKey(subjectKey);
+            result.setKey(anyKey);
             profile.getResults().add(result);
 
             LOG.warn("Ignoring during push", e);
@@ -94,26 +95,24 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    protected final void doHandle(final long subjectId)
+    protected final void doHandle(final Any<?, ?, ?> any)
             throws JobExecutionException {
 
-        Subject<?, ?, ?> subject = getSubject(subjectId);
-
-        AttributableUtils attrUtils = attrUtilsFactory.getInstance(subject);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
 
         ProvisioningResult result = new ProvisioningResult();
         profile.getResults().add(result);
 
-        result.setKey(subject.getKey());
-        result.setSubjectType(attrUtils.getType());
-        result.setName(getName(subject));
+        result.setKey(any.getKey());
+        result.setAnyType(any.getType().getKey());
+        result.setName(getName(any));
 
-        Boolean enabled = subject instanceof User && profile.getTask().isSyncStatus()
-                ? ((User) subject).isSuspended() ? Boolean.FALSE : Boolean.TRUE
+        Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
+                ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
                 : null;
 
         LOG.debug("Propagating {} with key {} towards {}",
-                attrUtils.getType(), subject.getKey(), profile.getTask().getResource());
+                anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
 
         Object output = null;
         Result resultStatus = null;
@@ -121,10 +120,10 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         String operation = null;
 
         // Try to read remote object (user / group) BEFORE any actual operation
-        String accountId = MappingUtils.getAccountIdValue(
-                subject, profile.getTask().getResource(), getMapping().getAccountIdItem());
+        Provision provision = profile.getTask().getResource().getProvision(any.getType());
+        String connObjecKey = MappingUtils.getConnObjectKeyValue(any, provision);
 
-        beforeObj = getRemoteObject(accountId);
+        beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
 
         Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
 
@@ -144,42 +143,45 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeAssign(this.getProfile(), subject);
+                                action.beforeAssign(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
                             } else {
-                                assign(subject, status);
+                                assign(any, status);
                             }
 
                             break;
+
                         case PROVISION:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeProvision(this.getProfile(), subject);
+                                action.beforeProvision(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformCreate()) {
                                 LOG.debug("PushTask not configured for create");
                             } else {
-                                provision(subject, status);
+                                provision(any, status);
                             }
 
                             break;
+
                         case UNLINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), subject);
+                                action.beforeUnlink(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                link(subject, true);
+                                link(any, true);
                             }
 
                             break;
+
                         case IGNORE:
-                            LOG.debug("Ignored subjectId: {}", subjectId);
+                            LOG.debug("Ignored any: {}", any);
                             break;
                         default:
                         // do nothing
@@ -192,65 +194,70 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUpdate(this.getProfile(), subject);
+                                action.beforeUpdate(this.getProfile(), any);
                             }
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                update(subject, status);
+                                update(any, status);
                             }
 
                             break;
+
                         case DEPROVISION:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeDeprovision(this.getProfile(), subject);
+                                action.beforeDeprovision(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
                             } else {
-                                deprovision(subject);
+                                deprovision(any);
                             }
 
                             break;
+
                         case UNASSIGN:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnassign(this.getProfile(), subject);
+                                action.beforeUnassign(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformDelete()) {
                                 LOG.debug("PushTask not configured for delete");
                             } else {
-                                unassign(subject);
+                                unassign(any);
                             }
 
                             break;
+
                         case LINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeLink(this.getProfile(), subject);
+                                action.beforeLink(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                link(subject, false);
+                                link(any, false);
                             }
 
                             break;
+
                         case UNLINK:
                             for (PushActions action : profile.getActions()) {
-                                action.beforeUnlink(this.getProfile(), subject);
+                                action.beforeUnlink(this.getProfile(), any);
                             }
 
                             if (!profile.getTask().isPerformUpdate()) {
                                 LOG.debug("PushTask not configured for update");
                             } else {
-                                link(subject, true);
+                                link(any, true);
                             }
 
                             break;
+
                         case IGNORE:
-                            LOG.debug("Ignored subjectId: {}", subjectId);
+                            LOG.debug("Ignored any: {}", any);
                             break;
                         default:
                         // do nothing
@@ -258,12 +265,12 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                 }
 
                 for (PushActions action : profile.getActions()) {
-                    action.after(this.getProfile(), subject, result);
+                    action.after(this.getProfile(), any, result);
                 }
 
                 result.setStatus(ProvisioningResult.Status.SUCCESS);
                 resultStatus = AuditElements.Result.SUCCESS;
-                output = getRemoteObject(accountId);
+                output = getRemoteObject(connObjecKey, provision.getObjectClass());
             } catch (IgnoreProvisionException e) {
                 throw e;
             } catch (Exception e) {
@@ -272,30 +279,30 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                 resultStatus = AuditElements.Result.FAILURE;
                 output = e;
 
-                LOG.warn("Error pushing {} towards {}", subject, profile.getTask().getResource(), e);
+                LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
 
                 for (PushActions action : profile.getActions()) {
-                    action.onError(this.getProfile(), subject, result, e);
+                    action.onError(this.getProfile(), any, result, e);
                 }
 
                 throw new JobExecutionException(e);
             } finally {
                 notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
-                        getAttributableUtils().getType().name().toLowerCase(),
+                        any.getType().getKind().name().toLowerCase(),
                         profile.getTask().getResource().getKey(),
                         operation,
                         resultStatus,
                         beforeObj,
                         output,
-                        subject);
+                        any);
                 auditManager.audit(AuditElements.EventCategoryType.PUSH,
-                        getAttributableUtils().getType().name().toLowerCase(),
+                        any.getType().getKind().name().toLowerCase(),
                         profile.getTask().getResource().getKey(),
                         operation,
                         resultStatus,
                         beforeObj,
                         output,
-                        subject);
+                        any);
             }
         }
     }
@@ -322,28 +329,24 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    protected Subject<?, ?, ?> update(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final Set<MembershipMod> membsToAdd = new HashSet<>();
-        final Set<String> vattrToBeRemoved = new HashSet<>();
-        final Set<String> membVattrToBeRemoved = new HashSet<>();
-        final Set<AttrMod> vattrToBeUpdated = new HashSet<>();
+    protected Any<?, ?, ?> update(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        Set<String> vattrToBeRemoved = new HashSet<>();
+        Set<AttrMod> vattrToBeUpdated = new HashSet<>();
 
         // Search for all mapped vattrs
-        final Mapping<?> umapping = getMapping();
-        for (MappingItem mappingItem : umapping.getItems()) {
+        Mapping mapping = profile.getTask().getResource().getProvision(sbj.getType()).getMapping();
+        for (MappingItem mappingItem : mapping.getItems()) {
             if (mappingItem.getIntMappingType() == IntMappingType.UserVirtualSchema) {
                 vattrToBeRemoved.add(mappingItem.getIntAttrName());
-            } else if (mappingItem.getIntMappingType() == IntMappingType.MembershipVirtualSchema) {
-                membVattrToBeRemoved.add(mappingItem.getIntAttrName());
             }
         }
 
         // Search for all user's vattrs and:
         // 1. add mapped vattrs not owned by the user to the set of vattrs to be removed
         // 2. add all vattrs owned by the user to the set of vattrs to be update
-        for (VirAttr vattr : sbj.getVirAttrs()) {
+        for (VirAttr<?> vattr : sbj.getVirAttrs()) {
             vattrToBeRemoved.remove(vattr.getSchema().getKey());
-            final AttrMod mod = new AttrMod();
+            AttrMod mod = new AttrMod();
             mod.setSchema(vattr.getSchema().getKey());
             mod.getValuesToBeAdded().addAll(vattr.getValues());
             vattrToBeUpdated.add(mod);
@@ -354,27 +357,9 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         if (sbj instanceof User) {
             changepwd = true;
             resourceNames = userDAO.findAllResourceNames((User) sbj);
-
-            // Search for memberships
-            for (Membership membership : User.class.cast(sbj).getMemberships()) {
-                MembershipMod membershipMod = new MembershipMod();
-                membershipMod.setKey(membership.getKey());
-                membershipMod.setGroup(membership.getGroup().getKey());
-
-                for (VirAttr vattr : membership.getVirAttrs()) {
-                    membVattrToBeRemoved.remove(vattr.getSchema().getKey());
-                    AttrMod mod = new AttrMod();
-                    mod.setSchema(vattr.getSchema().getKey());
-                    mod.getValuesToBeAdded().addAll(vattr.getValues());
-                    membershipMod.getVirAttrsToUpdate().add(mod);
-                }
-
-                membsToAdd.add(membershipMod);
-            }
-
-            if (!membsToAdd.isEmpty()) {
-                membsToAdd.iterator().next().getVirAttrsToRemove().addAll(membVattrToBeRemoved);
-            }
+        } else if (sbj instanceof AnyObject) {
+            changepwd = true;
+            resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) sbj);
         } else {
             changepwd = false;
             resourceNames = ((Group) sbj).getResourceNames();
@@ -387,9 +372,8 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getUpdateTasks(
-                sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources,
-                membsToAdd));
+                sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources));
 
-        return userDAO.authFetch(sbj.getKey());
+        return getAny(sbj.getKey());
     }
 }