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:55 UTC

[05/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/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 b3a73df..b854921 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
@@ -22,20 +22,21 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.AttributableTransformer;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.AnyTransformer;
 import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeSyncResultHandler;
@@ -51,19 +52,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
     protected SyncUtils syncUtilities;
 
     @Autowired
-    protected AttributableTransformer attrTransformer;
+    protected AnyTransformer anyTransformer;
 
-    protected abstract String getName(AbstractSubjectTO subjectTO);
+    protected abstract String getName(AnyTO anyTO);
 
-    protected abstract AbstractSubjectMod getSubjectMod(AbstractSubjectTO subjectTO, SyncDelta delta);
+    protected abstract AnyTO doCreate(AnyTO anyTO, SyncDelta delta, ProvisioningResult result);
 
-    protected abstract AbstractSubjectTO doCreate(
-            AbstractSubjectTO subjectTO, SyncDelta delta, ProvisioningResult result);
+    protected abstract AnyTO doLink(AnyTO before, ProvisioningResult result, boolean unlink);
 
-    protected abstract AbstractSubjectTO doLink(AbstractSubjectTO before, ProvisioningResult result, boolean unlink);
-
-    protected abstract AbstractSubjectTO doUpdate(AbstractSubjectTO before, AbstractSubjectMod subjectMod,
-            SyncDelta delta, ProvisioningResult result);
+    protected abstract AnyTO doUpdate(AnyTO before, AnyMod anyMod, SyncDelta delta, ProvisioningResult result);
 
     protected abstract void doDeprovision(Long key, boolean unlink);
 
@@ -71,13 +68,21 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
     @Override
     public boolean handle(final SyncDelta delta) {
+        Provision provision = null;
         try {
-            doHandle(delta);
+            provision = profile.getTask().getResource().getProvision(delta.getObject().getObjectClass());
+            if (provision == null) {
+                throw new JobExecutionException("No provision found on " + profile.getTask().getResource() + " for "
+                        + delta.getObject().getObjectClass());
+            }
+
+            doHandle(delta, provision);
             return true;
         } catch (IgnoreProvisionException e) {
             ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.NONE);
-            result.setSubjectType(getAttributableUtils().getType());
+            result.setAnyType(provision == null
+                    ? getAnyUtils().getAnyTypeKind().name() : provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.IGNORE);
             result.setKey(0L);
             result.setName(delta.getObject().getName().getNameValue());
@@ -91,7 +96,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         }
     }
 
-    protected List<ProvisioningResult> assign(final SyncDelta delta, final AttributableUtils attrUtils)
+    protected List<ProvisioningResult> assign(
+            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformCreate()) {
@@ -99,18 +105,17 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        final AbstractSubjectTO subjectTO =
-                connObjectUtils.getSubjectTO(delta.getObject(), profile.getTask(), attrUtils);
+        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
 
-        subjectTO.getResources().add(profile.getTask().getResource().getKey());
+        anyTO.getResources().add(profile.getTask().getResource().getKey());
 
         final ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
-        result.setSubjectType(attrUtils.getType());
+        result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
 
         // Attributable transformation (if configured)
-        AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
+        AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
         result.setName(getName(transformed));
@@ -123,13 +128,14 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                 actionedDelta = action.beforeAssign(this.getProfile(), actionedDelta, transformed);
             }
 
-            create(transformed, actionedDelta, attrUtils, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
+            create(transformed, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
         }
 
         return Collections.singletonList(result);
     }
 
-    protected List<ProvisioningResult> provision(final SyncDelta delta, final AttributableUtils attrUtils)
+    protected List<ProvisioningResult> provision(
+            final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformCreate()) {
@@ -137,16 +143,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        final AbstractSubjectTO subjectTO =
-                connObjectUtils.getSubjectTO(delta.getObject(), profile.getTask(), attrUtils);
+        AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
 
         // Attributable transformation (if configured)
-        AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
+        AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
         final ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
-        result.setSubjectType(attrUtils.getType());
+        result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
 
         result.setName(getName(transformed));
@@ -159,16 +164,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                 actionedDelta = action.beforeProvision(this.getProfile(), actionedDelta, transformed);
             }
 
