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/04/21 09:49:42 UTC

[27/40] syncope git commit: [SYNCOPE-119] New security model implemented

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtil.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtil.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtil.java
deleted file mode 100644
index f8d23df..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtil.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.api;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-public final class URIUtil {
-
-    private URIUtil() {
-        // empty constructor for static utility class
-    }
-
-    /**
-     * Build a valid URI out of the given location.
-     * Only "file", "connid" and "connids" schemes are allowed.
-     * For "file", invalid characters are handled via intermediate transformation into URL.
-     *
-     * @param location the candidate location for URI
-     * @return valid URI for the given location
-     * @throws MalformedURLException if the intermediate URL is not valid
-     * @throws URISyntaxException if the given location does not correspond to a valid URI
-     */
-    public static URI buildForConnId(final String location) throws MalformedURLException, URISyntaxException {
-        final String candidate = location.trim();
-
-        if (!candidate.startsWith("file:")
-                && !candidate.startsWith("connid:") && !candidate.startsWith("connids:")) {
-
-            throw new IllegalArgumentException(candidate + " is not a valid URI for file or connid(s) schemes");
-        }
-
-        URI uri;
-        if (candidate.startsWith("file:")) {
-            uri = new File(new URL(candidate).getFile()).getAbsoluteFile().toURI();
-        } else {
-            uri = new URI(candidate);
-        }
-
-        return uri;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java
new file mode 100644
index 0000000..91fd0c2
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+public final class URIUtils {
+
+    private URIUtils() {
+        // empty constructor for static utility class
+    }
+
+    /**
+     * Build a valid URI out of the given location.
+     * Only "file", "connid" and "connids" schemes are allowed.
+     * For "file", invalid characters are handled via intermediate transformation into URL.
+     *
+     * @param location the candidate location for URI
+     * @return valid URI for the given location
+     * @throws MalformedURLException if the intermediate URL is not valid
+     * @throws URISyntaxException if the given location does not correspond to a valid URI
+     */
+    public static URI buildForConnId(final String location) throws MalformedURLException, URISyntaxException {
+        final String candidate = location.trim();
+
+        if (!candidate.startsWith("file:")
+                && !candidate.startsWith("connid:") && !candidate.startsWith("connids:")) {
+
+            throw new IllegalArgumentException(candidate + " is not a valid URI for file or connid(s) schemes");
+        }
+
+        URI uri;
+        if (candidate.startsWith("file:")) {
+            uri = new File(new URL(candidate).getFile()).getAbsoluteFile().toURI();
+        } else {
+            uri = new URI(candidate);
+        }
+
+        return uri;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index f51e70a..19a1aed 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.core.provisioning.api;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.PropagationStatus;
@@ -30,22 +30,22 @@ import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 
 public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserMod> {
 
-    Map.Entry<Long, List<PropagationStatus>> activate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> activate(User user, StatusMod statusMod);
 
-    Map.Entry<Long, List<PropagationStatus>> reactivate(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> reactivate(User user, StatusMod statusMod);
 
-    Map.Entry<Long, List<PropagationStatus>> suspend(User user, StatusMod statusMod);
+    Pair<Long, List<PropagationStatus>> suspend(User user, StatusMod statusMod);
 
     void innerSuspend(User user, boolean propagate);
 
-    Map.Entry<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword);
+    Pair<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword);
 
-    Map.Entry<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword,
+    Pair<Long, List<PropagationStatus>> create(UserTO userTO, boolean storePassword,
             boolean disablePwdPolicyCheck, Boolean enabled, Set<String> excludedResources);
 
-    Map.Entry<Long, List<PropagationStatus>> update(UserMod userMod, boolean removeMemberships);
+    Pair<Long, List<PropagationStatus>> update(UserMod userMod, boolean removeMemberships);
 
-    Map.Entry<Long, List<PropagationStatus>> update(UserMod userMod, Long key,
+    Pair<Long, List<PropagationStatus>> update(UserMod userMod, Long key,
             ProvisioningResult result, Boolean enabled, Set<String> excludedResources);
 
     List<PropagationStatus> delete(Long subjectKey, Set<String> excludedResources);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
index 49e1138..cb1525e 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.provisioning.api.data;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -36,11 +36,11 @@ public interface SchemaDataBinder {
 
     <T extends DerSchema> DerSchemaTO getDerSchemaTO(T derSchema);
 
-    <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(T schema, AttributableUtil attributableUtil);
+    <T extends PlainSchema> PlainSchemaTO getPlainSchemaTO(T schema, AttributableUtils attributableUtil);
 
     <T extends VirSchema> VirSchemaTO getVirSchemaTO(T virSchema);
 
-    <T extends PlainSchema> void update(PlainSchemaTO schemaTO, T schema, AttributableUtil attributableUtil);
+    <T extends PlainSchema> void update(PlainSchemaTO schemaTO, T schema, AttributableUtils attributableUtil);
 
     <T extends DerSchema> T update(DerSchemaTO derSchemaTO, T derSchema);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java
index d09e054..997e98e 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java
@@ -24,16 +24,16 @@ import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.persistence.api.entity.task.TaskUtil;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 
 public interface TaskDataBinder {
 
-    SchedTask createSchedTask(SchedTaskTO taskTO, TaskUtil taskUtil);
+    SchedTask createSchedTask(SchedTaskTO taskTO, TaskUtils taskUtil);
 
     TaskExecTO getTaskExecTO(TaskExec execution);
 
-    <T extends AbstractTaskTO> T getTaskTO(Task task, TaskUtil taskUtil);
+    <T extends AbstractTaskTO> T getTaskTO(Task task, TaskUtils taskUtil);
 
-    void updateSchedTask(SchedTask task, SchedTaskTO taskTO, TaskUtil taskUtil);
+    void updateSchedTask(SchedTask task, SchedTaskTO taskTO, TaskUtils taskUtil);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
index 895e0dc..db76ca1 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java
@@ -20,8 +20,8 @@ package org.apache.syncope.core.provisioning.api.propagation;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
+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;
@@ -38,21 +38,12 @@ public interface PropagationManager {
     /**
      * Create the group on every associated resource.
      *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @param vAttrs virtual attributes to be set
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getGroupCreateTaskIds(WorkflowResult<Long> wfResult, List<AttrTO> vAttrs);
-
-    /**
-     * Create the group on every associated resource.
-     *
      * @param wfResult group to be propagated (and info associated), as per result from workflow
      * @param vAttrs virtual attributes to be set
      * @param noPropResourceNames external resources performing not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getGroupCreateTaskIds(
+    List<PropagationTask> getGroupCreateTasks(
             WorkflowResult<Long> wfResult, Collection<AttrTO> vAttrs, Collection<String> noPropResourceNames);
 
     /**
@@ -64,131 +55,109 @@ public interface PropagationManager {
      * @param noPropResourceNames external resources performing not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getGroupCreateTaskIds(Long key, Collection<AttrTO> vAttrs, PropagationByResource propByRes,
+    List<PropagationTask> getGroupCreateTasks(Long key, Collection<AttrTO> vAttrs, PropagationByResource propByRes,
             Collection<String> noPropResourceNames);
 
     /**
+     * Performs update on each resource associated to the group.
+     *
+     * @param wfResult group to be propagated (and info associated), as per result from workflow
+     * @param vAttrsToBeRemoved virtual attributes to be removed
+     * @param vAttrsToBeUpdated virtual attributes to be added
+     * @param noPropResourceNames external resource names not to be considered for propagation
+     * @return list of propagation tasks
+     */
+    List<PropagationTask> getGroupUpdateTasks(WorkflowResult<Long> wfResult, Set<String> vAttrsToBeRemoved,
+            Set<AttrMod> vAttrsToBeUpdated, Set<String> noPropResourceNames);
+
+    /**
      * Perform delete on each resource associated to the group. It is possible to ask for a mandatory provisioning for
      * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
      * the creation fails onto a mandatory resource.
      *
-     * @param groupId to be deleted
+     * @param groupKey to be deleted
      * @return list of propagation tasks
      */
-    List<PropagationTask> getGroupDeleteTaskIds(Long groupId);
+    List<PropagationTask> getGroupDeleteTasks(Long groupKey);
 
     /**
      * Perform delete on each resource associated to the group. It is possible to ask for a mandatory provisioning for
      * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
      * the creation fails onto a mandatory resource.
      *
-     * @param groupId to be deleted
+     * @param groupKey to be deleted
      * @param noPropResourceName name of external resource not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getGroupDeleteTaskIds(Long groupId, String noPropResourceName);
+    List<PropagationTask> getGroupDeleteTasks(Long groupKey, String noPropResourceName);
 
     /**
      * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
      * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
      * the creation fails onto a mandatory resource.
      *
-     * @param groupId to be deleted
+     * @param groupKey to be deleted
      * @param noPropResourceNames name of external resources not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getGroupDeleteTaskIds(Long groupId, Collection<String> noPropResourceNames);
+    List<PropagationTask> getGroupDeleteTasks(Long groupKey, Collection<String> noPropResourceNames);
 
     /**
      * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
      * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
      * the creation fails onto a mandatory resource.
      *
-     * @param groupId to be deleted
+     * @param groupKey to be deleted
+     * @param resourceNames resource from which group is to be deleted
      * @param noPropResourceNames name of external resources not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getGroupDeleteTaskIds(
-            Long groupId, Set<String> resourceNames, Collection<String> noPropResourceNames);
-
-    /**
-     * Performs update on each resource associated to the group.
-     *
-     * @param wfResult group to be propagated (and info associated), as per result from workflow
-     * @param vAttrsToBeRemoved virtual attributes to be removed
-     * @param vAttrsToBeUpdated virtual attributes to be added
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getGroupUpdateTaskIds(WorkflowResult<Long> wfResult, Set<String> vAttrsToBeRemoved,
-            Set<AttrMod> vAttrsToBeUpdated);
-
-    /**
-     * Performs update on each resource associated to the group.
-     *
-     * @param wfResult group to be propagated (and info associated), as per result from workflow
-     * @param vAttrsToBeRemoved virtual attributes to be removed
-     * @param vAttrsToBeUpdated virtual attributes to be added
-     * @param noPropResourceNames external resource names not to be considered for propagation
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getGroupUpdateTaskIds(WorkflowResult<Long> wfResult, Set<String> vAttrsToBeRemoved,
-            Set<AttrMod> vAttrsToBeUpdated, Set<String> noPropResourceNames);
-
-    List<PropagationTask> getUpdateTaskIds(Subject<?, ?, ?> subject, String password, boolean changePwd,
-            Boolean enable, Set<String> vAttrsToBeRemoved, Set<AttrMod> vAttrsToBeUpdated,
-            PropagationByResource propByRes, Collection<String> noPropResourceNames,
-            Set<MembershipMod> membershipsToAdd);
-
-    /**
-     * Create the user on every associated resource.
-     *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @param password to be set
-     * @param vAttrs virtual attributes to be set
-     * @param membershipTOs user memberships
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getUserCreateTaskIds(WorkflowResult<Map.Entry<Long, Boolean>> wfResult,
-            String password, List<AttrTO> vAttrs, List<MembershipTO> membershipTOs);
+    List<PropagationTask> getGroupDeleteTasks(
+            Long groupKey, Set<String> resourceNames, Collection<String> noPropResourceNames);
 
     /**
      * Create the user on every associated resource.
      *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
+     * @param key to be propagated
+     * @param enable whether user must be enabled or not
+     * @param propByRes operation to be performed per resource
      * @param password to be set
      * @param vAttrs virtual attributes to be set
      * @param noPropResourceNames external resources not to be considered for propagation
      * @param membershipTOs user memberships
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserCreateTaskIds(WorkflowResult<Map.Entry<Long, Boolean>> wfResult,
-            String password, Collection<AttrTO> vAttrs, Set<String> noPropResourceNames,
-            List<MembershipTO> membershipTOs);
-
-    List<PropagationTask> getUserCreateTaskIds(Long key, Boolean enabled,
+    List<PropagationTask> getUserCreateTasks(Long key, Boolean enable,
             PropagationByResource propByRes, String password, Collection<AttrTO> vAttrs,
             Collection<MembershipTO> membershipTOs, Collection<String> noPropResourceNames);
 
     /**
-     * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
-     * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
-     * the creation fails onto a mandatory resource.
+     * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
      *
-     * @param userKey to be deleted
+     * @param user to be propagated
+     * @param enable whether user must be enabled or not
+     * @param noPropResourceNames external resource names not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserDeleteTaskIds(Long userKey);
+    List<PropagationTask> getUserUpdateTasks(User user, Boolean enable, Collection<String> noPropResourceNames);
 
     /**
-     * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
-     * some resources specifying a set of resource names. Exceptions won't be ignored and the process will be stopped if
-     * the creation fails onto a mandatory resource.
+     * Performs update on each resource associated to the user.
      *
-     * @param userKey to be deleted
-     * @param noPropResourceName name of external resource not to be considered for propagation
+     * @param wfResult user to be propagated (and info associated), as per result from workflow
+     * @param changePwd whether password should be included for propagation attributes or not
+     * @param noPropResourceNames external resources not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserDeleteTaskIds(Long userKey, String noPropResourceName);
+    List<PropagationTask> getUserUpdateTasks(WorkflowResult<Pair<UserMod, Boolean>> wfResult,
+            boolean changePwd, Collection<String> noPropResourceNames);
+
+    List<PropagationTask> getUserUpdateTasks(WorkflowResult<Pair<UserMod, Boolean>> wfResult);
+
+    List<PropagationTask> getUpdateTasks(Subject<?, ?, ?> subject, String password, boolean changePwd,
+            Boolean enable, Set<String> vAttrsToBeRemoved, Set<AttrMod> vAttrsToBeUpdated,
+            PropagationByResource propByRes, Collection<String> noPropResourceNames,
+            Set<MembershipMod> membershipsToAdd);
 
     /**
      * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
@@ -199,7 +168,7 @@ public interface PropagationManager {
      * @param noPropResourceNames name of external resources not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserDeleteTaskIds(Long userKey, Collection<String> noPropResourceNames);
+    List<PropagationTask> getUserDeleteTasks(Long userKey, Collection<String> noPropResourceNames);
 
     /**
      * Perform delete on each resource associated to the user. It is possible to ask for a mandatory provisioning for
@@ -211,7 +180,7 @@ public interface PropagationManager {
      * @param noPropResourceNames name of external resources not to be considered for propagation
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserDeleteTaskIds(
+    List<PropagationTask> getUserDeleteTasks(
             Long userKey, Set<String> resourceNames, Collection<String> noPropResourceNames);
 
     /**
@@ -222,29 +191,6 @@ public interface PropagationManager {
      * @param wfResult user to be propagated (and info associated), as per result from workflow
      * @return list of propagation tasks
      */
-    List<PropagationTask> getUserDeleteTaskIds(WorkflowResult<Long> wfResult);
-
-    /**
-     * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
-     *
-     * @param user to be propagated
-     * @param enable whether user must be enabled or not
-     * @param noPropResourceNames external resource names not to be considered for propagation
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getUserUpdateTaskIds(User user, Boolean enable, Collection<String> noPropResourceNames);
-
-    /**
-     * Performs update on each resource associated to the user.
-     *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @param changePwd whether password should be included for propagation attributes or not
-     * @param noPropResourceNames external resources not to be considered for propagation
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getUserUpdateTaskIds(WorkflowResult<Map.Entry<UserMod, Boolean>> wfResult,
-            boolean changePwd, Collection<String> noPropResourceNames);
-
-    List<PropagationTask> getUserUpdateTaskIds(WorkflowResult<Map.Entry<UserMod, Boolean>> wfResult);
+    List<PropagationTask> getUserDeleteTasks(WorkflowResult<Long> wfResult);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
index c7ea22a..268453a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
@@ -33,8 +33,9 @@ import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.URIUtil;
+import org.apache.syncope.core.provisioning.api.URIUtils;
 import org.identityconnectors.common.IOUtil;
 import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.api.APIConfiguration;
@@ -81,7 +82,7 @@ public class ConnIdBundleManagerImpl implements ConnIdBundleManager {
             locations = new ArrayList<>();
             for (String location : StringUtils.isBlank(stringLocations) ? new String[0] : stringLocations.split(",")) {
                 try {
-                    locations.add(URIUtil.buildForConnId(location));
+                    locations.add(URIUtils.buildForConnId(location));
                     LOG.info("Valid ConnId location: {}", location.trim());
                 } catch (Exception e) {
                     LOG.error("Invalid ConnId location: {}", location.trim(), e);
@@ -223,19 +224,18 @@ public class ConnIdBundleManagerImpl implements ConnIdBundleManager {
     }
 
     @Override
-    public ConnectorInfo getConnectorInfo(
-            final String location, final String bundleName, final String bundleVersion, final String connectorName) {
-
+    public ConnectorInfo getConnectorInfo(final ConnInstance connInstance) {
         // check ConnIdLocation
         URI uriLocation = null;
         try {
-            uriLocation = URIUtil.buildForConnId(location);
+            uriLocation = URIUtils.buildForConnId(connInstance.getLocation());
         } catch (Exception e) {
-            throw new IllegalArgumentException("Invalid ConnId location " + location, e);
+            throw new IllegalArgumentException("Invalid ConnId location " + connInstance.getLocation(), e);
         }
 
         // create key for search all properties
-        final ConnectorKey key = new ConnectorKey(bundleName, bundleVersion, connectorName);
+        ConnectorKey key = new ConnectorKey(
+                connInstance.getBundleName(), connInstance.getVersion(), connInstance.getConnectorName());
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("\nBundle name: " + key.getBundleName()
@@ -249,7 +249,7 @@ public class ConnIdBundleManagerImpl implements ConnIdBundleManager {
             info = getConnManagers().get(uriLocation).findConnectorInfo(key);
         }
         if (info == null) {
-            throw new NotFoundException("Connector Info for location " + location + " and key " + key);
+            throw new NotFoundException("ConnectorInfo for location " + connInstance.getLocation() + " and key " + key);
         }
 
         return info;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index 8516804..3c76b82 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.MappingItem;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtil;
+import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.TimeoutException;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
@@ -99,8 +99,7 @@ public class ConnectorFacadeProxy implements Connector {
 
         ConnIdBundleManager connIdBundleManager =
                 ApplicationContextProvider.getApplicationContext().getBean(ConnIdBundleManager.class);
-        ConnectorInfo info = connIdBundleManager.getConnectorInfo(connInstance.getLocation(),
-                connInstance.getBundleName(), connInstance.getVersion(), connInstance.getConnectorName());
+        ConnectorInfo info = connIdBundleManager.getConnectorInfo(connInstance);
 
         // create default configuration
         APIConfiguration apiConfig = info.createDefaultAPIConfiguration();
@@ -117,7 +116,7 @@ public class ConnectorFacadeProxy implements Connector {
         // set pooling configuration (if supported) according to conninstance's
         if (connInstance.getPoolConf() != null) {
             if (apiConfig.isConnectorPoolingSupported()) {
-                ConnPoolConfUtil.updateObjectPoolConfiguration(
+                ConnPoolConfUtils.updateObjectPoolConfiguration(
                         apiConfig.getConnectorPoolConfiguration(), connInstance.getPoolConf());
             } else {
                 LOG.warn("Connector pooling not supported for {}", info);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index 2adbdd0..bf16b8d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -31,12 +30,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
@@ -46,7 +46,6 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationException
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.security.AuthContextUtil;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 
@@ -67,19 +66,16 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     protected GroupDAO groupDAO;
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final GroupTO subject) {
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO subject) {
         return create(subject, Collections.<String>emptySet());
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final GroupTO subject, final Set<String> excludedResources) {
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO subject, final Set<String> excludedResources) {
         WorkflowResult<Long> created = gwfAdapter.create(subject);
 
-        AuthContextUtil.extendAuthContext(created.getResult(), GroupEntitlementUtil.getEntitlementNameFromGroupKey(
-                created.getResult()));
-
         List<PropagationTask> tasks =
-                propagationManager.getGroupCreateTaskIds(created, subject.getVirAttrs(), excludedResources);
+                propagationManager.getGroupCreateTasks(created, subject.getVirAttrs(), excludedResources);
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(
                 PropagationReporter.class);
         try {
@@ -89,11 +85,11 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        return new AbstractMap.SimpleEntry<>(created.getResult(), propagationReporter.getStatuses());
+        return new ImmutablePair<>(created.getResult(), propagationReporter.getStatuses());
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(
+    public Pair<Long, List<PropagationStatus>> create(
             final GroupTO groupTO, final Map<Long, String> groupOwnerMap, final Set<String> excludedResources) {
 
         WorkflowResult<Long> created = gwfAdapter.create(groupTO);
@@ -102,30 +98,27 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             groupOwnerMap.put(created.getResult(), groupOwner.getValues().iterator().next());
         }
 
-        AuthContextUtil.extendAuthContext(created.getResult(),
-                GroupEntitlementUtil.getEntitlementNameFromGroupKey(created.getResult()));
-
-        List<PropagationTask> tasks = propagationManager.getGroupCreateTaskIds(
+        List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
                 created, groupTO.getVirAttrs(), excludedResources);
 
         taskExecutor.execute(tasks);
 
-        return new AbstractMap.SimpleEntry<>(created.getResult(), null);
+        return new ImmutablePair<>(created.getResult(), null);
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(final GroupMod subjectMod) {
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod subjectMod) {
         return update(subjectMod, Collections.<String>emptySet());
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(
+    public Pair<Long, List<PropagationStatus>> update(
             final GroupMod subjectMod, final Set<String> excludedResources) {
 
         WorkflowResult<Long> updated = gwfAdapter.update(subjectMod);
 
-        List<PropagationTask> tasks = propagationManager.getGroupUpdateTaskIds(updated,
-                subjectMod.getVirAttrsToRemove(), subjectMod.getVirAttrsToUpdate());
+        List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
+                subjectMod.getVirAttrsToRemove(), subjectMod.getVirAttrsToUpdate(), null);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {
@@ -135,41 +128,29 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<>(
+        Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>(
                 updated.getResult(), propagationReporter.getStatuses());
         return result;
     }
 
     @Override
     public List<PropagationStatus> delete(final Long subjectKey) {
-        final List<Group> toBeDeprovisioned = new ArrayList<>();
-
-        final Group syncopeGroup = groupDAO.find(subjectKey);
-
-        if (syncopeGroup != null) {
-            toBeDeprovisioned.add(syncopeGroup);
-
-            final List<Group> descendants = groupDAO.findDescendants(toBeDeprovisioned.get(0));
-            if (descendants != null) {
-                toBeDeprovisioned.addAll(descendants);
-            }
-        }
-
         final List<PropagationTask> tasks = new ArrayList<>();
 
-        for (Group group : toBeDeprovisioned) {
+        Group group = groupDAO.authFetch(subjectKey);
+        if (group != null) {
             // Generate propagation tasks for deleting users from group resources, if they are on those resources only
             // because of the reason being deleted (see SYNCOPE-357)
-            for (Map.Entry<Long, PropagationByResource> entry : groupDAO.findUsersWithIndirectResources(group.
-                    getKey()).entrySet()) {
+            for (Map.Entry<Long, PropagationByResource> entry
+                    : groupDAO.findUsersWithIndirectResources(group.getKey()).entrySet()) {
 
                 WorkflowResult<Long> wfResult =
                         new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
-                tasks.addAll(propagationManager.getUserDeleteTaskIds(wfResult));
+                tasks.addAll(propagationManager.getUserDeleteTasks(wfResult));
             }
 
             // Generate propagation tasks for deleting this group from resources
-            tasks.addAll(propagationManager.getGroupDeleteTaskIds(group.getKey()));
+            tasks.addAll(propagationManager.getGroupDeleteTasks(group.getKey()));
         }
 
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
@@ -202,7 +183,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         Collection<String> noPropResourceName = CollectionUtils.removeAll(group.getResourceNames(), resources);
 
-        List<PropagationTask> tasks = propagationManager.getGroupDeleteTaskIds(
+        List<PropagationTask> tasks = propagationManager.getGroupDeleteTasks(
                 groupKey, new HashSet<>(resources), noPropResourceName);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index 4eb425f..ce28830 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -18,14 +18,14 @@
  */
 package org.apache.syncope.core.provisioning.java;
 
-import java.util.AbstractMap;
 import java.util.Collection;
 import java.util.Collections;
 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.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.MembershipMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
@@ -68,28 +68,34 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     protected UserDAO userDAO;
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO) {
+    public Pair<Long, List<PropagationStatus>> create(final UserTO userTO) {
         return create(userTO, true, false, null, Collections.<String>emptySet());
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword) {
+    public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword) {
         return create(userTO, storePassword, false, null, Collections.<String>emptySet());
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
+    public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) {
 
-        WorkflowResult<Map.Entry<Long, Boolean>> created;
+        WorkflowResult<Pair<Long, Boolean>> created;
         try {
             created = uwfAdapter.create(userTO, disablePwdPolicyCheck, enabled, storePassword);
         } catch (PropagationException e) {
             throw e;
         }
 
-        List<PropagationTask> tasks = propagationManager.getUserCreateTaskIds(
-                created, userTO.getPassword(), userTO.getVirAttrs(), excludedResources, userTO.getMemberships());
+        List<PropagationTask> tasks = propagationManager.getUserCreateTasks(
+                created.getResult().getKey(),
+                created.getResult().getValue(),
+                created.getPropByRes(),
+                userTO.getPassword(),
+                userTO.getVirAttrs(),
+                userTO.getMemberships(),
+                excludedResources);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {
@@ -99,19 +105,19 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        return new AbstractMap.SimpleEntry<>(created.getResult().getKey(), propagationReporter.getStatuses());
+        return new ImmutablePair<>(created.getResult().getKey(), propagationReporter.getStatuses());
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(final UserMod userMod) {
+    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod) {
         return update(userMod, false);
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(final UserMod userMod, final boolean removeMemberships) {
-        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
+    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final boolean removeMemberships) {
+        WorkflowResult<Pair<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
 
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated);
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(updated);
         if (tasks.isEmpty()) {
             // SYNCOPE-459: take care of user virtual attributes ...
             final PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
@@ -133,7 +139,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
                 }
             }
             tasks.addAll(!propByResVirAttr.isEmpty() || addOrUpdateMemberships || removeMemberships
-                    ? propagationManager.getUserUpdateTaskIds(updated, false, null)
+                    ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());
         }
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
@@ -147,7 +153,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             }
         }
 
-        Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<>(
+        Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>(
                 updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
         return result;
     }
@@ -164,7 +170,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         // information could only be available after uwfAdapter.delete(), which
         // will also effectively remove user from db, thus making virtually
         // impossible by NotificationManager to fetch required user information
-        List<PropagationTask> tasks = propagationManager.getUserDeleteTaskIds(subjectId, excludedResources);
+        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(subjectId, excludedResources);
 
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
@@ -186,7 +192,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
 
     @Override
     public Long unlink(final UserMod userMod) {
-        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
+        WorkflowResult<Pair<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
         return updated.getResult().getKey().getKey();
     }
 
@@ -196,49 +202,37 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
-        WorkflowResult<Long> updated;
-        if (statusMod.isOnSyncope()) {
-            updated = uwfAdapter.activate(user.getKey(), statusMod.getToken());
-        } else {
-            updated = new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
-        }
+    public Pair<Long, List<PropagationStatus>> activate(final User user, final StatusMod statusMod) {
+        WorkflowResult<Long> updated = statusMod.isOnSyncope()
+                ? uwfAdapter.activate(user.getKey(), statusMod.getToken())
+                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        List<PropagationStatus> statuses = propagateStatus(user, statusMod);
-        return new AbstractMap.SimpleEntry<>(updated.getResult(), statuses);
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
-        WorkflowResult<Long> updated;
-        if (statusMod.isOnSyncope()) {
-            updated = uwfAdapter.reactivate(user.getKey());
-        } else {
-            updated = new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
-        }
+    public Pair<Long, List<PropagationStatus>> reactivate(final User user, final StatusMod statusMod) {
+        WorkflowResult<Long> updated = statusMod.isOnSyncope()
+                ? uwfAdapter.reactivate(user.getKey())
+                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        List<PropagationStatus> statuses = propagateStatus(user, statusMod);
-        return new AbstractMap.SimpleEntry<>(updated.getResult(), statuses);
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
-        WorkflowResult<Long> updated;
-        if (statusMod.isOnSyncope()) {
-            updated = uwfAdapter.suspend(user.getKey());
-        } else {
-            updated = new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
-        }
+    public Pair<Long, List<PropagationStatus>> suspend(final User user, final StatusMod statusMod) {
+        WorkflowResult<Long> updated = statusMod.isOnSyncope()
+                ? uwfAdapter.suspend(user.getKey())
+                : new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
 
-        List<PropagationStatus> statuses = propagateStatus(user, statusMod);
-        return new AbstractMap.SimpleEntry<>(updated.getResult(), statuses);
+        return new ImmutablePair<>(updated.getResult(), propagateStatus(user, statusMod));
     }
 
     protected List<PropagationStatus> propagateStatus(final User user, final StatusMod statusMod) {
         Collection<String> noPropResourceNames =
                 CollectionUtils.removeAll(user.getResourceNames(), statusMod.getResourceNames());
 
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
                 user, statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
         PropagationReporter propReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
@@ -262,9 +256,9 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             UserMod userMod = new UserMod();
             userMod.setKey(updated.getResult());
 
-            final List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
-                    new WorkflowResult<Map.Entry<UserMod, Boolean>>(
-                            new AbstractMap.SimpleEntry<>(userMod, Boolean.FALSE),
+            final List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+                    new WorkflowResult<Pair<UserMod, Boolean>>(
+                            new ImmutablePair<>(userMod, Boolean.FALSE),
                             updated.getPropByRes(), updated.getPerformedTasks()));
 
             taskExecutor.execute(tasks);
@@ -278,7 +272,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         Collection<String> noPropResourceNames = CollectionUtils.removeAll(user.getResourceNames(), resources);
 
         final List<PropagationTask> tasks =
-                propagationManager.getUserDeleteTaskIds(userKey, new HashSet<>(resources), noPropResourceNames);
+                propagationManager.getUserDeleteTasks(userKey, new HashSet<>(resources), noPropResourceNames);
         final PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {
@@ -292,10 +286,10 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(final UserMod userMod, final Long key,
+    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Long key,
             final ProvisioningResult result, final Boolean enabled, final Set<String> excludedResources) {
 
-        WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
+        WorkflowResult<Pair<UserMod, Boolean>> updated;
         try {
             updated = uwfAdapter.update(userMod);
         } catch (Exception e) {
@@ -304,8 +298,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             result.setStatus(ProvisioningResult.Status.FAILURE);
             result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
 
-            updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
-                    new AbstractMap.SimpleEntry<>(userMod, false), new PropagationByResource(),
+            updated = new WorkflowResult<Pair<UserMod, Boolean>>(
+                    new ImmutablePair<>(userMod, false), new PropagationByResource(),
                     new HashSet<String>());
         }
 
@@ -330,7 +324,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             }
         }
 
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
                 updated, updated.getResult().getKey().getPassword() != null, excludedResources);
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
                 getBean(PropagationReporter.class);
@@ -341,7 +335,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        return new AbstractMap.SimpleEntry<>(updated.getResult().getKey().getKey(),
+        return new ImmutablePair<>(updated.getResult().getKey().getKey(),
                 propagationReporter.getStatuses());
 
     }
@@ -355,7 +349,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     public void confirmPasswordReset(final User user, final String token, final String password) {
         uwfAdapter.confirmPasswordReset(user.getKey(), token, password);
 
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(user, null, null);
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(user, null, null);
         PropagationReporter propReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
index c948de4..6354041 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
@@ -31,14 +31,13 @@ import org.apache.syncope.common.lib.types.IntMappingType;
 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.MembershipDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
+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.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.Subject;
@@ -65,9 +64,6 @@ public class VirAttrHandler {
     private static final Logger LOG = LoggerFactory.getLogger(VirAttrHandler.class);
 
     @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
     private VirSchemaDAO virSchemaDAO;
 
     @Autowired
@@ -80,7 +76,7 @@ public class VirAttrHandler {
     private MembershipDAO membershipDAO;
 
     @Autowired
-    private AttributableUtilFactory attrUtilFactory;
+    private AttributableUtilsFactory attrUtilsFactory;
 
     public <T extends VirSchema> T getVirSchema(final String virSchemaName, final Class<T> reference) {
         T virtualSchema = null;
@@ -116,12 +112,12 @@ public class VirAttrHandler {
         }
     }
 
-    public void updateOnResourcesIfMappingMatches(final AttributableUtil attrUtil, final String schemaKey,
+    public void updateOnResourcesIfMappingMatches(final AttributableUtils attrUtils, final String schemaKey,
             final Set<ExternalResource> resources, final IntMappingType mappingType,
             final PropagationByResource propByRes) {
 
         for (ExternalResource resource : resources) {
-            for (MappingItem mapItem : attrUtil.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+            for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
                 if (schemaKey.equals(mapItem.getIntAttrName()) && mapItem.getIntMappingType() == mappingType) {
                     propByRes.add(ResourceOperation.UPDATE, resource.getKey());
                 }
@@ -132,7 +128,7 @@ public class VirAttrHandler {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public PropagationByResource fillVirtual(final Attributable attributable,
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
-            final AttributableUtil attrUtil) {
+            final AttributableUtils attrUtils) {
 
         PropagationByResource propByRes = new PropagationByResource();
 
@@ -146,7 +142,7 @@ public class VirAttrHandler {
 
         // 1. virtual attributes to be removed
         for (String vAttrToBeRemoved : vAttrsToBeRemoved) {
-            VirSchema virSchema = getVirSchema(vAttrToBeRemoved, attrUtil.virSchemaClass());
+            VirSchema virSchema = getVirSchema(vAttrToBeRemoved, attrUtils.virSchemaClass());
             if (virSchema != null) {
                 VirAttr virAttr = attributable.getVirAttr(virSchema.getKey());
                 if (virAttr == null) {
@@ -157,9 +153,9 @@ public class VirAttrHandler {
                 }
 
                 for (ExternalResource resource : externalResources) {
-                    for (MappingItem mapItem : attrUtil.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
+                    for (MappingItem mapItem : attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION)) {
                         if (virSchema.getKey().equals(mapItem.getIntAttrName())
-                                && mapItem.getIntMappingType() == attrUtil.virIntMappingType()) {
+                                && mapItem.getIntMappingType() == attrUtils.virIntMappingType()) {
 
                             propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 
@@ -177,12 +173,12 @@ public class VirAttrHandler {
 
         // 2. virtual attributes to be updated
         for (AttrMod vAttrToBeUpdated : vAttrsToBeUpdated) {
-            VirSchema virSchema = getVirSchema(vAttrToBeUpdated.getSchema(), attrUtil.virSchemaClass());
+            VirSchema virSchema = getVirSchema(vAttrToBeUpdated.getSchema(), attrUtils.virSchemaClass());
             VirAttr virAttr = null;
             if (virSchema != null) {
                 virAttr = attributable.getVirAttr(virSchema.getKey());
                 if (virAttr == null) {
-                    virAttr = attrUtil.newVirAttr();
+                    virAttr = attrUtils.newVirAttr();
                     setVirAttrSchema(attributable, virAttr, virSchema);
                     if (virAttr.getSchema() == null) {
                         LOG.debug("Ignoring {} because no valid schema or template was found", vAttrToBeUpdated);
@@ -194,10 +190,10 @@ public class VirAttrHandler {
 
             if (virSchema != null && virAttr != null && virAttr.getSchema() != null) {
                 if (attributable instanceof Subject) {
-                    updateOnResourcesIfMappingMatches(attrUtil, virSchema.getKey(),
-                            externalResources, attrUtil.derIntMappingType(), propByRes);
+                    updateOnResourcesIfMappingMatches(attrUtils, virSchema.getKey(),
+                            externalResources, attrUtils.derIntMappingType(), propByRes);
                 } else if (attributable instanceof Membership) {
-                    updateOnResourcesIfMappingMatches(attrUtil, virSchema.getKey(),
+                    updateOnResourcesIfMappingMatches(attrUtils, virSchema.getKey(),
                             externalResources, IntMappingType.MembershipVirtualSchema, propByRes);
                 }
 
@@ -223,18 +219,18 @@ public class VirAttrHandler {
      *
      * @param attributable attributable.
      * @param vAttrs virtual attributes to be added.
-     * @param attrUtil attributable util.
+     * @param attrUtils attributable util.
      */
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public void fillVirtual(final Attributable attributable, final Collection<AttrTO> vAttrs,
-            final AttributableUtil attrUtil) {
+            final AttributableUtils attrUtils) {
 
         for (AttrTO attributeTO : vAttrs) {
             VirAttr virAttr = attributable.getVirAttr(attributeTO.getSchema());
             if (virAttr == null) {
-                VirSchema virSchema = getVirSchema(attributeTO.getSchema(), attrUtil.virSchemaClass());
+                VirSchema virSchema = getVirSchema(attributeTO.getSchema(), attrUtils.virSchemaClass());
                 if (virSchema != null) {
-                    virAttr = attrUtil.newVirAttr();
+                    virAttr = attrUtils.newVirAttr();
                     setVirAttrSchema(attributable, virAttr, virSchema);
                     if (virAttr.getSchema() == null) {
                         LOG.debug("Ignoring {} because no valid schema or template was found", attributeTO);
@@ -267,7 +263,7 @@ public class VirAttrHandler {
                 userDAO.authFetch(key),
                 vAttrsToBeRemoved,
                 vAttrsToBeUpdated,
-                attrUtilFactory.getInstance(AttributableType.USER));
+                attrUtilsFactory.getInstance(AttributableType.USER));
     }
 
     private Set<String> getAttrNames(final List<? extends VirAttr> virAttrs) {
@@ -302,12 +298,12 @@ public class VirAttrHandler {
                         membership,
                         getAttrNames(membership.getVirAttrs()),
                         vAttrsToBeUpdated,
-                        attrUtilFactory.getInstance(AttributableType.MEMBERSHIP))
+                        attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP))
                 : fillVirtual(
                         membership,
                         vAttrsToBeRemoved,
                         vAttrsToBeUpdated,
-                        attrUtilFactory.getInstance(AttributableType.MEMBERSHIP));
+                        attrUtilsFactory.getInstance(AttributableType.MEMBERSHIP));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
index 3c3dcca..faaa070 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/DisabledVirAttrCache.java
@@ -27,6 +27,10 @@ import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
  */
 public class DisabledVirAttrCache implements VirAttrCache {
 
+    public DisabledVirAttrCache(final int ttl, final int maxCacheSize) {
+        // ignore
+    }
+
     @Override
     public void expire(final AttributableType type, final Long id, final String schemaName) {
         // nothing to do

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
index 8a32e99..885b194 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
@@ -46,7 +46,7 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Cache entries.
      */
-    protected final Map<VirAttrCacheKey, VirAttrCacheValue> cache = new HashMap<VirAttrCacheKey, VirAttrCacheValue>();
+    protected final Map<VirAttrCacheKey, VirAttrCacheValue> cache = new HashMap<>();
 
     public MemoryVirAttrCache(final int ttl, final int maxCacheSize) {
         this.ttl = ttl;
@@ -56,8 +56,8 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Cache virtual attribute values.
      *
-     * @param type user or group
-     * @param key user or group id
+     * @param type user, group or membership
+     * @param key attributable key
      * @param schemaName virtual attribute name
      * @param value virtual attribute values
      */
@@ -81,26 +81,26 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Retrieve cached value. Return null in case of virtual attribute not cached.
      *
-     * @param type user or group
-     * @param id user or group id
+     * @param type user, group or membership
+     * @param key attributable key
      * @param schemaName virtual attribute schema name.
      * @return cached values or null if virtual attribute is not cached.
      */
     @Override
-    public VirAttrCacheValue get(final AttributableType type, final Long id, final String schemaName) {
-        return cache.get(new VirAttrCacheKey(type, id, schemaName));
+    public VirAttrCacheValue get(final AttributableType type, final Long key, final String schemaName) {
+        return cache.get(new VirAttrCacheKey(type, key, schemaName));
     }
 
     /**
      * Force entry expiring.
      *
-     * @param type user or group
-     * @param id user or group id
+     * @param type user, group or membership
+     * @param key attributable key
      * @param schemaName virtual attribute schema name
      */
     @Override
-    public void expire(final AttributableType type, final Long id, final String schemaName) {
-        final VirAttrCacheValue value = cache.get(new VirAttrCacheKey(type, id, schemaName));
+    public void expire(final AttributableType type, final Long key, final String schemaName) {
+        final VirAttrCacheValue value = cache.get(new VirAttrCacheKey(type, key, schemaName));
         if (isValidEntry(value)) {
             synchronized (cache) {
                 value.forceExpiring();