-            create(transformed, actionedDelta, attrUtils, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
+            create(transformed, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
         }
 
         return Collections.<ProvisioningResult>singletonList(result);
     }
 
     private void create(
-            final AbstractSubjectTO subjectTO,
+            final AnyTO anyTO,
             final SyncDelta delta,
-            final AttributableUtils attrUtils,
             final String operation,
             final ProvisioningResult result)
             throws JobExecutionException {
@@ -177,7 +181,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         Result resultStatus;
 
         try {
-            AbstractSubjectTO actual = doCreate(subjectTO, delta, result);
+            AnyTO actual = doCreate(anyTO, delta, result);
             result.setName(getName(actual));
             output = actual;
             resultStatus = Result.SUCCESS;
@@ -190,7 +194,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         } catch (PropagationException e) {
             // A propagation failure doesn't imply a synchronization failure.
             // The propagation exception status will be reported into the propagation task execution.
-            LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+            LOG.error("Could not propagate {} {}", anyTO.getType(), delta.getUid().getUidValue(), e);
             output = e;
             resultStatus = Result.FAILURE;
 
@@ -200,7 +204,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         } catch (Exception e) {
             result.setStatus(ProvisioningResult.Status.FAILURE);
             result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-            LOG.error("Could not create {} {} ", attrUtils.getType(), delta.getUid().getUidValue(), e);
+            LOG.error("Could not create {} {} ", anyTO.getType(), delta.getUid().getUidValue(), e);
             output = e;
             resultStatus = Result.FAILURE;
 
@@ -212,32 +216,32 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         audit(operation, resultStatus, null, output, delta);
     }
 
-    protected List<ProvisioningResult> update(final SyncDelta delta, final List<Long> subjects,
-            final AttributableUtils attrUtils) throws JobExecutionException {
+    protected List<ProvisioningResult> update(final SyncDelta delta, final List<Long> anys,
+            final Provision provision) throws JobExecutionException {
 
         if (!profile.getTask().isPerformUpdate()) {
             LOG.debug("SyncTask not configured for update");
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to update {}", subjects);
+        LOG.debug("About to update {}", anys);
 
         List<ProvisioningResult> results = new ArrayList<>();
 
         SyncDelta workingDelta = delta;
-        for (Long key : subjects) {
+        for (Long key : anys) {
             LOG.debug("About to update {}", key);
 
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.UPDATE);
-            result.setSubjectType(attrUtils.getType());
+            result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(key);
 
-            AbstractSubjectTO before = getSubjectTO(key);
+            AnyTO before = getAnyTO(key);
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Subject '%s(%d)' not found", attrUtils.getType().name(), key));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
             } else {
                 result.setName(getName(before));
             }
@@ -250,17 +254,23 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     output = null;
                 } else {
                     try {
-                        AbstractSubjectMod subjectMod = getSubjectMod(before, workingDelta);
+                        AnyMod anyMod = connObjectUtils.getAnyMod(
+                                before.getKey(),
+                                workingDelta.getObject(),
+                                before,
+                                profile.getTask(),
+                                provision,
+                                getAnyUtils());
 
                         // Attribute value transformation (if configured)
-                        AbstractSubjectMod actual = attrTransformer.transform(subjectMod);
+                        AnyMod actual = anyTransformer.transform(anyMod);
                         LOG.debug("Transformed: {}", actual);
 
                         for (SyncActions action : profile.getActions()) {
-                            workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, subjectMod);
+                            workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyMod);
                         }
 
-                        final AbstractSubjectTO updated = doUpdate(before, subjectMod, workingDelta, result);
+                        final AnyTO updated = doUpdate(before, anyMod, workingDelta, result);
 
                         for (SyncActions action : profile.getActions()) {
                             action.after(this.getProfile(), workingDelta, updated, result);
@@ -269,14 +279,14 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         output = updated;
                         resultStatus = Result.SUCCESS;
                         result.setName(getName(updated));
-                        LOG.debug("{} {} successfully updated", attrUtils.getType(), key);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
                         LOG.error("Could not propagate {} {}",
-                                attrUtils.getType(), workingDelta.getUid().getUidValue(), e);
+                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -287,7 +297,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
                         LOG.error("Could not update {} {}",
-                                attrUtils.getType(), workingDelta.getUid().getUidValue(), e);
+                                provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -305,8 +315,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
     protected List<ProvisioningResult> deprovision(
             final SyncDelta delta,
-            final List<Long> subjects,
-            final AttributableUtils attrUtils,
+            final List<Long> anys,
+            final Provision provision,
             final boolean unlink)
             throws JobExecutionException {
 
@@ -315,11 +325,11 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to update {}", subjects);
+        LOG.debug("About to update {}", anys);
 
         final List<ProvisioningResult> updResults = new ArrayList<>();
 
-        for (Long id : subjects) {
+        for (Long id : anys) {
             LOG.debug("About to unassign resource {}", id);
 
             Object output;
@@ -327,15 +337,15 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
             final ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.DELETE);
-            result.setSubjectType(attrUtils.getType());
+            result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(id);
 
-            final AbstractSubjectTO before = getSubjectTO(id);
+            final AnyTO before = getAnyTO(id);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Subject '%s(%d)' not found", attrUtils.getType().name(), id));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), id));
             }
 
             if (!profile.isDryRun()) {
@@ -357,20 +367,21 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         }
 
                         doDeprovision(id, unlink);
-                        output = getSubjectTO(id);
+                        output = getAnyTO(id);
 
                         for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
+                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
                         }
 
                         resultStatus = Result.SUCCESS;
-                        LOG.debug("{} {} successfully updated", attrUtils.getType(), id);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), id);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
-                        LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -380,7 +391,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -401,8 +413,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
     protected List<ProvisioningResult> link(
             final SyncDelta delta,
-            final List<Long> subjects,
-            final AttributableUtils attrUtils,
+            final List<Long> anys,
+            final Provision provision,
             final boolean unlink)
             throws JobExecutionException {
 
@@ -411,27 +423,27 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to update {}", subjects);
+        LOG.debug("About to update {}", anys);
 
         final List<ProvisioningResult> updResults = new ArrayList<>();
 
-        for (Long id : subjects) {
+        for (Long id : anys) {
             LOG.debug("About to unassign resource {}", id);
 
             Object output;
             Result resultStatus;
 
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.NONE);
-            result.setSubjectType(attrUtils.getType());
+            result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(id);
 
-            final AbstractSubjectTO before = getSubjectTO(id);
+            final AnyTO before = getAnyTO(id);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Subject '%s(%d)' not found", attrUtils.getType().name(), id));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), id));
             }
 
             if (!profile.isDryRun()) {
@@ -455,17 +467,18 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         output = doLink(before, result, unlink);
 
                         for (SyncActions action : profile.getActions()) {
-                            action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
+                            action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
                         }
 
                         resultStatus = Result.SUCCESS;
-                        LOG.debug("{} {} successfully updated", attrUtils.getType(), id);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), id);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
                         // A propagation failure doesn't imply a synchronization failure.
                         // The propagation exception status will be reported into the propagation task execution.
-                        LOG.error("Could not propagate {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not propagate {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -475,7 +488,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not update {} {}", attrUtils.getType(), delta.getUid().getUidValue(), e);
+                        LOG.error("Could not update {} {}",
+                                provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
                         output = e;
                         resultStatus = Result.FAILURE;
 
@@ -494,7 +508,9 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
     }
 
     protected List<ProvisioningResult> delete(
-            final SyncDelta delta, final List<Long> subjects, final AttributableUtils attrUtils)
+            final SyncDelta delta,
+            final List<Long> anys,
+            final Provision provision)
             throws JobExecutionException {
 
         if (!profile.getTask().isPerformDelete()) {
@@ -502,25 +518,25 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             return Collections.<ProvisioningResult>emptyList();
         }
 
-        LOG.debug("About to delete {}", subjects);
+        LOG.debug("About to delete {}", anys);
 
         List<ProvisioningResult> delResults = new ArrayList<>();
 
         SyncDelta workingDelta = delta;
-        for (Long id : subjects) {
+        for (Long id : anys) {
             Object output;
             Result resultStatus = Result.FAILURE;
 
-            AbstractSubjectTO before = null;
+            AnyTO before = null;
             final ProvisioningResult result = new ProvisioningResult();
 
             try {
-                before = getSubjectTO(id);
+                before = getAnyTO(id);
 
                 result.setKey(id);
                 result.setName(getName(before));
                 result.setOperation(ResourceOperation.DELETE);
-                result.setSubjectType(attrUtils.getType());
+                result.setAnyType(provision.getAnyType().getKey());
                 result.setStatus(ProvisioningResult.Status.SUCCESS);
 
                 if (!profile.isDryRun()) {
@@ -541,7 +557,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                     } catch (Exception e) {
                         result.setStatus(ProvisioningResult.Status.FAILURE);
                         result.setMessage(ExceptionUtils.getRootCauseMessage(e));
-                        LOG.error("Could not delete {} {}", attrUtils.getType(), id, e);
+                        LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), id, e);
                         output = e;
 
                         for (SyncActions action : profile.getActions()) {
@@ -554,21 +570,24 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
                 delResults.add(result);
             } catch (NotFoundException e) {
-                LOG.error("Could not find {} {}", attrUtils.getType(), id, e);
+                LOG.error("Could not find {} {}", provision.getAnyType().getKey(), id, e);
             } catch (UnauthorizedException e) {
-                LOG.error("Not allowed to read {} {}", attrUtils.getType(), id, e);
+                LOG.error("Not allowed to read {} {}", provision.getAnyType().getKey(), id, e);
             } catch (Exception e) {
-                LOG.error("Could not delete {} {}", attrUtils.getType(), id, e);
+                LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), id, e);
             }
         }
 
         return delResults;
     }
 
-    private List<ProvisioningResult> ignore(final SyncDelta delta, final AttributableUtils attrUtils,
-            final boolean matching) throws JobExecutionException {
+    private List<ProvisioningResult> ignore(
+            final SyncDelta delta,
+            final Provision provision,
+            final boolean matching)
+            throws JobExecutionException {
 
-        LOG.debug("Subject to ignore {}", delta.getObject().getUid().getUidValue());
+        LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
 
         final List<ProvisioningResult> ignoreResults = new ArrayList<>();
         final ProvisioningResult result = new ProvisioningResult();
@@ -576,7 +595,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         result.setKey(null);
         result.setName(delta.getObject().getUid().getUidValue());
         result.setOperation(ResourceOperation.NONE);
-        result.setSubjectType(attrUtils.getType());
+        result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
         ignoreResults.add(result);
 
@@ -590,89 +609,92 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
     }
 
     /**
-     * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on user(s)/group(s).
+     * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on any object(s).
      *
      * @param delta returned by the underlying profile.getConnector()
+     * @param provision provisioning info
      * @throws JobExecutionException in case of synchronization failure.
      */
-    protected void doHandle(final SyncDelta delta)
+    protected void doHandle(final SyncDelta delta, final Provision provision)
             throws JobExecutionException {
 
-        final AttributableUtils attrUtils = getAttributableUtils();
+        AnyUtils anyUtils = getAnyUtils();
 
         LOG.debug("Process {} for {} as {}",
                 delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
 
-        final String uid = delta.getPreviousUid() == null
+        String uid = delta.getPreviousUid() == null
                 ? delta.getUid().getUidValue()
                 : delta.getPreviousUid().getUidValue();
 
         try {
-            List<Long> subjectKeys = syncUtilities.findExisting(
-                    uid, delta.getObject(), profile.getTask().getResource(), attrUtils);
+            List<Long> anyKeys = syncUtilities.findExisting(uid, delta.getObject(), provision, anyUtils);
 
-            if (subjectKeys.size() > 1) {
+            if (anyKeys.size() > 1) {
                 switch (profile.getResAct()) {
                     case IGNORE:
-                        throw new IllegalStateException("More than one match " + subjectKeys);
+                        throw new IllegalStateException("More than one match " + anyKeys);
 
                     case FIRSTMATCH:
-                        subjectKeys = subjectKeys.subList(0, 1);
+                        anyKeys = anyKeys.subList(0, 1);
                         break;
 
                     case LASTMATCH:
-                        subjectKeys = subjectKeys.subList(subjectKeys.size() - 1, subjectKeys.size());
+                        anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
                         break;
 
                     default:
-                    // keep subjectIds as is
+                    // keep anyIds as is
                 }
             }
 
             if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
-                if (subjectKeys.isEmpty()) {
+                if (anyKeys.isEmpty()) {
                     switch (profile.getTask().getUnmatchingRule()) {
                         case ASSIGN:
-                            profile.getResults().addAll(assign(delta, attrUtils));
+                            profile.getResults().addAll(assign(delta, provision, anyUtils));
                             break;
+
                         case PROVISION:
-                            profile.getResults().addAll(provision(delta, attrUtils));
+                            profile.getResults().addAll(provision(delta, provision, anyUtils));
                             break;
+
                         case IGNORE:
-                            profile.getResults().addAll(ignore(delta, attrUtils, false));
+                            profile.getResults().addAll(ignore(delta, provision, false));
                             break;
+
                         default:
                         // do nothing
                     }
                 } else {
                     switch (profile.getTask().getMatchingRule()) {
                         case UPDATE:
-                            profile.getResults().addAll(update(delta, subjectKeys, attrUtils));
+                            profile.getResults().addAll(update(delta, anyKeys, provision));
                             break;
                         case DEPROVISION:
-                            profile.getResults().addAll(deprovision(delta, subjectKeys, attrUtils, false));
+                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, false));
                             break;
                         case UNASSIGN:
-                            profile.getResults().addAll(deprovision(delta, subjectKeys, attrUtils, true));
+                            profile.getResults().addAll(deprovision(delta, anyKeys, provision, true));
                             break;
                         case LINK:
-                            profile.getResults().addAll(link(delta, subjectKeys, attrUtils, false));
+                            profile.getResults().addAll(link(delta, anyKeys, provision, false));
                             break;
                         case UNLINK:
-                            profile.getResults().addAll(link(delta, subjectKeys, attrUtils, true));
+                            profile.getResults().addAll(link(delta, anyKeys, provision, true));
                             break;
                         case IGNORE:
-                            profile.getResults().addAll(ignore(delta, attrUtils, true));
+                            profile.getResults().addAll(ignore(delta, provision, true));
                             break;
                         default:
                         // do nothing
                     }
                 }
             } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
-                if (subjectKeys.isEmpty()) {
+                if (anyKeys.isEmpty()) {
                     LOG.debug("No match found for deletion");
                 } else {
-                    profile.getResults().addAll(delete(delta, subjectKeys, attrUtils));
+                    profile.getResults().addAll(delete(delta, anyKeys, provision));
                 }
             }
         } catch (IllegalStateException | IllegalArgumentException e) {
@@ -688,7 +710,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             final Object... input) {
 
         notificationManager.createTasks(AuditElements.EventCategoryType.SYNCHRONIZATION,
-                getAttributableUtils().getType().name().toLowerCase(),
+                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
                 profile.getTask().getResource().getKey(),
                 event,
                 result,
@@ -697,7 +719,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                 input);
 
         auditManager.audit(AuditElements.EventCategoryType.SYNCHRONIZATION,
-                getAttributableUtils().getType().name().toLowerCase(),
+                getAnyUtils().getAnyTypeKind().name().toLowerCase(),
                 profile.getTask().getResource().getKey(),
                 event,
                 result,

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/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 28c3885..fccecc4 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
@@ -18,10 +18,9 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 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.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
@@ -34,8 +33,13 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
 import org.apache.syncope.core.misc.AuditManager;
 import org.apache.syncope.core.misc.ConnObjectUtils;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.slf4j.Logger;
@@ -51,6 +55,9 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
 
     @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     protected UserDAO userDAO;
 
     @Autowired
@@ -86,6 +93,8 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A
     @Autowired
     protected PropagationTaskExecutor taskExecutor;
 
+    protected AnyObjectWorkflowAdapter awfAdapter;
+
     /**
      * User workflow adapter.
      */
@@ -99,28 +108,34 @@ public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A
     protected GroupWorkflowAdapter gwfAdapter;
 
     @Autowired
+    protected AnyObjectDataBinder anyObjectDataBinder;
+
+    @Autowired
     protected UserDataBinder userDataBinder;
 
     @Autowired
     protected GroupDataBinder groupDataBinder;
 
     @Autowired
+    protected AnyObjectProvisioningManager anyObjectProvisioningManager;
+
+    @Autowired
     protected UserProvisioningManager userProvisioningManager;
 
     @Autowired
     protected GroupProvisioningManager groupProvisioningManager;
 
     @Autowired
-    protected AttributableUtilsFactory attrUtilsFactory;
+    protected AnyUtilsFactory anyUtilsFactory;
 
     /**
      * Sync profile.
      */
     protected ProvisioningProfile<T, A> profile;
 
-    protected abstract AttributableUtils getAttributableUtils();
+    protected abstract AnyUtils getAnyUtils();
 
-    protected abstract AbstractSubjectTO getSubjectTO(long key);
+    protected abstract AnyTO getAnyTO(long key);
 
     @Override
     public void setProfile(final ProvisioningProfile<T, A> profile) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
new file mode 100644
index 0000000..fcfb537
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.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.resource.MappingItem;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+
+public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+    }
+
+    @Override
+    protected Any<?, ?, ?> deprovision(final Any<?, ?, ?> sbj) {
+        AnyObjectTO before = anyObjectDataBinder.getAnyObjectTO(AnyObject.class.cast(sbj));
+
+        List<String> noPropResources = new ArrayList<>(before.getResources());
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        taskExecutor.execute(propagationManager.getAnyObjectDeleteTasks(before.getKey(), noPropResources));
+
+        return anyObjectDAO.authFind(before.getKey());
+    }
+
+    @Override
+    protected Any<?, ?, ?> provision(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        AnyObjectTO before = anyObjectDataBinder.getAnyObjectTO(AnyObject.class.cast(sbj));
+
+        List<String> noPropResources = new ArrayList<>(before.getResources());
+        noPropResources.remove(profile.getTask().getResource().getKey());
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+        taskExecutor.execute(propagationManager.getAnyObjectCreateTasks(
+                before.getKey(),
+                Collections.unmodifiableCollection(before.getVirAttrs()),
+                propByRes,
+                noPropResources));
+
+        return anyObjectDAO.authFind(before.getKey());
+    }
+
+    @Override
+    protected Any<?, ?, ?> link(final Any<?, ?, ?> sbj, final Boolean unlink) {
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(sbj.getKey());
+
+        if (unlink) {
+            anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        } else {
+            anyObjectMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+        }
+
+        awfAdapter.update(anyObjectMod);
+
+        return anyObjectDAO.authFind(sbj.getKey());
+    }
+
+    @Override
+    protected Any<?, ?, ?> unassign(final Any<?, ?, ?> sbj) {
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(sbj.getKey());
+        anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        awfAdapter.update(anyObjectMod);
+        return deprovision(sbj);
+    }
+
+    @Override
+    protected Any<?, ?, ?> assign(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(sbj.getKey());
+        anyObjectMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+        awfAdapter.update(anyObjectMod);
+        return provision(sbj, enabled);
+    }
+
+    @Override
+    protected String getName(final Any<?, ?, ?> subject) {
+        return StringUtils.EMPTY;
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        try {
+            return anyObjectDataBinder.getAnyObjectTO(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving user {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected Any<?, ?, ?> getAny(final long key) {
+        try {
+            return anyObjectDAO.authFind(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving anyObject {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
+        ConnectorObject obj = null;
+        try {
+            Uid uid = new Uid(connObjectKey);
+
+            obj = profile.getConnector().getObject(
+                    objectClass,
+                    uid,
+                    profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
+        } catch (TimeoutException toe) {
+            LOG.debug("Request timeout", toe);
+            throw toe;
+        } catch (RuntimeException ignore) {
+            LOG.debug("While resolving {}", connObjectKey, ignore);
+        }
+
+        return obj;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
new file mode 100644
index 0000000..2b4b667
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.sync;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class AnyObjectSyncResultHandlerImpl extends AbstractSyncResultHandler implements AnyObjectSyncResultHandler {
+
+    @Override
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+    }
+
+    @Override
+    protected String getName(final AnyTO anyTO) {
+        return StringUtils.EMPTY;
+    }
+
+    @Override
+    protected AnyTO getAnyTO(final long key) {
+        try {
+            return anyObjectDataBinder.getAnyObjectTO(key);
+        } catch (Exception e) {
+            LOG.warn("Error retrieving anyObject {}", key, e);
+            return null;
+        }
+    }
+
+    @Override
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningResult result) {
+        AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
+
+        Map.Entry<Long, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
+                anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()));
+
+        anyObjectTO = anyObjectDataBinder.getAnyObjectTO(created.getKey());
+
+        result.setKey(created.getKey());
+        result.setName(getName(anyTO));
+
+        return anyObjectTO;
+    }
+
+    @Override
+    protected AnyTO doLink(
+            final AnyTO before,
+            final ProvisioningResult result,
+            final boolean unlink) {
+
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(before.getKey());
+
+        if (unlink) {
+            anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        } else {
+            anyObjectMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+        }
+
+        return anyObjectDataBinder.getAnyObjectTO(awfAdapter.update(anyObjectMod).getResult());
+    }
+
+    @Override
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyMod anyMod,
+            final SyncDelta delta,
+            final ProvisioningResult result) {
+
+        AnyObjectMod anyObjectMod = AnyObjectMod.class.cast(anyMod);
+
+        Map.Entry<Long, List<PropagationStatus>> updated = anyObjectProvisioningManager.update(anyObjectMod);
+
+        AnyObjectTO after = anyObjectDataBinder.getAnyObjectTO(updated.getKey());
+        result.setName(getName(after));
+        return after;
+    }
+
+    @Override
+    protected void doDeprovision(final Long key, final boolean unlink) {
+        taskExecutor.execute(propagationManager.getAnyObjectDeleteTasks(
+                key, profile.getTask().getResource().getKey()));
+
+        if (unlink) {
+            AnyObjectMod anyObjectMod = new AnyObjectMod();
+            anyObjectMod.setKey(key);
+            anyObjectMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+        }
+    }
+
+    @Override
+    protected void doDelete(final Long key) {
+        try {
+            taskExecutor.execute(propagationManager.getAnyObjectDeleteTasks(
+                    key, profile.getTask().getResource().getKey()));
+        } catch (Exception e) {
+            // A propagation failure doesn't imply a synchronization failure.
+            // The propagation exception status will be reported into the propagation task execution.
+            LOG.error("Could not propagate anyObject " + key, e);
+        }
+
+        anyObjectProvisioningManager.delete(key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
index 2b3ca02..5615876 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
@@ -20,9 +20,9 @@ package org.apache.syncope.core.provisioning.java.sync;
 
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
@@ -59,13 +59,13 @@ public class DBPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+    public <T extends AnyTO> SyncDelta beforeProvision(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject) throws JobExecutionException {
+            final T any) throws JobExecutionException {
 
-        if (subject instanceof UserTO) {
-            String password = ((UserTO) subject).getPassword();
+        if (any instanceof UserTO) {
+            String password = ((UserTO) any).getPassword();
             parseEncodedPassword(password, profile.getConnector());
         }
 
@@ -74,14 +74,14 @@ public class DBPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
-            final K subjectMod) throws JobExecutionException {
+            final T any,
+            final K anyMod) throws JobExecutionException {
 
-        if (subjectMod instanceof UserMod) {
-            String modPassword = ((UserMod) subjectMod).getPassword();
+        if (anyMod instanceof UserMod) {
+            String modPassword = ((UserMod) anyMod).getPassword();
             parseEncodedPassword(modPassword, profile.getConnector());
         }
 
@@ -123,14 +123,14 @@ public class DBPasswordSyncActions extends DefaultSyncActions {
 
     @Transactional(readOnly = true)
     @Override
-    public <T extends AbstractSubjectTO> void after(
+    public <T extends AnyTO> void after(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
+            final T any,
             final ProvisioningResult result) throws JobExecutionException {
 
-        if (subject instanceof UserTO && encodedPassword != null && cipher != null) {
-            User syncopeUser = userDAO.find(subject.getKey());
+        if (any instanceof UserTO && encodedPassword != null && cipher != null) {
+            User syncopeUser = userDAO.find(any.getKey());
             if (syncopeUser != null) {
                 syncopeUser.setEncodedPassword(encodedPassword.toUpperCase(), cipher);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
index fa5f843..14da889 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.core.persistence.api.entity.Subject;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.provisioning.api.sync.PushActions;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
@@ -34,58 +34,58 @@ public abstract class DefaultPushActions implements PushActions {
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeAssign(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeAssign(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeProvision(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeProvision(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeLink(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeLink(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeUnassign(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeUnassign(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeDeprovision(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeDeprovision(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> T beforeUnlink(final ProvisioningProfile<?, ?> profile, final T subject)
+    public <T extends Any<?, ?, ?>> T beforeUnlink(final ProvisioningProfile<?, ?> profile, final T any)
             throws JobExecutionException {
 
-        return subject;
+        return any;
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> void onError(
-            final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result,
+    public <T extends Any<?, ?, ?>> void onError(
+            final ProvisioningProfile<?, ?> profile, final T any, final ProvisioningResult result,
             final Exception error) throws JobExecutionException {
 
         // do nothing
     }
 
     @Override
-    public <T extends Subject<?, ?, ?>> void after(
-            final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result)
+    public <T extends Any<?, ?, ?>> void after(
+            final ProvisioningProfile<?, ?> profile, final T any, final ProvisioningResult result)
             throws JobExecutionException {
 
         // do nothing

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
index 8f3432a..29d7662 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.core.provisioning.java.sync;
 
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.core.provisioning.api.sync.SyncActions;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
@@ -36,66 +36,66 @@ public abstract class DefaultSyncActions implements SyncActions {
     }
 
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
-            final K subjectMod) throws JobExecutionException {
+            final T any,
+            final K anyMod) throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeDelete(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeDelete(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeAssign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeAssign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeLink(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeLink(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeUnassign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeUnassign(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeDeprovision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeDeprovision(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
     }
 
     @Override
-    public <T extends AbstractSubjectTO> SyncDelta beforeUnlink(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+    public <T extends AnyTO> SyncDelta beforeUnlink(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         return delta;
@@ -108,8 +108,8 @@ public abstract class DefaultSyncActions implements SyncActions {
     }
 
     @Override
-    public <T extends AbstractSubjectTO> void after(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject,
+    public <T extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any,
             final ProvisioningResult result)
             throws JobExecutionException {
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
index c38e5d6..38ae900 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
@@ -22,16 +22,15 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.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.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -41,30 +40,30 @@ import org.identityconnectors.framework.common.objects.Uid;
 public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
 
     @Override
-    protected AttributableUtils getAttributableUtils() {
-        return attrUtilsFactory.getInstance(AttributableType.GROUP);
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
     }
 
     @Override
-    protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
-        final GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
+    protected Any<?, ?, ?> deprovision(final Any<?, ?, ?> sbj) {
+        GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
 
-        final List<String> noPropResources = new ArrayList<>(before.getResources());
+        List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getGroupDeleteTasks(before.getKey(), noPropResources));
 
-        return groupDAO.authFetch(before.getKey());
+        return groupDAO.authFind(before.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
+    protected Any<?, ?, ?> provision(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        GroupTO before = groupDataBinder.getGroupTO(Group.class.cast(sbj));
 
-        final List<String> noPropResources = new ArrayList<>(before.getResources());
+        List<String> noPropResources = new ArrayList<>(before.getResources());
         noPropResources.remove(profile.getTask().getResource().getKey());
 
-        final PropagationByResource propByRes = new PropagationByResource();
+        PropagationByResource propByRes = new PropagationByResource();
         propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
 
         taskExecutor.execute(propagationManager.getGroupCreateTasks(
@@ -73,12 +72,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
                 propByRes,
                 noPropResources));
 
-        return groupDAO.authFetch(before.getKey());
+        return groupDAO.authFind(before.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
-        final GroupMod groupMod = new GroupMod();
+    protected Any<?, ?, ?> link(final Any<?, ?, ?> sbj, final Boolean unlink) {
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(sbj.getKey());
 
         if (unlink) {
@@ -89,12 +88,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
 
         gwfAdapter.update(groupMod);
 
-        return groupDAO.authFetch(sbj.getKey());
+        return groupDAO.authFind(sbj.getKey());
     }
 
     @Override
-    protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
-        final GroupMod groupMod = new GroupMod();
+    protected Any<?, ?, ?> unassign(final Any<?, ?, ?> sbj) {
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(sbj.getKey());
         groupMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         gwfAdapter.update(groupMod);
@@ -102,8 +101,8 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-        final GroupMod groupMod = new GroupMod();
+    protected Any<?, ?, ?> assign(final Any<?, ?, ?> sbj, final Boolean enabled) {
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(sbj.getKey());
         groupMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
         gwfAdapter.update(groupMod);
@@ -111,12 +110,12 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected String getName(final Subject<?, ?, ?> subject) {
+    protected String getName(final Any<?, ?, ?> subject) {
         return Group.class.cast(subject).getName();
     }
 
     @Override
-    protected AbstractSubjectTO getSubjectTO(final long key) {
+    protected AnyTO getAnyTO(final long key) {
         try {
             return groupDataBinder.getGroupTO(key);
         } catch (Exception e) {
@@ -126,9 +125,9 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected Subject<?, ?, ?> getSubject(final long key) {
+    protected Any<?, ?, ?> getAny(final long key) {
         try {
-            return groupDAO.authFetch(key);
+            return groupDAO.authFind(key);
         } catch (Exception e) {
             LOG.warn("Error retrieving group {}", key, e);
             return null;
@@ -136,27 +135,22 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected ConnectorObject getRemoteObject(final String accountId) {
+    protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
         ConnectorObject obj = null;
-
         try {
-            final Uid uid = new Uid(accountId);
+            Uid uid = new Uid(connObjectKey);
 
             obj = profile.getConnector().getObject(
-                    ObjectClass.GROUP,
+                    objectClass,
                     uid,
                     profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;
         } catch (RuntimeException ignore) {
-            LOG.debug("While resolving {}", accountId, ignore);
+            LOG.debug("While resolving {}", connObjectKey, ignore);
         }
-        return obj;
-    }
 
-    @Override
-    protected Mapping<?> getMapping() {
-        return profile.getTask().getResource().getGmapping();
+        return obj;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/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 1ce0357..f6218ce 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
@@ -22,15 +22,14 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
 import org.identityconnectors.framework.common.objects.SyncDelta;
@@ -45,17 +44,17 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected AttributableUtils getAttributableUtils() {
-        return attrUtilsFactory.getInstance(AttributableType.GROUP);
+    protected AnyUtils getAnyUtils() {
+        return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
     }
 
     @Override
-    protected String getName(final AbstractSubjectTO subjectTO) {
-        return GroupTO.class.cast(subjectTO).getName();
+    protected String getName(final AnyTO anyTO) {
+        return GroupTO.class.cast(anyTO).getName();
     }
 
     @Override
-    protected AbstractSubjectTO getSubjectTO(final long key) {
+    protected AnyTO getAnyTO(final long key) {
         try {
             return groupDataBinder.getGroupTO(key);
         } catch (Exception e) {
@@ -65,20 +64,8 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected AbstractSubjectMod getSubjectMod(final AbstractSubjectTO subjectTO, final SyncDelta delta) {
-        return connObjectUtils.getAttributableMod(
-                subjectTO.getKey(),
-                delta.getObject(),
-                subjectTO,
-                profile.getTask(),
-                attrUtilsFactory.getInstance(AttributableType.GROUP));
-    }
-
-    @Override
-    protected AbstractSubjectTO doCreate(
-            final AbstractSubjectTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
-
-        GroupTO groupTO = GroupTO.class.cast(subjectTO);
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningResult result) {
+        GroupTO groupTO = GroupTO.class.cast(anyTO);
 
         Map.Entry<Long, List<PropagationStatus>> created = groupProvisioningManager.create(groupTO, groupOwnerMap,
                 Collections.singleton(profile.getTask().getResource().getKey()));
@@ -86,18 +73,18 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
         groupTO = groupDataBinder.getGroupTO(created.getKey());
 
         result.setKey(created.getKey());
-        result.setName(getName(subjectTO));
+        result.setName(getName(anyTO));
 
         return groupTO;
     }
 
     @Override
-    protected AbstractSubjectTO doLink(
-            final AbstractSubjectTO before,
+    protected AnyTO doLink(
+            final AnyTO before,
             final ProvisioningResult result,
             final boolean unlink) {
 
-        final GroupMod groupMod = new GroupMod();
+        GroupMod groupMod = new GroupMod();
         groupMod.setKey(before.getKey());
 
         if (unlink) {
@@ -110,13 +97,13 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected AbstractSubjectTO doUpdate(
-            final AbstractSubjectTO before,
-            final AbstractSubjectMod subjectMod,
+    protected AnyTO doUpdate(
+            final AnyTO before,
+            final AnyMod anyMod,
             final SyncDelta delta,
             final ProvisioningResult result) {
 
-        GroupMod groupMod = GroupMod.class.cast(subjectMod);
+        GroupMod groupMod = GroupMod.class.cast(anyMod);
 
         Map.Entry<Long, List<PropagationStatus>> updated = groupProvisioningManager.update(groupMod);
 
@@ -139,28 +126,26 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
     }
 
     @Override
-    protected void doDeprovision(final Long id, final boolean unlink) {
-        taskExecutor.execute(
-                propagationManager.getGroupDeleteTasks(id, profile.getTask().getResource().getKey()));
+    protected void doDeprovision(final Long key, final boolean unlink) {
+        taskExecutor.execute(propagationManager.getGroupDeleteTasks(key, profile.getTask().getResource().getKey()));
 
         if (unlink) {
-            final UserMod userMod = new UserMod();
-            userMod.setKey(id);
-            userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+            GroupMod groupMod = new GroupMod();
+            groupMod.setKey(key);
+            groupMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
         }
     }
 
     @Override
-    protected void doDelete(final Long id) {
+    protected void doDelete(final Long key) {
         try {
-            taskExecutor.execute(
-                    propagationManager.getGroupDeleteTasks(id, profile.getTask().getResource().getKey()));
+            taskExecutor.execute(propagationManager.getGroupDeleteTasks(key, profile.getTask().getResource().getKey()));
         } catch (Exception e) {
             // A propagation failure doesn't imply a synchronization failure.
             // The propagation exception status will be reported into the propagation task execution.
-            LOG.error("Could not propagate user " + id, e);
+            LOG.error("Could not propagate group " + key, e);
         }
 
-        groupProvisioningManager.delete(id);
+        groupProvisioningManager.delete(key);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/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 fc68ec0..fb2f9a4 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
@@ -25,17 +25,14 @@ import java.util.Map;
 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.AbstractSubjectMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-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.task.ProvisioningTask;
@@ -48,6 +45,9 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
 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.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.identityconnectors.framework.common.objects.Attribute;
@@ -70,6 +70,9 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
     protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipSyncActions.class);
 
     @Autowired
+    protected AnyTypeDAO anyTypeDAO;
+
+    @Autowired
     protected GroupDAO groupDAO;
 
     @Autowired
@@ -88,7 +91,7 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
     private AuditManager auditManager;
 
     @Autowired
-    private SyncUtils syncUtilities;
+    private SyncUtils syncUtils;
 
     protected Map<Long, Long> membersBeforeGroupUpdate = Collections.<Long, Long>emptyMap();
 
@@ -122,24 +125,24 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
      * {@inheritDoc}
      */
     @Override
-    public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+    public <T extends AnyTO, K extends AnyMod> SyncDelta beforeUpdate(
             final ProvisioningProfile<?, ?> profile,
-            final SyncDelta delta, final T subject, final K subjectMod) throws JobExecutionException {
+            final SyncDelta delta, final T any, final K anyMod) throws JobExecutionException {
 
-        if (subject instanceof GroupTO) {
+        if (any instanceof GroupTO) {
             // search for all users assigned to given group
-            Group group = groupDAO.find(subject.getKey());
+            Group group = groupDAO.find(any.getKey());
             if (group != null) {
-                List<Membership> membs = groupDAO.findMemberships(group);
+                List<UMembership> membs = groupDAO.findUMemberships(group);
                 // save memberships before group update takes place
                 membersBeforeGroupUpdate = new HashMap<>(membs.size());
-                for (Membership memb : membs) {
-                    membersBeforeGroupUpdate.put(memb.getUser().getKey(), memb.getKey());
+                for (UMembership memb : membs) {
+                    membersBeforeGroupUpdate.put(memb.getLeftEnd().getKey(), memb.getKey());
                 }
             }
         }
 
-        return super.beforeUpdate(profile, delta, subject, subjectMod);
+        return super.beforeUpdate(profile, delta, any, anyMod);
     }
 
     /**
@@ -156,10 +159,7 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
             membersBeforeGroupUpdate.remove(userKey);
         } else {
             userMod.setKey(userKey);
-
-            MembershipMod membershipMod = new MembershipMod();
-            membershipMod.setGroup(groupTO.getKey());
-            userMod.getMembershipsToAdd().add(membershipMod);
+            userMod.getMembershipsToAdd().add(groupTO.getKey());
         }
 
         return userMod;
@@ -256,16 +256,16 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
      * @throws JobExecutionException if anything goes wrong
      */
     protected void synchronizeMemberships(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO) throws
-            JobExecutionException {
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO)
+            throws JobExecutionException {
 
-        final ProvisioningTask task = profile.getTask();
-        final ExternalResource resource = task.getResource();
-        final Connector connector = profile.getConnector();
+        ProvisioningTask task = profile.getTask();
+        ExternalResource resource = task.getResource();
+        Connector connector = profile.getConnector();
 
         for (Object membValue : getMembAttrValues(delta, connector)) {
-            Long userKey = syncUtilities.findMatchingAttributableKey(
-                    ObjectClass.ACCOUNT,
+            Long userKey = syncUtils.findMatchingAnyKey(
+                    anyTypeDAO.findUser(),
                     membValue.toString(),
                     profile.getTask().getResource(),
                     profile.getConnector());
@@ -289,20 +289,23 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
      * {@inheritDoc}
      */
     @Override
-    public <T extends AbstractSubjectTO> void after(
+    public <T extends AnyTO> void after(
             final ProvisioningProfile<?, ?> profile,
             final SyncDelta delta,
-            final T subject,
+            final T any,
             final ProvisioningResult result) throws JobExecutionException {
 
         if (!(profile.getTask() instanceof SyncTask)) {
             return;
         }
 
-        if (!(subject instanceof GroupTO) || profile.getTask().getResource().getUmapping() == null) {
-            super.after(profile, delta, subject, result);
+        if (!(any instanceof GroupTO)
+                || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()) == null
+                || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()).getMapping() == null) {
+
+            super.after(profile, delta, any, result);
         } else {
-            synchronizeMemberships(profile, delta, (GroupTO) subject);
+            synchronizeMemberships(profile, delta, (GroupTO) any);
         }
     }
 }